AWS API gateway introduced HTTP API endpoints based integration in recent 2-3 years and they are different from the legacy REST API endpoint.
With this AWS also introduced JWT authorizer based authorization for the endpoints and made life easy for all the architects and developers, who were previously forced to use a custom authorizer only.
In this blog post which you are reading the primary focus is on AWS API gateway JWT Authorizer - with Pulumi as IAC provisioner & Zitadel for the identity/ authentication provider.
Reference to the zitadel setup for client_credentials flow here
Prerequisites
- AWS account.
- Average knowledge about AWS, AWS API Gateway, AWS Lambda Functions.
- AWS CLI, Pulumi CLI on local machine.
- NodeJS 16 on local machine.
- Zitadel cloud account(setting up zitacloud is out of scope of this blog post) - refer my other blog post here for setting up zitadel cloud account
- You may also use any other Identity provider. (like AWS cognito, etc.)
- Great to have knowledge of JWT.
Flow Diagram Positive Scenario
- client fetches the access token required by the API endpoint before hitting the actual endpoint.
- client sends request along with JWT as part of an Authorization Header prefixed with Bearer or can be without Bearer, to API gateway.
- AWS API gateway delegates the Authorization to it's self managed Authorizer(not sure how they might be doing it - could be internally lambda managed?!).
- fetches the jwks based on the issuer property & validates the signature of the JWT based on the kid in the input JWT.
- internal JWT authorizer will return back true/ success.
- API gateway will pass on the original request to the AWS lambda function.
- Lambda function will reply back the response.
- Response received from the lambda function is sent back to the client.
Flow Diagram Negative Scenario
- client fetches the access token required by the API endpoint before hitting the actual endpoint. (or if skipped for testing purpose)
- client sends incorrect or blank or expired or misconfigured token.
- AWS API gateway delegates the Authorization to it's self managed Authorizer(not sure how they might be doing it - could be internally lambda managed?!). It will delegate only if the header was present.
- fetches the jwks based on the issuer property & validates the signature of the JWT based on the kid in the input JWT.
- authorizer will reply back with false.
- API gateway sends back the response as 401 (Unauthorized) or 403(forbidden).
Code and configuration
The code repository referred is from the previous blog post
- change the configuration in the stack's yml files
- domain, cert, zitacloud issuer, etc. as per your setup
Link to the repo is here and the branch is authorizer
The config related to the JWT authorizer are in the file:-
config:
aws:profile: <AWS_PROFILE>
aws:region: <AWS_REGION>
non-mtls-apis:API_DOMAIN: <API_DOMAIN>
non-mtls-apis:API_DOMAIN_MTLS: <MTLS_API_DOMAIN>
non-mtls-apis:HOSTED_ZONE_NAME: <HOSTED_ZONE>
non-mtls-apis:JWT:
audiences:
- test
- aws_client
issuer: https://instance_code.zitadel.cloud/
non-mtls-apis:SUB_DOMAIN: <SUB_DOMAIN>
non-mtls-apis:SUB_DOMAIN_MTLS: mtls.<SUB_DOMAIN>
Make changes to the audiences and issuer as per the setup.
- audiences will be part of the JWT access token as aud claim.
- issuer is also part of the JWT as iss claim.
If these configurations are not correct - then the API gateway will give error while accessing the endpoints
The error could be 401 unauthorized and relating to the below:-
- issuer incorrect
- jwks url not accessible
- keys not resolvable, kid mismatch
- JWT's - exp nbf, iat not correct
Please feel free to reach me over Linkedin here for further questions, doubts or suggestions.
Top comments (0)