aws / aws/serverless-application-model

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

Open Beginner friendly
#3,979 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
9.6k
Forks
2.5k
Avg merge
1d 11h
Merged PRs (30d)
7

Description

### 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`):

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

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

```python
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:

```python
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

```yaml
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.

Contributor guide

Open the contributing guide

Research direction

Start in samtranslator/open_api/open_api.py at OpenApiEditor.add_auth_to_method and _set_method_authorizer, comparing the REST equivalent in samtranslator/swagger/swagger.py. Inspect the documented cases in tests/translator/input/api_with_auth_with_default_scopes.yaml and run the relevant HTTP API authorization-scope tests; done means an explicit [] produces an empty security scope while an unset value preserves authorizer defaults.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python
Domain
api
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
82/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.