{"id":19854694,"url":"https://github.com/obytes/apigw-jwt-authorizer","last_synced_at":"2026-05-10T22:35:06.097Z","repository":{"id":77139201,"uuid":"428185958","full_name":"obytes/apigw-jwt-authorizer","owner":"obytes","description":"AWS API Gateway Websocket JWT Authorizer","archived":false,"fork":false,"pushed_at":"2021-11-15T21:58:24.000Z","size":1284,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":12,"default_branch":"main","last_synced_at":"2025-01-11T13:50:54.093Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/obytes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2021-11-15T08:45:21.000Z","updated_at":"2024-08-01T14:43:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"1855518e-1eab-420d-a6f2-7c64a00ac624","html_url":"https://github.com/obytes/apigw-jwt-authorizer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obytes%2Fapigw-jwt-authorizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obytes%2Fapigw-jwt-authorizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obytes%2Fapigw-jwt-authorizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/obytes%2Fapigw-jwt-authorizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/obytes","download_url":"https://codeload.github.com/obytes/apigw-jwt-authorizer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241244953,"owners_count":19933295,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-11-12T14:10:09.353Z","updated_at":"2026-05-10T22:35:06.069Z","avatar_url":"https://github.com/obytes.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# APIGW JWT Authorizer\n\n\u003cimg src=\"docs/images/fingerprint.gif\" width=\"100%\"\u003e\n\nJWT Authorizer to use with AWS APIGW as a Custom Lambda Authorizer for Websocket APIs\n\n## Features\n\nThis Custom JWT Authorizer can be used by any API Gateway Websocket route, it's:\n\n- **Interoperable**: It can validate JWT tokens for any JWT Token Provider (Firebase, Auth0 ...)\n- **Fast**: It can cache public keys, so it doesn't request them every time from the Token Provider.\n- **Secure**: It can validate token signature, expiration time and allowed audiences.\n\n## Environment Variables:\n\n- **JWT_ISSUER_JWKS_URI** - The issuer JWKs URI\n    - Firebase: https://www.googleapis.com/service_accounts/v1/metadata/x509/securetoken@system.gserviceaccount.com\n    - Cognito: https://cognito-idp.YOUR_REGION_NAME.amazonaws.com/YOUR_USER_POOL_ID/.well-known/jwks.json\n    - Auth0: https://YOUR_DOMAIN/.well-known/jwks.json\n    - etc\n    \n- **JWT_AUTHORIZED_AUDIENCES** - A comma separated list of the audiences authorized to consume the API.\n\n- **JWT_VERIFY_EXPIRATION** - Whether to verify token expiration, default is \"true\".\n\n- **AUTHORIZED_APIS** - A comma separated list of the APIs to authorize token's holder to.\n\n## Usage\n\nCreate an API Gateway REQUEST Authorizer\n\n```hcl\nresource \"aws_apigatewayv2_authorizer\" \"request_authorizer\" {\n  name                       = \"${var.prefix}-request-authz\"\n  api_id                     = aws_apigatewayv2_api._.id\n  authorizer_type            = \"REQUEST\"\n  identity_sources           = [\n    \"route.request.querystring.authorization\",\n    #\"route.request.header.Authorization\",\n  ]\n  authorizer_uri             = module.request_authorizer.lambda[\"invoke_arn\"]\n  authorizer_credentials_arn = aws_iam_role._.arn\n}\n```\n\nGive API Gateway permission to invoke the Authorizer\n\n```hcl\nresource \"aws_lambda_permission\" \"allow_apigw\" {\n  statement_id  = local.prefix\n  action        = \"lambda:InvokeFunction\"\n  function_name = var.request_authorizer.name\n  qualifier     = var.request_authorizer.alias\n  principal     = \"apigateway.amazonaws.com\"\n  source_arn    = \"${aws_apigatewayv2_api._.execution_arn}/${aws_apigatewayv2_stage._.name}/*\"\n}\n```\n\nAssign the authorizer to the websocket route you want to secure, usually it's the `$connect` route\n\n```hcl\nresource \"aws_apigatewayv2_route\" \"connect\" {\n  api_id         = var.api_id\n\n  # UPSTREAM\n  target         = \"integrations/${aws_apigatewayv2_integration.ack_presence.id}\"\n  route_key      = \"$connect\"\n  operation_name = \"Acknowledge user presence\"\n\n  # AUTHORIZATION\n  authorizer_id      = aws_apigatewayv2_authorizer.request.id\n  authorization_type = \"CUSTOM\"\n  api_key_required   = false\n\n  route_response_selection_expression = \"$default\"\n}\n```\n\nFinally, pass the JWT token as query param `authorization` when connecting to websocket\n\n```javascript\naccessToken = \"LONG_USER_JWT_TOKEN\"\nlet endpoint = `wss://live.kodhive.com/push?authorization=${accessToken}`;\nws = new Sockette(endpoint);\n```\n\n## Deploy\n\nBefore deploying the authorizer, version control it on your github account and then call these Terraform modules to \nprovision the authorizer lambda and CI/CD pipeline:\n\n```hcl\n# Authorizer Lambda\nmodule \"request_authorizer\" {\n  source      = \"git::https://github.com/obytes/terraform-aws-codeless-lambda.git//modules/lambda\"\n  prefix      = \"${local.prefix}-authorizer\"\n  common_tags = local.common_tags\n\n  handler = \"app.main.handle\"\n  envs    = {\n    AUTHORIZED_APIS          = join(\",\", module.gateway.authorized_apis)\n    JWT_ISSUER_JWKS_URI      = var.issuer_jwks_uri\n    JWT_AUTHORIZED_AUDIENCES = join(\",\", var.authorized_audiences)\n    JWT_VERIFY_EXPIRATION    = var.verify_token_expiration\n  }\n}\n\n# CI/CD\nmodule \"authorizer_ci\" {\n  source      = \"git::https://github.com/obytes/terraform-aws-lambda-ci.git//modules/ci\"\n  prefix      = \"${local.prefix}-authorizer-ci\"\n  common_tags = var.common_tags\n\n  # Lambda\n  lambda                   = module.authorizer.lambda\n  app_src_path             = \"sources\"\n  packages_descriptor_path = \"sources/requirements/lambda.txt\"\n\n  # Github\n  pre_release = true\n  s3_artifacts = {\n    arn = aws_s3_bucket.artifacts.arn\n    bucket = aws_s3_bucket.artifacts.bucket\n  }\n  github = {\n    owner = \"obytes\"\n    webhook_secret = \"not-secret\"\n    connection_arn = \"arn:aws:codestar-connections:us-east-1:{ACCOUNT_ID}:connection/{CONNECTION_ID}\"\n  }\n  github_repository = {\n    name = \"apigw-jwt-authorizer\"\n    branch = \"main\"\n  }\n  # Notifications\n  ci_notifications_slack_channels = {\n    info = \"ci-info\"\n    alert = \"ci-alert\"\n  }\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobytes%2Fapigw-jwt-authorizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fobytes%2Fapigw-jwt-authorizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fobytes%2Fapigw-jwt-authorizer/lists"}