fix(apigateway): StepFunctionsIntegration doesn't pass Cognito authorizer claims
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 4.6k
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 83
Description
### Describe the bug
When using `StepFunctionsIntegration` with a Cognito User Pool Authorizer and `authorizer: true` option, the Cognito claims are not properly passed to the Step Functions execution input. The VTL template iterates over `$context.authorizer.keySet()` but Cognito claims are nested under `$context.authorizer.claims`, resulting in an empty authorizer object.
### Regression Issue
- [ ] Select this option if this issue appears to be a regression.
### Last Known Working CDK Library Version
_No response_
### Expected Behavior
The Step Functions execution input should contain all Cognito claims inside the `authorizer` object:
```json
{
"authorizer": {
"sub": "user-id",
"email": "user@example.com",
"cognito:username": "username"
}
}
```
### Current Behavior
The authorizer object is empty or only contains top-level properties, missing the claims:
```json
{
"authorizer": {
"claims": ""
}
}
```
### Reproduction Steps
1. Create a Cognito User Pool
2. Create a RestApi with StepFunctionsIntegration
3. Configure the method with Cognito User Pool Authorizer
4. Set `authorizer: true` in the integration options
5. Deploy and invoke the API with a valid Cognito token
6. Observe that the Step Functions execution input has an empty authorizer object
### Possible Solution
The VTL template in `packages/aws-cdk-lib/aws-apigateway/lib/integrations/stepfunctions.vtl` (lines 53-62) needs to handle Cognito claims:
**Current code:**
```vtl
#if ($includeAuthorizer)
#set($inputString = "$inputString, @@authorizer@@:{")
#foreach($paramName in $context.authorizer.keySet())
#set($inputString = "$inputString @@$paramName@@: @@$util.escapeJavaScript($context.authorizer.get($
paramName))@@")
#if($foreach.hasNext)
#set($inputString = "$inputString,")
#end
#end
#set($inputString = "$inputString }")
#end
```
**Suggested fix:**
```vtl
#if ($includeAuthorizer)
#set($inputString = "$inputString, @@authorizer@@:{")
#if ($context.authorizer.claims)
#foreach($paramName in $context.authorizer.claims.keySet())
#set($inputString = "$inputString @@$paramName@@: @@$util.escapeJavaScript($
context.authorizer.claims.get($paramName))@@")
#if($foreach.hasNext)
#set($inputString = "$inputString,")
#end
#end
#else
#foreach($paramName in $context.authorizer.keySet())
#set($inputString = "$inputString @@$paramName@@: @@$util.escapeJavaScript($context.authorizer.get($
paramName))@@")
#if($foreach.hasNext)
#set($inputString = "$inputString,")
#end
#end
#end
#set($inputString = "$inputString }")
#end
```
### Additional Information/Context
_No response_
### AWS CDK Library version (aws-cdk-lib)
2.238.0
### AWS CDK CLI version
2.1105.0 (build 3e25a4e)
### Node.js Version
v24.12.0
### OS
Linux
### Language
TypeScript
### Language Version
5.9.3
### Other information
This issue is related to #30144 which was closed due to staleness. The problem still exists in the current version.
The fix should handle both Cognito User Pool Authorizers (claims in `$context.authorizer.claims`) and Lambda Authorizers (properties in `$context.authorizer`).
Contributor guide
Research direction
Start at packages/aws-cdk-lib/aws-apigateway/lib/integrations/stepfunctions.vtl and inspect the StepFunctionsIntegration authorizer template around lines 53-62. Reproduce the Cognito and Lambda authorizer cases described in the issue; done means Cognito claims appear inside the authorizer object while Lambda authorizer properties continue to work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, typescript
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100