CDK Lambda TokenAuthorizer JWT
Add a lambda function to your project which can be used as a apigateway token authorizer
Install
TypeScript
npm install @cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt
Python
pip install cloudy-with-a-chance-of-meatballs.cdk-lambda-token-authorizer-jwt
Usage
Notes
- JWT Token handling: The token verfification is done via https://github.com/auth0/node-jsonwebtoken, the jwks fetcher is using https://github.com/auth0/node-jwks-rsa. The implementation per default verifies the token and if given the expiration.
- JWT Payload: Any verification of the token payload must be done over injecting a json schema for validation using https://ajv.js.org/json-type-definition.html.
- Protocols: main/API.md#iauthorizeroptions
Example usage with Rest Apigateway
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as apigateway from 'aws-cdk-lib/aws-apigateway';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
export class HelloworldStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const api = new apigateway.RestApi(this, 'ApiName', {});
const tokenAuthFunction = new TokenAuthorizerJwtFunction(this, 'fnName', {
tokenAuthorizerOptions: {
verificationStrategy: {
strategyName: 'argument',
secret: 'mySecret-symmetric-or-asymmetric',
},
},
});
const tokenAuthorizer = new apigateway.TokenAuthorizer(this, 'fnNameApiGwAuthorizer', {
handler: tokenAuthFunction // use the TokenAuthorizerJwtFunction
});
const dummyFn = new lambda.Function(this, 'helloWorldFunction', {
handler: 'index.handler',
code: lambda.Code.fromInline(`exports.handler = async (event) => { console.log('event: ', event); return '{"statusCode": 200, "message": "DummyLambdaFunction"}' };`),
runtime: lambda.Runtime.NODEJS_16_X,
});
const dummyLambdaIntegration = new apigateway.LambdaIntegration(
dummyFn, { passthroughBehavior: apigateway.PassthroughBehavior.WHEN_NO_MATCH }
);
const someMethod = api.root.addMethod("GET", dummyLambdaIntegration, {
authorizer: tokenAuthorizer
});
}
}
Validation
import * as cdk from 'aws-cdk-lib';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
const myValidation = { properties:{ iss: { enum: ['my_trusted_iss'] } }};
new TokenAuthorizerJwtFunction(stack, 'example-stack', {
tokenAuthorizerOptions: {
payloadValidationStrategy: {
strategyName: 'schema',
schema: JSON.stringify(myValidation)
},
verificationStrategy: { strategyName: 'argument', secret: 'someSecret' }
}
});
Using JWKS
import * as cdk from 'aws-cdk-lib';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
new TokenAuthorizerJwtFunction(stack, 'example-stack', {
tokenAuthorizerOptions: {
verificationStrategy: {
strategyName: 'jwksFromUriByKid',
uri: 'uri',
kid: 'kid',
}
}
});
Using asymmetric algorithms, e.g. public key
import * as cdk from 'aws-cdk-lib';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
const myPublicKeyOneliner = '-----BEGIN PUBLIC KEY---\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKuTfz7kpJHPrmcmgx4Xf4GMoM2kK4mh\nMpSOW3qu1zZA1wfMHV8PS0Kds0nXMB6mmHk/Ke1\Et68aEspQRIn1aLcCAwEAAQ==\n-----END PUBLIC KEY-----';
new TokenAuthorizerJwtFunction(stack, 'example-stack', {
tokenAuthorizerOptions: {
verificationStrategy: {
strategyName: 'argument',
secret: myPublicKeyOneliner
}
}
});
Using symmetric algorithms, same key for sign and verify ⚠️
Attention: the key might be exposed during deploy, in the runtime etc.
import * as cdk from 'aws-cdk-lib';
import { TokenAuthorizerJwtFunction } from '@cloudy-with-a-chance-of-meatballs/cdk-lambda-token-authorizer-jwt';
const app = new cdk.App();
const stack = new cdk.Stack(app, 'MyStack');
const mySymmetricSecret = 'sharedSecret';
new TokenAuthorizerJwtFunction(stack, 'example-stack', {
tokenAuthorizerOptions: {
verificationStrategy: {
strategyName: 'argument',
secret: mySymmetricSecret
}
}
});
🍻
Metadata
Release files for cloudy-with-a-chance-of-meatballs.cdk-lambda-token-authorizer-jwt 0.1.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| cloudy-with-a-chance-of-meatballs.cdk-lambda-token-authorizer-jwt-0.1.8.tar.gz | 166.6 kB | Without provenance | Details for cloudy-with-a-chance-of-meatballs.cdk-lambda-token-authorizer-jwt-0.1.8.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| cloudy_with_a_chance_of_meatballs.cdk_lambda_token_authorizer_jwt-0.1.8-py3-none-any.whl | Python 3 | none | any | Details for cloudy_with_a_chance_of_meatballs.cdk_lambda_token_authorizer_jwt-0.1.8-py3-none-any.whl |
Total release size: 334.5 kB
Security for cloudy-with-a-chance-of-meatballs.cdk-lambda-token-authorizer-jwt 0.1.8
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.