Description
Expected Behaviour
I have defined an apigateway rest resolver with swagger enabled and a security scheme with oauth.
I have two endpoints, one protected, and one unprotected. I explicitly define the unprotected endpoint with security empty, so I would expect it to override the global config of swagger and be unprotected.
Current Behaviour
Currently, the unprotected security of the route is not overwritten. Instead, the global config seems to be applied over the specific one of the router. This only happens if the specific config is an empty list.
However, if the global config of security is an empty list or not defined at all, defining a specific security config in a route overwrites it.
With the current behaviour, if I want to keep all resources protected except one, I need to remove the global config of security, and put it in each route that i want protected.
Code snippet
import json
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.event_handler.openapi.models import OAuth2, OAuthFlows, OAuthFlowAuthorizationCode
app = APIGatewayRestResolver(enable_validation=True)
app.enable_swagger(
path="/swagger",
security_schemes={
"oauth": OAuth2(
flows=OAuthFlows(
authorizationCode=OAuthFlowAuthorizationCode(
authorizationUrl="",
tokenUrl="",
scopes={
"email": "email scope",
"openid": "openid scope",
"profile": "profile scope",
},
),
),
)
},
security=[{"oauth": ["openid", "profile", "email"]}]
)
@app.get("/unprotected", security=[])
def unprotected() -> dict:
return {}
@app.get("/protected", security=[{"oauth": ["openid", "profile", "email"]}])
def protected() -> dict:
return {}
def lambda_handler(event, context):
return app.resolve(event, context)
if __name__ == "__main__":
test_event = {
"body": json.dumps({}),
"httpMethod": "GET",
"path": "/swagger",
"headers": {
"Content-Type": "application/json"
},
"requestContext": {
"requestId": "test-id",
"stage": "test-stage",
"path": "/swagger",
}
}
result = lambda_handler(test_event, {})
# store swagger in file to be able to check it
with open("swagger.html", "w") as f:
f.write(result["body"])
Possible Solution
Either clarify the docs of the enable_swagger() or make the specific router security options override the global security even if the security is empty.
Steps to Reproduce
- Copy the snippet provided.
- Run it and open the generated swagger.html
- The unprotected endpoint is protected (I expected it to not be protected)
- Remove the global security config from the enable_swagger()
- Rerun and reload the swagger.html
- The unprotected endpoint is now marked as unprotected as expected
Powertools for AWS Lambda (Python) version
latest
AWS Lambda function runtime
3.12
Packaging format used
Lambda Layers
Debugging logs
Metadata
Metadata
Assignees
Type
Projects
Status