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.
Describe the bug
For
AWS::Serverless::HttpApi, settingAuth.AuthorizationScopes: []on an individual function/event'sAuthblock is documented and (forAWS::Serverless::Api, i.e. REST APIs) implemented to mean "require no scopes for this method, overriding the named authorizer's defaultAuthorizationScopes."For HTTP APIs this override is silently dropped: the authorizer's default scopes are applied anyway, as if
AuthorizationScopeshad not been set at all.Root cause
OpenApiEditor.add_auth_to_method(samtranslator/open_api/open_api.py):defaults an unset value to
[]. This is then passed into_set_method_authorizer, which checks it with:Since
[]is falsy, this can't distinguish "the user didn't setAuthorizationScopes" from "the user explicitly setAuthorizationScopes: []" — both take the "not set" branch, so the authorizer's own defaultAuthorizationScopesis used instead of the empty override.The REST API equivalent,
SwaggerEditor.add_auth_to_method/_set_method_authorizerinsamtranslator/swagger/swagger.py, gets this right:which correctly distinguishes "unset" (
None) from "explicitly cleared" ([]).Reproduction
Expected behavior
The generated OpenAPI
securityblock forGET /xshould be{"MyAuth": []}— no required scopes, matching what the equivalent REST API (AWS::Serverless::Api) template already produces (seetests/translator/input/api_with_auth_with_default_scopes.yaml, casesCognitoDefaultScopesNone/CognitoDefaultAuthDefaultScopesNone).Actual behavior
The generated
securityblock 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.