Skip to content

HttpApi: explicit AuthorizationScopes: [] is silently overridden by the authorizer's default scopes #3979

Description

@Adityaj0

Describe the bug

For AWS::Serverless::HttpApi, setting Auth.AuthorizationScopes: [] on an individual function/event's Auth block is documented and (for AWS::Serverless::Api, i.e. REST APIs) implemented to mean "require no scopes for this method, overriding the named authorizer's default AuthorizationScopes."

For HTTP APIs this override is silently dropped: the authorizer's default scopes are applied anyway, as if AuthorizationScopes had not been set at all.

Root cause

OpenApiEditor.add_auth_to_method (samtranslator/open_api/open_api.py):

authorization_scopes = auth.get("AuthorizationScopes", [])

defaults an unset value to []. This is then passed into _set_method_authorizer, which checks it with:

if authorization_scopes:
    method_authorization_scopes = authorization_scopes

Since [] is falsy, this can't distinguish "the user didn't set AuthorizationScopes" from "the user explicitly set AuthorizationScopes: []" — both take the "not set" branch, so the authorizer's own default AuthorizationScopes is used instead of the empty override.

The REST API equivalent, SwaggerEditor.add_auth_to_method/_set_method_authorizer in samtranslator/swagger/swagger.py, gets this right:

method_scopes = auth and auth.get("AuthorizationScopes")   # None, not [], when unset
...
if method_scopes is not None:
    method_auth_scopes = method_scopes

which correctly distinguishes "unset" (None) from "explicitly cleared" ([]).

Reproduction

Resources:
  MyApi:
    Type: AWS::Serverless::HttpApi
    Properties:
      Auth:
        Authorizers:
          MyAuth:
            JwtConfiguration: {...}
            IdentitySource: $request.header.Authorization
            AuthorizationScopes: [default.delete, default.update]

  MyFn:
    Type: AWS::Serverless::Function
    Properties:
      ...
      Events:
        Api:
          Type: HttpApi
          Properties:
            ApiId: !Ref MyApi
            Path: /x
            Method: get
            Auth:
              Authorizer: MyAuth
              AuthorizationScopes: []

Expected behavior

The generated OpenAPI security block for GET /x should be {"MyAuth": []} — no required scopes, matching what the equivalent REST API (AWS::Serverless::Api) template already produces (see tests/translator/input/api_with_auth_with_default_scopes.yaml, cases CognitoDefaultScopesNone / CognitoDefaultAuthDefaultScopesNone).

Actual behavior

The generated security block is {"MyAuth": ["default.delete", "default.update"]} — the authorizer's default scopes are enforced anyway, silently ignoring the explicit override. This causes requests the user intended to allow without those scopes to be rejected by API Gateway.

Fix

PR incoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions