Skip to content

[Annotations] Fail authorizers when parameter conversion fails - #2591

Open
normj wants to merge 2 commits into
masterfrom
normj/fix-authorizer
Open

normj wants to merge 2 commits into
masterfrom
normj/fix-authorizer

Conversation

@normj

@normj normj commented Oct 8, 2026

Copy link
Copy Markdown
Member

Issue #, if available:

Description of changes:

Generated API Gateway authorizer handlers bind [FromHeader], [FromQuery] and [FromRoute] parameters (and the REST API TOKEN AuthorizationToken) with Convert.ChangeType. When conversion failed, for example abc for a long parameter, the generated code logged the error and then still invoked the authorizer method with the parameter set to default(T). The non-authorizer API Gateway template already returns a 400 in this case; the authorizer template had no equivalent.

Generated authorizers now fail closed: if any bound value fails to convert, the handler returns a deny response without invoking the authorizer method. The deny response matches the authorizer's return type:

Return type Response on conversion failure
IAuthorizerResult AuthorizerResults.Deny() serialized with the same format and method/route ARN as the normal path
APIGatewayCustomAuthorizerV2SimpleResponse IsAuthorized = false
APIGatewayCustomAuthorizerResponse / APIGatewayCustomAuthorizerV2IamResponse Deny policy for execute-api:Invoke on the method/route ARN
Any other type throw new Exception("Unauthorized")

The check is only emitted when the method has bound parameters. Missing values are unchanged and still bind as default(T).

Changes

  • AuthorizerSetupParameters.tt / .cs: track a __bindingFailed__ flag in each conversion catch block and emit the deny check after parameter binding. The preprocessed .cs was updated by hand to match the .tt, so it's worth regenerating in Visual Studio before merging.
  • AuthorizerSetupParametersCode.cs: generate the deny response for each return type.
  • TypeFullNames.cs: add APIGatewayCustomAuthorizerV2IamResponse and APIGatewayCustomAuthorizerPolicy.
  • Updated the 4 existing authorizer snapshots.
  • New AuthorizerBindingFailureTests: runs the generator, compiles the output, and invokes the generated handlers. It covers malformed header, query, route and token values across all response shapes, and asserts that the request is denied and the authorizer method isn't invoked. A control test checks that well-formed values still reach the method. Without the template change, 9 of the 10 tests fail.

Testing

  • Amazon.Lambda.Annotations.SourceGenerators.Tests: 593/593 passing on net8.0 and net10.0.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Generated API Gateway authorizer handlers previously logged a conversion
failure for [FromHeader], [FromQuery] and [FromRoute] parameters and then
invoked the authorizer method with the parameter set to default(T). They
now return a deny response matching the authorizer's return type without
invoking the authorizer method.
@normj normj changed the title Fail closed in generated authorizers when parameter conversion fails [Annotations] Fail authorizers when parameter conversion fails Oct 8, 2026
@normj
normj requested a balanced review from Copilot October 8, 2026 21:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

3 open findings
What changed in this PR

Updates the Annotations source generator so API Gateway authorizer handlers fail closed when parameter binding/conversion fails, aligning behavior with non-authorizer handlers and preventing “default(T)” from reaching user code.

Changes:

  • Track conversion failures during authorizer parameter binding and deny without invoking the user authorizer.
  • Generate deny responses appropriate to the authorizer’s return type (IAuthorizerResult, simple response, IAM policy, or throw Unauthorized).
  • Add targeted generator+runtime compilation tests and update snapshots.
File Description
Libraries/​src/​Amazon.Lambda.Annotations.SourceGenerator/​Templates/​AuthorizerSetupParameters.tt Emits __bindingFailed__ tracking and a deny check after parameter binding.
Libraries/​src/​Amazon.Lambda.Annotations.SourceGenerator/​Templates/​AuthorizerSetupParameters.cs Updates preprocessed T4 output to match the template changes.
Libraries/​src/​Amazon.Lambda.Annotations.SourceGenerator/​Templates/​AuthorizerSetupParametersCode.cs Adds helper logic to detect bound parameters and generate deny responses per return type.
Libraries/​src/​Amazon.Lambda.Annotations.SourceGenerator/​TypeFullNames.cs Adds missing full names for APIGW v2 IAM response and policy types.
Libraries/​test/​.../​AuthorizerBindingFailureTests.cs New integration-style tests that run the generator, compile output, and validate deny behavior + no user invocation.
Libraries/​test/​.../​Snapshots/​Authorizer_Generated.g.cs Snapshot updates to include binding-failure deny path.
.autover/​changes/​*.json Records a patch changelog entry for the behavior change.

🧠 Review effort: Lite


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@normj
normj marked this pull request as ready for review October 8, 2026 21:46
@normj
normj requested review from a team as code owners October 8, 2026 21:46
@normj
normj requested a review from boblodgett October 8, 2026 21:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants