Skip to content

fromx support for authorizers#2304

Draft
GarrettBeatty wants to merge 2 commits intofeature/authfrom
auth3
Draft

fromx support for authorizers#2304
GarrettBeatty wants to merge 2 commits intofeature/authfrom
auth3

Conversation

@GarrettBeatty
Copy link
Contributor

Here's the PR description:


Add IAuthorizerResult and FromX Attribute Support for Lambda Authorizer Functions

Description

This PR introduces a simplified developer experience for writing Lambda authorizer functions using the Annotations framework. It follows the same pattern established by IHttpResult for API Gateway endpoint responses — providing IAuthorizerResult as a high-level abstraction that hides the raw API Gateway authorizer response types and IAM policy construction.

Previously, authorizer functions required users to manually work with raw API Gateway types (APIGatewayCustomAuthorizerV2Request, APIGatewayCustomAuthorizerV2SimpleResponse, APIGatewayCustomAuthorizerResponse), construct IAM policy documents by hand, and manage context dictionaries directly. This was verbose and error-prone, especially for REST API authorizers where ~15 lines of IAM policy boilerplate was needed for a simple allow/deny.

Before (existing pattern — still supported)

[LambdaFunction]
[RestApiAuthorizer(Type = RestApiAuthorizerType.Token)]
public APIGatewayCustomAuthorizerResponse Authorize(
    APIGatewayCustomAuthorizerRequest request, ILambdaContext context)
{
    var token = request.AuthorizationToken;
    if (!IsValid(token))
        return new APIGatewayCustomAuthorizerResponse
        {
            PrincipalID = "user",
            PolicyDocument = new APIGatewayCustomAuthorizerPolicy
            {
                Version = "2012-10-17",
                Statement = new List<APIGatewayCustomAuthorizerPolicy.IAMPolicyStatement>
                {
                    new() { Action = new HashSet<string> { "execute-api:Invoke" },
                            Effect = "Deny", Resource = new HashSet<string> { request.MethodArn } }
                }
            }
        };
    // ... similar for Allow with context
}

After (new pattern)

[LambdaFunction]
[RestApiAuthorizer(Type = RestApiAuthorizerType.Token)]
public IAuthorizerResult Authorize(
    [FromHeader(Name = "Authorization")] string authorization, ILambdaContext context)
{
    if (!IsValid(authorization))
        return AuthorizerResults.Deny();

    return AuthorizerResults.Allow()
        .WithPrincipalId("user-123")
        .WithContext("userId", "user-123")
        .WithContext("role", "admin");
}

Key Changes

New Types (Amazon.Lambda.Annotations)

  • IAuthorizerResult — Interface representing an authorizer result with IsAuthorized, PrincipalId, Context, and fluent WithContext()/WithPrincipalId() methods
  • AuthorizerResults — Implementation with static Allow() and Deny() factory methods. Handles serialization to the correct API Gateway response format (HTTP API simple, HTTP API IAM policy, or REST API IAM policy)
  • AuthorizerResultSerializationOptions — Configuration for the serialization format and method ARN

Source Generator Changes (Amazon.Lambda.Annotations.SourceGenerator)

  • EventType.Authorizer — New event type detected when [HttpApiAuthorizer] or [RestApiAuthorizer] is present
  • GeneratedMethodModelBuilder — Handles authorizer request/response type selection:
    • HTTP API V2 → APIGatewayCustomAuthorizerV2Request input, Stream output (when returning IAuthorizerResult)
    • HTTP API V1 / REST API → APIGatewayCustomAuthorizerRequest input, Stream output
    • Raw return types → pass-through (backwards compatible)
  • AuthorizerSetupParameters template — Extracts [FromHeader], [FromQuery], [FromRoute] from authorizer request objects
  • AuthorizerInvoke template — Calls user method and serializes IAuthorizerResult with correct format/MethodArn
  • LambdaFunctionTemplate — Routes to authorizer templates when EventType.Authorizer is detected
  • LambdaFunctionValidator — Updated to allow FromX attributes on authorizer functions (previously only allowed on [HttpApi]/[RestApi] endpoints)
  • TypeFullNames — Added constants for IAuthorizerResult, authorizer request/response types

Supported Patterns

Pattern HTTP API (Simple) HTTP API (IAM Policy) REST API
IAuthorizerResult + FromX attributes
Raw request/response types (backwards compat)
Mixed: raw request + IAuthorizerResult return
Async (Task<IAuthorizerResult>)
Dependency Injection

Testing

  • Added SimpleHttpApiAuthorize and SimpleRestApiAuthorize example methods to TestCustomAuthorizerApp demonstrating the new pattern
  • Build verified successfully with existing and new authorizer functions

Backwards Compatibility

This is a purely additive change. The existing pattern (raw API Gateway request/response types) continues to work exactly as before. The source generator detects which pattern the user chose based on the return type (IAuthorizerResult → new simplified path, raw types → existing pass-through path).

source gen tests

add IT tests

fix serialization

update generator for rest

in progress
@GarrettBeatty GarrettBeatty requested a review from Copilot March 18, 2026 18:47
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a higher-level authorizer programming model to the Lambda Annotations framework—IAuthorizerResult + AuthorizerResults—and extends the source generator so authorizer functions can use FromHeader/FromQuery/FromRoute parameter binding (similar to API endpoints). It also updates test apps, snapshots, and integration tests to validate the new authorizer flow end-to-end.

Changes:

  • Introduces IAuthorizerResult, AuthorizerResults, and AuthorizerResultSerializationOptions to simplify authorizer responses (simple responses + IAM policy).
  • Updates the source generator to detect authorizer methods (EventType.Authorizer), bind FromX parameters for authorizers, and serialize IAuthorizerResult.
  • Adds/updates example apps, serverless templates, snapshots, and integration tests for HTTP API + REST API authorizers using the new pattern.

Reviewed changes

Copilot reviewed 45 out of 45 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
Libraries/src/Amazon.Lambda.Annotations/APIGateway/IAuthorizerResult.cs Adds new authorizer result abstraction interface.
Libraries/src/Amazon.Lambda.Annotations/APIGateway/AuthorizerResults.cs Implements Allow/Deny + context/principal + serialization logic.
Libraries/src/Amazon.Lambda.Annotations/APIGateway/AuthorizerResultSerializationOptions.cs Defines serialization format/options passed from generated handlers.
Libraries/src/Amazon.Lambda.Annotations/README.md Documents the new simplified authorizer pattern and FromX support.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/EventType.cs Adds Authorizer event type.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/EventTypeBuilder.cs Detects [HttpApiAuthorizer]/[RestApiAuthorizer] as authorizer events.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/LambdaMethodModel.cs Adds ReturnsIAuthorizerResult detection for IAuthorizerResult / Task<IAuthorizerResult>.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/GeneratedMethodModelBuilder.cs Selects authorizer request types and sets generated return type to Stream for IAuthorizerResult.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Models/Attributes/AttributeModelBuilder.cs Adds model building for authorizer attributes.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/TypeFullNames.cs Adds type constants for authorizers and updates request-type recognition.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Validation/LambdaFunctionValidator.cs Updates dependency checks and authorizer-vs-API validation flow.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.tt Routes generation to authorizer templates when EventType.Authorizer is present.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/LambdaFunctionTemplate.cs Generated C# for the template routing changes.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/AuthorizerSetupParameters.tt New template to bind FromX params for authorizer requests.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/AuthorizerSetupParameters.cs Preprocessed template output for authorizer setup parameters.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/AuthorizerSetupParametersCode.cs Template helper class for authorizer setup parameters.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/AuthorizerInvoke.tt New template to invoke user authorizer method + serialize IAuthorizerResult.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/AuthorizerInvoke.cs Preprocessed template output for authorizer invocation.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Templates/AuthorizerInvokeCode.cs Template helper class for authorizer invocation.
Libraries/src/Amazon.Lambda.Annotations.SourceGenerator/Amazon.Lambda.Annotations.SourceGenerator.csproj Registers new .tt templates for preprocessing/compilation.
Libraries/test/TestServerlessApp/IAuthorizerResultExample.cs Adds example authorizer methods using IAuthorizerResult + [FromHeader].
Libraries/test/TestServerlessApp/serverless.template Adds dedicated HttpApi/RestApi resources + new authorizer functions and API IDs.
Libraries/test/TestServerlessApp/aws-lambda-tools-defaults.json Updates deployment defaults (bucket/stack).
Libraries/test/TestServerlessApp.IntegrationTests/IntegrationTestContextFixture.cs Updates expected API resource names + function count.
Libraries/test/TestExecutableServerlessApp/serverless.template Regenerates/updates template output for executable test app.
Libraries/test/TestCustomAuthorizerApp/AuthorizerFunction.cs Adds simplified authorizer implementations returning IAuthorizerResult.
Libraries/test/TestCustomAuthorizerApp/ProtectedFunction.cs Adds protected endpoints using the new simple authorizers.
Libraries/test/TestCustomAuthorizerApp/serverless.template Adds resources for new authorizers + protected endpoints.
Libraries/test/TestCustomAuthorizerApp/src/Function/serverless.template Updates authorizer names + adds simple authorizer resources/endpoints.
Libraries/test/TestCustomAuthorizerApp/aws-lambda-tools-defaults.json Updates deployment defaults (bucket/stack).
Libraries/test/TestCustomAuthorizerApp.IntegrationTests/IntegrationTestContextFixture.cs Updates expected function count for new authorizer endpoints.
Libraries/test/TestCustomAuthorizerApp.IntegrationTests/SimpleHttpApiAuthorizerTests.cs New integration tests for HTTP API simple authorizer flow.
Libraries/test/TestCustomAuthorizerApp.IntegrationTests/SimpleRestApiAuthorizerTests.cs New integration tests for REST API IAM policy authorizer flow.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/SourceGeneratorTests.cs Adds snapshot coverage for new authorizer templates/handlers.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/customAuthorizerApp.template Updates expected generated template for custom authorizer app.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ServerlessTemplates/authorizerIAuthorizerResult.template Adds expected template snapshot for IAuthorizerResult example.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/AuthorizerFunction_SimpleHttpApiAuthorize_Generated.g.cs Adds expected generated handler snapshot for simple HTTP API authorizer.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/AuthorizerFunction_SimpleRestApiAuthorize_Generated.g.cs Adds expected generated handler snapshot for simple REST API authorizer.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IAuthorizerResultExample_SimpleHttpApiAuthorizer_Generated.g.cs Adds expected generated handler snapshot for test-serverless-app HTTP API authorizer.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/IAuthorizerResultExample_SimpleRestApiAuthorizer_Generated.g.cs Adds expected generated handler snapshot for test-serverless-app REST API authorizer.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProtectedFunction_GetSimpleHttpApiUserInfo_Generated.g.cs Adds expected generated handler snapshot for protected HTTP API endpoint.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/ProtectedFunction_GetSimpleRestApiUserInfo_Generated.g.cs Adds expected generated handler snapshot for protected REST API endpoint.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/AuthorizerFunction_HttpApiAuthorize_Generated.g.cs Minor snapshot changes from regeneration.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/AuthorizerFunction_HttpApiAuthorizeV1_Generated.g.cs Minor snapshot changes from regeneration.
Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Snapshots/AuthorizerFunction_RestApiAuthorize_Generated.g.cs Minor snapshot changes from regeneration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines 54 to 60
public static HashSet<string> Requests = new HashSet<string>
{
APIGatewayProxyRequest,
APIGatewayHttpApiV2ProxyRequest
APIGatewayHttpApiV2ProxyRequest,
APIGatewayCustomAuthorizerV2Request,
APIGatewayCustomAuthorizerRequest
};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is a good suggestion i will do that

/// <code>
/// [LambdaFunction]
/// [HttpApiAuthorizer(EnableSimpleResponses = true)]
/// public IAuthorizerResult Authorize([FromHeader("Authorization")] string auth, ILambdaContext context)
Comment on lines +63 to +68
/// Serialize the authorizer result into the correct API Gateway response format.
/// This is called by the generated Lambda handler code.
/// </summary>
/// <param name="options">Serialization options that determine the output format</param>
/// <returns>The serialized response object (type depends on the authorizer format)</returns>
object Serialize(AuthorizerResultSerializationOptions options);
Comment on lines +304 to +307
ILambdaContext context)
{
context.Logger.LogLine($"Simple Authorizer invoked with authorization: {authorization}");

Comment on lines +334 to +338
[FromHeader(Name = "Authorization")] string authorization,
ILambdaContext context)
{
context.Logger.LogLine($"Simple REST Authorizer invoked with authorization: {authorization}");

Comment on lines +119 to +122
// If this is an Authorizer event, skip the API Gateway-specific parameter validation below
if (lambdaFunctionModel.LambdaMethod.Events.Contains(EventType.Authorizer))
{
return;
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