{"id":19777996,"url":"https://github.com/aleph0io/aws-api-key-tag-context-lambda-authorizer","last_synced_at":"2026-05-18T15:36:37.150Z","repository":{"id":215150889,"uuid":"738238834","full_name":"aleph0io/aws-api-key-tag-context-lambda-authorizer","owner":"aleph0io","description":"AWS API Gateway Lambda authorizer that copies API key tags to request context","archived":false,"fork":false,"pushed_at":"2024-06-01T22:48:59.000Z","size":48,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-16T20:48:59.414Z","etag":null,"topics":["authentication","authn","authorization","authz","aws","aws-api-gateway","aws-lambda"],"latest_commit_sha":null,"homepage":"https://github.com/aleph0io/aws-api-key-tag-context-lambda-authorizer","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aleph0io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-02T19:00:16.000Z","updated_at":"2024-01-06T02:16:40.000Z","dependencies_parsed_at":"2024-01-25T17:40:46.463Z","dependency_job_id":"1544a44b-0f23-42b3-b760-252d5c1fed75","html_url":"https://github.com/aleph0io/aws-api-key-tag-context-lambda-authorizer","commit_stats":null,"previous_names":["aleph0io/aws-api-key-tag-context-lambda-authorizer"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aleph0io/aws-api-key-tag-context-lambda-authorizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleph0io%2Faws-api-key-tag-context-lambda-authorizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleph0io%2Faws-api-key-tag-context-lambda-authorizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleph0io%2Faws-api-key-tag-context-lambda-authorizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleph0io%2Faws-api-key-tag-context-lambda-authorizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aleph0io","download_url":"https://codeload.github.com/aleph0io/aws-api-key-tag-context-lambda-authorizer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aleph0io%2Faws-api-key-tag-context-lambda-authorizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33183168,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-18T09:27:30.708Z","status":"ssl_error","status_checked_at":"2026-05-18T09:27:28.300Z","response_time":71,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","authn","authorization","authz","aws","aws-api-gateway","aws-lambda"],"created_at":"2024-11-12T05:27:24.564Z","updated_at":"2026-05-18T15:36:37.135Z","avatar_url":"https://github.com/aleph0io.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# aws-api-key-tag-context-lambda-authorizer [![integration](https://github.com/aleph0io/aws-api-key-tag-context-lambda-authorizer/actions/workflows/integration.yml/badge.svg)](https://github.com/aleph0io/aws-api-key-tag-context-lambda-authorizer/actions/workflows/integration.yml)\n\nImplements an [AWS API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html) [Lambda Authorizer](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) that copies API key tags to request context for downstream processing.\n\n## Introduction\n\nOut of the box, the authorizer performs the following steps:\n\n1. Unpacks the API key from a bearer token (e.g., `Authorization: bearer $API_TOKEN`). The API token appears in plain text and is not base64-encoded. If not found, then unauthorized.\n2. Looks up the API key using the [`GetApiKeys`](https://docs.aws.amazon.com/apigateway/latest/api/API_GetApiKeys.html) endpoint. If not found, then unauthorized.\n3. Extracts data from API key [tags](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-tagging.html) and setting request principal ID, appending to context, etc.\n4. Returns these metadata along with a policy that grants access to all methods in the requesting API.\n\nThis allows implementations to encode important metadata in API key tags (e.g., subscription plan, billing ID, etc.) and then access that data downstream in [mapping templates](https://docs.aws.amazon.com/apigateway/latest/developerguide/models-mappings.html), [access logging](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html), and so on via the `$context` request parameter.\n\nThe included `cfn-deploy.yml` [SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification.html) [Template](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-reference.html) can be used to deploy the authorizer.\n\nThe included `.github/workflows/deployment.yml.example` [GitHub Actions workflow](https://docs.github.com/en/actions) can be used to implement [continuous delivery](https://en.wikipedia.org/wiki/Continuous_delivery).\n\n## Use Cases\n\n### Metered Billing\n\nIn [metered billing](https://stripe.com/docs/billing/subscriptions/usage-based), API users are charged based on usage. This requires APIs to track usage on a per-user basis.\n\nApplications can append subscription ID, user ID, and other metadata to API Keys at key creation time. Next, they can make these data available in [access logs](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html) via the `$context` request parameter. Finally, they can report usage to using a [lambda log subscription filter](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#LambdaFunctionExample) on the access logs.\n\n### Multitenant Usage Tracking\n\nIt's important to provide customers with up-to-date usage information, particularly for APIs with hard quotas or metered billing. When multiple customers are using the same API, adding customer IDs to access logs allows for real-time usage information simply through log analysis.\n\n## Recommended Developer Workflow\n\nAuthentication and Authorization are complex, so finding a (preferably simple) developer workflow that allows total control over deployment lifecycle is key. Find a proposed developer workflow below.\n\n* **Fork this repo.** Needs differ, so keeping a separate copy to customize is useful. At the very least, this will allow total control over CI/CD.\n* **Maintain a branch for each deployed Lambda authorizer.** This ensures that different authorizers with different logic are kept separate.\n* **Use Continuous Delivery to deploy updates.** Enable CD on each branch by copying and modifying `.github/workflows/deployment.yml.example` to run on pushes to the appropriate branch(es). Individual branches can be updated separately, giving the user total control over deployment lifecycle.\n* **Deploy to a fixed Lambda Alias.** For example, the default is `stag`. Configure a non-production API stage to use this alias, which allows easy testing.\n* **Promote manually.** Configure the production API stage to use a different alias, e.g., `prod`. After testing is complete, point the `prod` alias at the same version as `stag`, thus promoting the staging code to production.\n\nThe authorizer and CloudFormation template support this workflow out of the box.\n\n## Customization\n\n### CloudFormation Parameters\n\nThe implementation supports several important customizations out of the box in the form of CloudFormation template parameters:\n\n* `FunctionName` - An explicit name for the authorizer Lambda function. Useful to make ARN predictable. If left blank, a name will be generated automatically.\n* `AuthorizationPlan` - A comma-separated (`,`) list of one or more places to look for an API key, first one wins:\n  * `authorization:bearer(plain)` - A [bearer token](https://datatracker.ietf.org/doc/html/rfc6750) in plain text\n  * `authorization:bearer(base64)` - A [bearer token](https://datatracker.ietf.org/doc/html/rfc6750) in base64 encoding\n  * `header:$HEADER_NAME()` - An HTTP header of the given name contains the API key\n* `PrincipalIdTagName` - The API key tag name to extract the request [`principalId`](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html) from.\n* `ContextTagPrefix` - A prefix to use to decide which API key tags to include in request context. The prefix value is removed from tag keys before copying to request context. If left blank, then all tags are copied to request context without modification.\n* `DefaultPrincipalId` - The default value to use for [`principalId`](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html) if the given `PrincipalIdTagName` tag is missing. Leave blank to cause authentication to fail in this case.\n* `AliasName` - The name of the [Lambda alias](https://docs.aws.amazon.com/lambda/latest/dg/configuration-aliases.html) to publish automatically on deploy. If left blank, then no alias is published.\n* `VersionDescription` - The description to attach to the published [Lambda version](https://docs.aws.amazon.com/lambda/latest/dg/configuration-versions.html). If the `AliasName` parameter is blank, then this value is ignored. This is typically used in continuous delivery to label each version with its associated source code version.\n\n### Other\n\nOf course, users are free to modify however they like, but changes like the following are expected:\n\n* Different approaches to loading API keys, e.g., [`customerId`](https://docs.aws.amazon.com/apigateway/latest/api/API_GetApiKeys.html#API_GetApiKeys_RequestSyntax)\n* Custom access policies\n* Append additional, bespoke request context\n* Export authorizer ARN from `cfn-deploy.yml`\n\n## Considerations\n\n### GetApiKeys Throttling\n\nThe authorizer looks up API keys using the [`GetApiKeys`](https://docs.aws.amazon.com/apigateway/latest/api/API_GetApiKeys.html) endpoint. This endpoint is [throttled](https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#api-gateway-control-service-limits-table) at 10 requests per second, with a burst of 40 requests per second. For this reason, it's recommended to enable [authorization policy caching](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html#api-gateway-lambda-authorizer-flow) to manage authentication volume.\n\nAPI keys are loaded at 500 per page, so API key loading is reasonably efficient. However, applications above a certain volume of API keys and request traffic may get throttled, even after enabling authorization policy caching. Note that there is a hard limit of [10,000 keys per account region](https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html#api-gateway-execution-service-limits-table).\n\nUsers experiencing throttling should consider other approaches to API key lookup, such as caching keys in a data store (e.g., [DynamoDB](https://aws.amazon.com/dynamodb/)) to reduce calls to the `GetApiKeys` endpoint.\n\n## Future Features\n\nConcepts for future features are captured as issues in this repository. If you have an idea for a new feature, please drop an issue!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleph0io%2Faws-api-key-tag-context-lambda-authorizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faleph0io%2Faws-api-key-tag-context-lambda-authorizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faleph0io%2Faws-api-key-tag-context-lambda-authorizer/lists"}