Skip to content

upstandfm/lambda-authorizers

Repository files navigation

Lambda authorizers

CircleCI

AWS lambda authorizers.

Table of contents

Development

Code linting and formatting

Code is automatically linted and formatted on commit, using ESLint and Prettier.

Available scripts

In the project directory, you can run:

npm test

Runs all (unit) tests.

npm run lint

Lints all code using ESLint.

npm run lint:format

Lints all code using ESLint, and formats it using Prettier.

npm run sls:debug

Prints the serverless.yaml configuration.

Monitoring

A Serverless dashboard has been setup for:

  • Alerts (errors)
  • RED metrics
  • Basic observability based on:
    • Date & time
    • Function name
    • Execution duration
    • Memory usage
    • Cold start time
    • Errors

CI/CD

CircleCI is used to:

  • Audit npm dependencies for security vulnerabilities.
  • Run unit/integration tests (Jest).
  • Deploy services via Serverless Framework.

Serverless Framework

CircleCI requires a "Serverless Personal Access Key" to deploy services. This is configured as an environment variable named SERVERLESS_ACCESS_KEY in the CircleCI credentials context. The value of the access key can be found in the 1Password "Upstand FM" vault under "Serverless access key for CircleCI".

The access key allows the Serverless CLI (used by CircleCI in the release job) to authenticate with the Serverless Framework Dashboard.
Additionally, an access role has been configured to help secure resource deployments on AWS, by enabling the Serverless Framework to issue temporary AWS access keys to deploy resources. These keys are generated by Serverless Framework on every command, and the credentials expire after one hour.

The Serverless Framework leverages AWS Security Token Service and the AssumeRole API to automate creating and usage of temporary credentials, so your developers can stay productive and work securely without doing this manually.

We also use a separate CloudFormation role to limit access during deployment, to only the required set of permissions needed by Serverless to deploy resources (i.e. no AdministratorAccess). This is done by setting provider.cfnRole in the Serverless manifest.

Auth0 authorizer

The implementation is based on serverless auth.

The lambda authorizer controls API access by using a bearer auth strategy. This is provided by Auth0 and means that clients can only access a protected API by using a valid access token.

Lambda authorizer output

On successful auth, the lambda authorizer will return an output that contains a context. This context object contains properties that can be used by a lambda proxy handler. One of those properties is the scope, which the API (i.e. lambda proxy handler) can use to make authorization decisions.

This information can be extracted from the event Object like this:

module.exports.handler = async event => {
  const { authorizer } = event.requestContext;
  const { scope } = authorizer;
};

More information about the request context can be found here.

Error handling and CORS

In general, the lambda authorizer will return either 4XX or 5XX error responses (API Gateway).

The 4XX error response can be triggered by throwing "Unauthorized":

// MUST match the error EXACTLY!
throw new Error('Unauthorized');

Any other thrown errors, will result in a 5XX error response.

Additionally, the proper CORS headers must be returned by the API, because when the lambda authorizer fails, it won't execute the lambda proxy handler. This can be achieved by adding a custom "API Gateway Response" on the API that uses the lambda authorizer:

service: my-api
app: my-app
org: upstandfm

provider:
  name: aws
  runtime: nodejs10.x
  memorySize: 128
  timeout: 3

functions:
  getSecret:
    handler: src/handler.secret
    events:
      - http:
          path: /secret
          method: get
          authorizer:
            arn: 'LAMBDA_AUTHORIZER_ARN'
            resultTtlInSeconds: 0
            identitySource: method.request.header.Authorization
            identityValidationExpression: '^Bearer [-0-9a-zA-z\.]*$'
            type: token

# This returns the proper CORS headers when an authorized request fails, which
# applies to 4XX and 5XX responses.
#
# For more info see:
# - https://serverless.com/blog/cors-api-gateway-survival-guide/
# - https://docs.aws.amazon.com/apigateway/latest/developerguide/supported-gateway-response-types.html
resources:
  Resources:
    GatewayResponseDefault4XX:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
        ResponseType: DEFAULT_4XX
        RestApiId:
          Ref: 'ApiGatewayRestApi'
    GatewayResponseDefault5XX:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
        ResponseType: DEFAULT_5XX
        RestApiId:

Configuration

The lambda authorizer must be configured via the following environment variables:

Var Name Required Description
AUTH0_TOKEN_ISSUER Yes The token provider. This must have the format of https://<TENANT>.<REGION>.auth0.com/.
AUTH0_JWKS_URI Yes The token provider. This must have the format of https://<TENANT>.<REGION>.auth0.com/.well-known/jwks.json.
AUTH0_AUDIENCE Yes The audience for "whom" the access token is intended for. This must be the Identifier (NOT the Id!) of an Auth0 API Client, and must match the audience used by the client that obtained the access token.

About

AWS lambda authorizers.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published