
Security News
vlt Launches "reproduce": A New Tool Challenging the Limits of Package Provenance
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
aws-apigw-authorizer
Advanced tools
This is an implementation in NodeJS of an authorizer function for AWS API Gateway.
(i.e. an implementation of this: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html)
The authorizer supports these authentication mechanisms:
Also, the authorizer can be configured to only allow certain source IP's (see below).
Create a Lambda function in AWS using Node 10.x runtime and use the following code:
import { ApiGatewayAuthorizer } from 'aws-apigw-authorizer';
const lambdaAuthorizer = new ApiGatewayAuthorizer();
// use the authorizers handler as the lambda handler function:
export const handler = lambdaAuthorizer.handler.bind(lambdaAuthorizer);
Of course you will have to create a deployment package to include aws-apigw-authorizer
and it's dependencies.
npm install aws-apigw-authorizer
See instructions here: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-create-deployment-pkg.html
Give the lambda the right environment variables. You'll have to configure at least:
See below the exact description of the environment variables.
Use the Lambda function you created for your API Gateway Authorizer.
See further instructions here: https://docs.aws.amazon.com/apigateway/latest/developerguide/configure-api-gateway-lambda-authorization-with-console.html
Make sure the "Lambda Event Payload" of the authorizer is set to "Request" (explained here: https://aws.amazon.com/blogs/compute/using-enhanced-request-authorizers-in-amazon-api-gateway/). This will (a.o.) give access to the source IP-address of calls to your API.
Your lambda function should be configured using the following environment variables:
It is mandatory to explicitly specify which remote IP adresses/address ranges are allowed to access the API.
ALLOWED_IP_ADDRESSES can be set to 0.0.0.0/0
for public access.
Individual IP-addresses can be specified, or ranges using CIDR-notation, multiple entries separated bij comma's.
Example:
ALLOWED_IP_ADDRESSES=213.149.225.141/32,213.149.225.141
Users allowed access through HTTP Basic Authentication can be configured as follows:
BASIC_AUTH_USER_mike=mikespassword
BASIC_AUTH_USER_lisa=lisaspassword
This is an optional environment key, without which Basic Authentication is not enabled.
For JWT authentication provide a value for AUDIENCE_URI
, ISSUER_URI
and JWKS_URI
Example:
AUDIENCE_URI=123456cc-cd12-1234-ff66-7897fabcd12
ISSUER_URI=https://sts.yourserver.com/876abc-ab12-8765-ff43-75232abc/
JWKS_URI=https://login.yourserver.com/common/discovery/keys'
These are optional environment keys, without which JWT Authentication is not enabled.
A custom function can be provided for building custom AWS IAM policies. The custom function will be called after succesfull authentication:
import { ApiGatewayAuthorizer } from 'aws-apigw-authorizer';
const lambdaAuthorizer = new ApiGatewayAuthorizer({ policyBuilder: customPolicyBuilder });
// May return promise or synchronous result as below
function customPolicyBuilder(_event, _principal, _decodedJwt) {
// event: the raw event that the authorizer lambda function receives from API Gateway
// principal: the username of the authenticated user
// decodedJwt: the decoded JWT. Only present if authentication was based on JWT
return {
"principalId": "your principal - just a name",
"policyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "execute-api:Invoke",
"Effect": "Allow",
"Resource": [
"arn:aws:execute-api:eu-west-1:region:api-id/stage/*/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": [
"123.456.789.123/32"
]
}
}
}
]
}
}
}
export const handler = lambdaAuthorizer.handler.bind(lambdaAuthorizer);
If a custom policy builder is not provided, the default policy builder will be used, which will grant the user access to invoke all resources of the API using any HTTP method.
A custom function can be provided for setting the authorization context (https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html). The custom function will be called after succesfull authentication:
// May return promise or synchronous result as below
import { ApiGatewayAuthorizer } from 'aws-apigw-authorizer';
const lambdaAuthorizer = new ApiGatewayAuthorizer({ contextBuilder: customContextBuilder });
function customContextBuilder(_event, _principal, decodedToken) {
return {
name: decodedToken['sub'],
foo: 'bar'
}
}
export const handler = lambdaAuthorizer.handler.bind(lambdaAuthorizer);
If you throw an error anywhere in the customContextBuilder the request will be denied (HTTP 401).
The validity of the JWT and/or Basic Authentication credentials will always be checked. A custom function can be provided in which you can include your own additional checks. If you throw an error anywhere in that function the request will be denied (HTTP 401).
// May return promise or synchronous result as below
function customAuthChecks(event, principal, decodedToken) {
if (!event.headers['X-SHOULD-BE-PRESENT']) {
throw new Error('HTTP header X-SHOULD-BE-PRESENT is required');
}
}
const authorizer = new (require('aws-apigw-authorizer')).ApiGatewayAuthorizer(
{ authChecks: customAuthChecks }
);
exports.handler = authorizer.handler.bind(authorizer);
If you want to take control of the determination of the principalId that is used in the AWS policy and cloudwatch logging, specify a custom JwtPrincipalIdSelectorFunction.
This is only useful for JWT auth, because for Basic Authentication the username will be used as principalId.
// May return promise or synchronous result as below
function customJwtPrincipalIdSelectorFunction(event, decodedToken) {
return 'principalId of your liking';
}
const authorizer = new (require('aws-apigw-authorizer')).ApiGatewayAuthorizer(
{ jwtPrincipalIdSelectorFunction: customJwtPrincipalIdSelectorFunction }
);
exports.handler = authorizer.handler.bind(authorizer);
If a custom principalId selector for JWT is not provided, the default principalId selector for JWT will be used which will try the following JWT claims in order, the first one that has a value will be used:
email
upn
sub
FAQs
AWS Lambda Authorizer for API Gateway
We found that aws-apigw-authorizer demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
vlt's new "reproduce" tool verifies npm packages against their source code, outperforming traditional provenance adoption in the JavaScript ecosystem.
Research
Security News
Socket researchers uncovered a malicious PyPI package exploiting Deezer’s API to enable coordinated music piracy through API abuse and C2 server control.
Research
The Socket Research Team discovered a malicious npm package, '@ton-wallet/create', stealing cryptocurrency wallet keys from developers and users in the TON ecosystem.