This repo intends to demonstrate how to address the OAuth2-based authorization security requirement for Brazilian Open Banking to use Amazon API Gateway to protect and authorize API accesses using an external FAPI-compliant OIDC provider and a Lambda Authorizer.
- awscli
- Pre configured AWS credentials
- npm
- cdk
- Docker
- A Route 53 Public Hosted Zone configured to a DNS
- A Public Certificate issued to your Domain Name using ACM
Make sure Docker is running. We will use Docker to create the container that will be used to run NODE-OIDC, create an Amazon ECR repository, and push our newly create image to our repository.
After Docker is running, execute the following commands:
git clone <REPO_URL>
cd <REPO_NAME>/resources/oidc-provider-app
npm install
aws ecr create-repository --repository-name oidc-provider-app
Take note of your repositoryUrl
output variable, which should be something like this: repositoryUri": "<AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/oidc-provider-app"
Now let's build our image and push it to the ECR repository:
docker build -t oidc-provider-app .
docker tag oidc-provider-app:latest <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/oidc-provider-app:latest
docker push <AWS_ACCOUNT_ID>.dkr.ecr.<AWS_REGION>.amazonaws.com/oidc-provider-app:latest
Now, make sure to set the following env variables in the .env
file:
Key | Value | Description |
---|---|---|
ECR_REPOSITORY_ARN | arn:aws:ecr::<account_id>:repository/oidc-provider-app | Your Amazon ECR repository name for the Node OIDC Provider application |
ECR_OIDC_IMAGE_TAG | latest | Your Docker image tag (e.g. latest) |
ACM_CERTIFICATE_ARN | arn:aws:acm::<account_id>:certificate/abc-123 | Your Amazon Certificate Manager (ACM) public certificate ARN |
R53_ZONE_NAME | example.com | Your Route 53 public zone name (e.g. example.com) |
R53_HOSTED_ZONE_ID | ABCDEF012345 | Your Route 53 public Hosted Zone ID |
R53_DOMAIN_NAME | oidc.example.com | The desired domain name to host your OIDC application (e.g. oidc.example.com) |
JWKS_URI | /jwks | Your OIDC Provider's JWKS Endpoint |
SM_JWKS_SECRET_NAME | dev/OpenBankingBrazil/Auth/OIDC_JWKS | The AWS Secrets Manager's secret name to securely store your JWKS Key ID for JWT token verification |
cd <REPO_NAME>/resources/lambda
npm install
cd ../..
npm install
cdk deploy
This will install all packages required. CDK will then bootstrap a deploy environment in your account. You will then synthetize a cloudformation template and finally deploy it. The end result will be the following architecture performing the following steps:
- User accesses the OIDC provider to Authenticate (AuthN) and enter its credentials.
- OIDC provider issues a JWT-based access and/or ID token to client.
- User invokes a protected API resource passing the access/ID bearer token to the
Authorization
header. - API Gateway uses a Lambda Authorizer to decode and verify the JWT token and its scopes to allow/deny access to the protected resource.
- Lambda Authorizer query the JWKS key for verifying the token signature stored in AWS Secrets Manager
- Lambda Authorizer uses the retrieved key from AWS Secrets Manager to verify the token signature against the OIDC provider.
- In case the token is successfully verified and contains the proper scopes to access the API resource, Lambda Authorizer returns a temporary IAM credential allowing API Gateway to invoke the protected resource.
- API Gateway invokes the protected resource and performs an action on behalf of the user.
First, use terminal to run the following command to invoke your API without any JWT token:
curl -X GET https://<API-ID>.execute-api.<REGION>.amazonaws.com/prod/
You should get the following error message with a 401 HTTP Status Code
:
"message": "Unauthorized"
Or the following error message with a 403 HTTP Status Code
in case you pass an invalid Bearer
token:
"Message": "User is not authorized to access this resource with an explicit deny"
Open your browser and open the following URL:
https://<YOUR-DOMAIN-NAME>/auth?client_id=client_app&redirect_uri=https://jwt.io&response_type=id_token&scope=openid%20profile&nonce=123&state=abca
You'll be required to enter your username/password. At this time, you can enter any user/pass. Click Sign-in.
Now, once presented with the consent
screen, you can authorize the provider to issue a token on behalf of your user. Click Continue.
For validation-only purposes, you are being redirected to JWT.IO to visualize your issue JWT token. Copy the generated token from the left side of the screen.
Let's try once again, this time including the Authorization
header in our request together with our newly issued JWT token.
curl -X GET https://<API-ID>.execute-api.<REGION>.amazonaws.com/prod/ -H "Authorization: Bearer <YOUR.ACCESS.TOKEN>"
Now, you should get the following message with a 200 HTTP Status Code
:
Hello From Authorized API
Congratulations! You have now configured your API Gateway to authorize access based on JWT-based tokens issued by an external FAPI-compliant OIDC Provider.
Run the following command:
cdk destroy
aws ecr delete-repository --repository-name oidc-provider-app
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.