Context:
EasySAM generates AWS SAM templates for API Gateway (AWS::Serverless::Api), including routes, authorizers, and CORS configuration.
Problem:
When a request fails authentication (invalid or missing token), API Gateway returns a 401 UnauthorizedException BEFORE invoking Lambda.
These 401/403 responses do NOT include CORS headers, even though:
- OPTIONS (preflight) responses include correct CORS headers
- Successful authenticated requests include correct CORS headers
Observed behavior:
- OPTIONS → 200 with CORS headers
- GET with valid token → 200, response readable in browser
- GET with invalid/missing token → 401 UnauthorizedException (from API Gateway)
- 401 response has NO Access-Control-Allow-Origin header
- Browser blocks response and reports CORS/network error instead of exposing 401
Impact:
- Frontend cannot distinguish auth failure from network/CORS failure
- Proper auth flows (token refresh, re-login) break
- Debugging becomes misleading
Root cause:
EasySAM configures CORS only for:
- OPTIONS (preflight)
- Integration/Lambda responses (via Swagger/SAM)
But does NOT configure API Gateway GatewayResponses:
- UNAUTHORIZED
- ACCESS_DENIED
- DEFAULT_4XX
- DEFAULT_5XX
Since these responses are generated by API Gateway before Lambda, runtime code (FastAPI/Vial/etc.) cannot add CORS headers.
Why this belongs in EasySAM:
EasySAM owns API Gateway/SAM generation (RestApi, Authorizers, Swagger, CORS).
The missing behavior is at API Gateway configuration level, not application code.
Proposed fix:
Extend EasySAM template generation to include GatewayResponses with CORS headers for every API that has CORS enabled.
Implementation requirements:
-
For each generated RestApi, add resources:
- AWS::ApiGateway::GatewayResponse:
- DEFAULT_4XX
- DEFAULT_5XX
- UNAUTHORIZED
- ACCESS_DENIED
-
Each GatewayResponse must include:
gatewayresponse.header.Access-Control-Allow-Origin
gatewayresponse.header.Access-Control-Allow-Methods
gatewayresponse.header.Access-Control-Allow-Headers
(and Access-Control-Allow-Credentials if CORS config enables it)
-
Header values must:
- Reuse existing CORS configuration from EasySAM (origins, headers, credentials)
- NOT be hardcoded
- Match behavior of successful responses
-
Solution must be:
- Global (API-level), not per-route
- Path-agnostic
- Compatible with authorizer-generated responses (pre-Lambda)
- Automatically applied (no manual patching in services)
-
Do NOT:
- Modify Lambda runtime code
- Add per-route CORS hacks
- Depend on specific endpoints like /assets or /channels
Acceptance criteria:
- GET with invalid/missing token returns 401 visible to browser (not CORS error)
- 401 response includes Access-Control-Allow-Origin
- Frontend can read response and handle auth failure correctly
- Behavior consistent across all routes behind the same API Gateway
- OPTIONS and successful requests remain unchanged
Context:
EasySAM generates AWS SAM templates for API Gateway (AWS::Serverless::Api), including routes, authorizers, and CORS configuration.
Problem:
When a request fails authentication (invalid or missing token), API Gateway returns a 401 UnauthorizedException BEFORE invoking Lambda.
These 401/403 responses do NOT include CORS headers, even though:
Observed behavior:
Impact:
Root cause:
EasySAM configures CORS only for:
But does NOT configure API Gateway GatewayResponses:
Since these responses are generated by API Gateway before Lambda, runtime code (FastAPI/Vial/etc.) cannot add CORS headers.
Why this belongs in EasySAM:
EasySAM owns API Gateway/SAM generation (RestApi, Authorizers, Swagger, CORS).
The missing behavior is at API Gateway configuration level, not application code.
Proposed fix:
Extend EasySAM template generation to include GatewayResponses with CORS headers for every API that has CORS enabled.
Implementation requirements:
For each generated RestApi, add resources:
Each GatewayResponse must include:
gatewayresponse.header.Access-Control-Allow-Origin
gatewayresponse.header.Access-Control-Allow-Methods
gatewayresponse.header.Access-Control-Allow-Headers
(and Access-Control-Allow-Credentials if CORS config enables it)
Header values must:
Solution must be:
Do NOT:
Acceptance criteria: