Skip to content
Eugene Lazutkin edited this page Jul 17, 2026 · 2 revisions

lambda

The AWS Lambda port of the middleware family: cognito-toolkit/lambda, wrapping (event, context) => result handlers — including dynamodb-toolkit's createLambdaHandler. API Gateway v1, API Gateway v2 / Function URL, and ALB event shapes are auto-detected.

import {makeAuth} from 'cognito-toolkit/lambda';

function makeAuth<Payload extends object = JwtPayload>(options: AuthOptions<Payload>): Auth<Payload>;

type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2 | ALBEvent; // from @types/aws-lambda
type LambdaResult = APIGatewayProxyResult | APIGatewayProxyStructuredResultV2 | ALBResult;
type LambdaHandler = (event: LambdaEvent, ...rest: any[]) => LambdaResult | Promise<LambdaResult>;

interface Auth<Payload> {
  getUser(event: LambdaEvent): Promise<AuthUser<Payload> | null>; // memoized per event
  isAuthenticated(handler: LambdaHandler): LambdaHandler;
  hasGroup(group: string): (handler: LambdaHandler) => LambdaHandler;
  hasScope(scope: string): (handler: LambdaHandler) => LambdaHandler;
  isAllowed(validator: (event: LambdaEvent, groups: string[], scopes: string[]) => boolean | Promise<boolean>): (handler: LambdaHandler) => LambdaHandler;
  setAuthCookie(event: LambdaEvent, result: LambdaResult, cookieOptions?: CookieOptions): Promise<LambdaResult>;
}

type AuthUser<Payload> = Payload & {_token: string};

Options: see Middleware ports § Options — no stateUserProperty here. Event/result types come from @types/aws-lambda; the payload type flows from the verifier.

Example

import {CognitoJwtVerifier} from 'cognito-toolkit';
import {makeAuth} from 'cognito-toolkit/lambda';

const verifier = CognitoJwtVerifier.create({userPoolId: 'us-east-1_MY_POOL', clientId: 'my-app-client', tokenUse: 'access'});
const auth = makeAuth({verifier});

export const handler = auth.hasGroup('admins')(async (event, context) => ({statusCode: 200, body: 'ok'}));

When to use it

Behind API Gateway proper, prefer the built-in Cognito / JWT authorizer — it rejects bad tokens without invoking your function. This port's niche:

  • Function URLs — their only auth options are IAM or none, so a public URL wanting Cognito JWT auth must verify in code.
  • ALB targets — when the ALB's authenticate-cognito action forwards x-amzn-oidc-data, pair this port with AlbJwtVerifier (re-exported from the package root) as the verifier.
  • Local-debug bridges — e.g. dynamodb-toolkit's lambda/local.js driving the composed, guarded handler from real HTTP traffic.

Port specifics

  • Event shapes: ALB is detected by requestContext.elb, v2 / Function URL by version === '2.0', everything else is v1. Headers are read case-insensitively (v2 lowercases them, v1/ALB preserve the sender's casing); v2 cookies come from event.cookies; ALB multi-value mode (multiValueHeaders with null-stamped headers) is honored on reads and mirrored on responses.
  • Denials are result envelopes — {statusCode: 401 | 403, body: ''}, with multiValueHeaders: {} added when the trigger runs in ALB multi-value mode.
  • setAuthCookie is async, shape-aware (v2 cookies array; v1/ALB headers, lifted to multiValueHeaders when required), and mutates + returns the result. Automatic refresh via setAuthCookieOptions applies to results passing through guards. Domain defaults to requestContext.domainName or the Host header, port stripped.

Clone this wiki locally