Skip to main content
The SST SDK provides authentication helpers for working with the Auth component.

Import

import { auth } from "sst/auth";
import { AuthAdapter } from "sst/auth/adapter";

Usage

The auth helpers work with SST’s Auth component to handle authentication flows.

Basic Auth Flow

import { auth } from "sst/auth";
import { Resource } from "sst";

export const handler = auth.authorizer(async (event) => {
  const token = event.headers.authorization?.replace("Bearer ", "");
  
  if (!token) {
    return {
      statusCode: 401,
      body: "Unauthorized"
    };
  }
  
  // Validate token and return user context
  return {
    statusCode: 200,
    user: {
      id: "user-123",
      email: "[email protected]"
    }
  };
});

Auth Adapters

SST provides adapters for popular authentication providers.

Cognito Adapter

import { AuthAdapter } from "sst/auth/adapter";
import { Resource } from "sst";

const adapter = AuthAdapter.cognito({
  userPoolId: Resource.MyUserPool.id
});

export const handler = async (event) => {
  const user = await adapter.verify(event);
  
  return {
    statusCode: 200,
    body: JSON.stringify({ user })
  };
};

Custom Adapter

Create your own auth adapter:
import { AuthAdapter } from "sst/auth/adapter";

const customAdapter = {
  async verify(event) {
    const token = event.headers.authorization?.replace("Bearer ", "");
    
    // Your custom verification logic
    const decoded = await verifyJWT(token);
    
    return {
      id: decoded.sub,
      email: decoded.email
    };
  }
};

export const handler = async (event) => {
  const user = await customAdapter.verify(event);
  
  return {
    statusCode: 200,
    body: JSON.stringify({ user })
  };
};

Session Management

Handle user sessions in your functions:
import { Resource } from "sst";

export const handler = async (event) => {
  // Get user from auth context
  const userId = event.requestContext.authorizer.userId;
  
  // Fetch user data
  const user = await getUserFromDatabase(userId);
  
  return {
    statusCode: 200,
    body: JSON.stringify({ user })
  };
};

Protecting Routes

Use auth with API Gateway:
sst.config.ts
const auth = new sst.aws.Auth("MyAuth", {
  authorizer: {
    handler: "src/authorizer.handler"
  }
});

const api = new sst.aws.ApiGatewayV2("MyApi");

api.route("GET /protected", {
  handler: "src/protected.handler",
  auth: auth
});

api.route("GET /public", {
  handler: "src/public.handler"
  // No auth - publicly accessible
});

JWT Verification

Verify JWTs in your handlers:
import { createRemoteJWKSet, jwtVerify } from "jose";

const JWKS = createRemoteJWKSet(
  new URL("https://cognito-idp.us-east-1.amazonaws.com/us-east-1_abc/.well-known/jwks.json")
);

export const handler = async (event) => {
  const token = event.headers.authorization?.replace("Bearer ", "");
  
  try {
    const { payload } = await jwtVerify(token, JWKS);
    
    return {
      statusCode: 200,
      body: JSON.stringify({ user: payload })
    };
  } catch (error) {
    return {
      statusCode: 401,
      body: "Invalid token"
    };
  }
};

OAuth Flows

Handle OAuth callbacks:
import { Resource } from "sst";

export const handler = async (event) => {
  const code = event.queryStringParameters?.code;
  
  if (!code) {
    return {
      statusCode: 400,
      body: "Missing code parameter"
    };
  }
  
  // Exchange code for tokens
  const response = await fetch("https://oauth.example.com/token", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      code,
      client_id: Resource.OAuthClientId.value,
      client_secret: Resource.OAuthClientSecret.value,
      grant_type: "authorization_code"
    })
  });
  
  const tokens = await response.json();
  
  return {
    statusCode: 302,
    headers: {
      Location: `/dashboard?token=${tokens.access_token}`
    }
  };
};

Best Practices

Validate All Tokens

Always validate tokens before trusting them:
// ✓ Good - validates token
const { payload } = await jwtVerify(token, JWKS);

// ✗ Avoid - trusts token without validation
const payload = JSON.parse(atob(token.split(".")[1]));

Use Secure Headers

Set appropriate security headers:
return {
  statusCode: 200,
  headers: {
    "Content-Security-Policy": "default-src 'self'",
    "X-Content-Type-Options": "nosniff",
    "X-Frame-Options": "DENY"
  },
  body: JSON.stringify({ data })
};

Handle Token Expiry

Check token expiration:
const { payload } = await jwtVerify(token, JWKS);

if (payload.exp && payload.exp < Date.now() / 1000) {
  return {
    statusCode: 401,
    body: "Token expired"
  };
}

Auth Component

Set up authentication in your infrastructure

Resource Access

Access linked resources at runtime

Build docs developers (and LLMs) love