A custom authorizer for AWS REST API Gateways
that will authorize requests to protected endpoints by validating a signed JWT access token. The token should be included
in the Authorization header in requests to the API in the form Bearer accessToken, and will be validated using the public
key available at the configured JWKS endpoint.
Entrust Identity as a Service (IDaaS) is a cloud-based identity and access management (IAM) solution with multi-factor authentication (MFA), credential-based passwordless access, and single sign-on (SSO).
Get started with a free trial account today.
You will need:
- An AWS account
- A token issuer (e.g. an IDaaS account with an OIDC application)
When using an IDaaS OIDC application, ensure that the appropriate APIs/URLs resource servers have been configured as well.
Install dependencies:
npm i
Build the sample code:
npm run build
-
Obtain a valid JWT access token from IDaaS for the relevant audience.
-
Create a local event.json file containing the access token. You can use
sample-event.jsonas a template:cp sample-event.json event.jsonAdd your JWT token to
authorizationToken. You can also replacemethodArnwith a method ARN of your API that you intend to protect (optional for local tests). -
Create a local .env file containing the
JWKS_URI,ISSUER, andAUDIENCE. You can use.sample-envas a template:cp .sample-env .envParameter Value ISSUERThe issuer of the token. If IDaaS is the token issuer, use https://{yourIdaasDomain}/api/oidc.JWKS_URIThe URL of the JWKS endpoint. If IDaaS is the token issuer, use https://{yourIdaasDomain}/api/oidc/jwks.AUDIENCEThe URL of the domain of the endpoint you are trying to secure. E.g. https://{yourApiGateway}. -
Run the test using
npm run test. If successful, you should see an output similar to the following:info: START RequestId: 3df095ef-8876-c996-919f-cca592e01a62 info: End - Result: info: { "principalId": "userId", "policyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "execute-api:Invoke", "Effect": "Allow", "Resource": "arn:aws:execute-api:us-east-1:1234567890:apiId/stage/method/resourcePath" } ] } } info: Lambda successfully executed in 316ms.
To use this sample to protect your AWS REST API Gateway:
-
Bundle the sample code into an upload-able zip by running
npm run bundle. It will be located in the/distdirectory. -
Navigate to the AWS Lambda console, and click Create function.
-
The default should be Author from scratch to create a blank function. Under Basic information, provide values for the following parameters:
Parameter Value Function Name A name for your Lambda function, such as jwtCustomAuthorizerRuntime Select Node.js 20.x -
Click Create Function to continue.
-
On the Code page of your function, select the Upload From dropdown menu and select .zip file.
-
Click Upload and select the
token-authorizer.zipbundle you created earlier. -
Then creat the following three Environment variables. Note that this information is identical to the contents of
.envfile:Parameter Value ISSUERThe issuer of the token. If IDaaS is the token issuer, use https://{yourIdaasDomain}/api/oidc.JWKS_URIThe URL of the JWKS endpoint. If IDaaS is the token issuer, use https://{yourIdaasDomain}/api/oidc/jwks.AUDIENCEThe URL of the domain of the endpoint you are trying to secure. E.g. https://{yourApiGateway}. -
To test the Lambda function you just created, click the Test tab.
-
Copy the contents of your
event.jsonfile into the Event JSON form. You can use the default "Hello World" event template. ThemethodArnmust be set to a valid method ARN in your gateway. -
Click Save.
-
Run your test by selecting it and clicking Test. If the test was successful, you'll see: "Execution result: succeeded". Expanding the output window should show a message similar to the one you received after your successful local test.
After adding this custom authorizer to protect your AWS API Gateway endpoints, you might want to limit access to individual
endpoints based on the allowed scopes of the authorized party (e.g. read:resource). To do this, leverage the authorizationScopes
property of each gateway method to define the scopes required to invoke the method.