Securing API Gateway with Okta, Serverless Framework and SSM

Dave Townsend
unbounded.io
Published in
3 min readAug 13, 2019

--

Overview

This brief article with accompanying GitHub repo, together cover how to secure an Amazon API Gateway endpoint with a Lambda authorizer function using Okta, Serverless Framework and AWS Systems Manager Parameter Store (SSM) for storing secrets.

Prerequisites

  1. Basic understanding of API Gateway Lambda Authorizers
  2. Basic understanding of Serverless Framework
  3. An app in Okta capable of minting JSON Web Tokens (JWT)
  4. Access to the Okta authorization server settings in your Okta domain

Code repo

https://github.com/davetownsend/serverless-okta-lambda-auth
Node.js based Lambdas are used in this project.

Authorizer Function

To grant secured access to API Gateway with an Okta JWT, a lambda authorizer function is needed that can perform the following tasks:

  1. Verify authenticity and validity of an Okta JWT
  2. Return an IAM policy granting access to API Gateway

In a Serverless Framework project, install the Okta JWT Verifier for Node.js package. This library will be used to verify the Okta JWT.

Create a function in the serverless project for the authorizer:

We’ll be assigning this function to API Gateway as an authorizer. Refer to the GitHub repo, to see the full authorizer function exampleAuth.js.

Note the following line in exampleAuth.js:

policy.allowMethod(AuthPolicy.HttpVerb.GET, “/example/read”) 

This is where access to API Gateway resources, that will be written into the returned policy, are defined.

Policy Generator

The policy generator (used by the authorizer function) is responsible for creating a least privilege IAM policy to allow access into API Gateway.

Refer to the GitHub repo, to see the authPolicy.js file.

Note: This code has been taken as is from here:
https://github.com/mcguinness/node-lambda-oauth2-jwt-authorizer/blob/master/auth-policy.js

Assign Authorizer to API Gateway

The authorizer function can now be assigned in serverless.yml to the API Gateway.

Note the usage of authorizer:

The identitySource specifies the request header where API Gateway should expect to find the JWT, and identityValidationExpression specifies the format required of the Authorization header value. If the header value does not meet this criterion, the request will not be sent on to the lambda authorizer and the caller will receive a 401 Unauthorized response code. In addition, resultTtlInSeconds specifies the cache timeout (in seconds) for the authorizer results (default 300, max 3600). For the example app, I’ve specified 0 to opt-out of caching.

Store Okta secrets in SSM

This example project uses SSM to store Okta secrets as SecuresString(s) and uses Middy to fetch and cache the params.

View the readme in the repo for steps to create the SSM parameters.

Middy makes working with SSM in Node.js extremely clean. Below is how Middy is configured to pull the SSM params, store them in the lambda’s context object and cache them for five minutes.

Usage of the ${stage} environment variable allows for account specific parameters.

Middy allows the retrieved SSM params to be set in either process.env or into the lambda function’s context object. Notice setContext: true in the above config to opt-in to that setting. Refer to the Middy docs for more detail on SSM config options.

The SSM params can now be accessed from the context object using the name assigned in the config, e.g.:

context.ISSUER;

Additional IAM permissions will be required on the authorizer function to both access SSM and to use KMS for decrypting the SecuredString(s).

Note: This service uses the serverless-iam-roles-per-function and serverless-pseudo-parameters serverless plugins to keep config clean and localized.

Refer to the GitHub repo readme for details on deploying and testing out the example application.

Additional Resources

Use API Gateway Lambda Authorizers
https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html

The Complete Guide to Custom Authorizers w/ Lambda and API Gateway
https://www.alexdebrie.com/posts/lambda-custom-authorizers/

node-lambda-oauth2-jwt-authorizer
https://github.com/mcguinness/node-lambda-oauth2-jwt-authorizer

Okta JWT Verifier for Node.js
https://github.com/okta/okta-oidc-js/tree/master/packages/jwt-verifier

Integrating Okta with Amazon API Gateway
https://github.com/tom-smith-okta/okta-api-center/tree/master/gateways/aws

--

--