Skip to content

test(cdk): fail synth when a route has no authorizer - #22

Open
patote85 wants to merge 1 commit into
mainfrom
cursor/cdk-route-authorizer-synth-test-f03e
Open

patote85 wants to merge 1 commit into
mainfrom
cursor/cdk-route-authorizer-synth-test-f03e

Conversation

@patote85

@patote85 patote85 commented Oct 20, 2026 •

Copy link
Copy Markdown
Owner

In your own words

I need a test that synthesizes this CDK stack and fails when any HTTP API route is missing an authorizer. GET /health is the only route that may stay open. PR #21 wrote that rule into ADR-002 and left the check as a CAB follow-up. The rule still lives as prose. A new route can omit the authorizer and make check still passes. The CORS test scans cdk/ for a * string and stops there.

Why

ADR-002 requires an authorizer on every HttpApi route except GET /health. test_every_http_route_has_authorizer_except_get_health synthesizes ExclusaoClienteStack and reads each AWS::ApiGatewayV2::Route. The test fails when AuthorizationType is missing or NONE, and when JWT or CUSTOM has no AuthorizerId.

What changed

  • The new test synthesizes the stack and checks every route.
  • The CI test job installs cdk/requirements.txt and Node 20 so pytest can import aws_cdk.
  • Current template: POST /solicitar-exclusao-cliente, GET /status-exclusao/{cliente_id}, and POST /confirmar-pagamento are JWT with an AuthorizerId. GET /health is AuthorizationType NONE. No other route is missing an authorizer, so there is no route to report or leave broken.
  • ADR-002 still lists this test under Pendente. This diff leaves that sentence in place.

Blast radius

Deployed resources stay the same. A later route with no authorizer fails the test job. That job also installs the CDK library and Node, so a broken install fails the job even when the routes are fine.

The safety fact is that cdk/app.py is unchanged. git diff main -- cdk/app.py is empty, and make check runs npx --yes aws-cdk@2 synth to exit 0.

Verification

Temporary GET /cab-caveat-probe with no authorizer, not committed. python3 -m pytest tests/test_cdk_route_authorizer.py -v --tb=short exited 1:

============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-9.1.1, pluggy-1.7.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /workspace
configfile: pyproject.toml
plugins: typeguard-2.13.3
collecting ... collected 1 item

tests/test_cdk_route_authorizer.py::test_every_http_route_has_authorizer_except_get_health FAILED [100%]

=================================== FAILURES ===================================
____________ test_every_http_route_has_authorizer_except_get_health ____________
tests/test_cdk_route_authorizer.py:57: in test_every_http_route_has_authorizer_except_get_health
    assert not offenders, (
E   AssertionError: Every API route needs an authorizer except GET /health. Offenders:
E     ExclusaoClienteHttpApiGETcabcaveatprobe74EC9593: GET /cab-caveat-probe AuthorizationType='NONE'
E   assert not ["ExclusaoClienteHttpApiGETcabcaveatprobe74EC9593: GET /cab-caveat-probe AuthorizationType='NONE'"]
=========================== short test summary info ============================
FAILED tests/test_cdk_route_authorizer.py::test_every_http_route_has_authorizer_except_get_health
============================== 1 failed in 1.76s ===============================

After removing that route, the same test passed (1 passed in 1.70s).

make check on the real stack exited 0. Lint, typecheck, and pytest:

ruff check lambda tests cdk
All checks passed!
mypy
tests/test_cdk_cors_ban.py:17: note: By default the bodies of untyped functions are not checked, consider using --check-untyped-defs  [annotation-unchecked]
Success: no issues found in 5 source files
PYTHONPATH=. pytest tests/ -v
============================= test session starts ==============================
platform linux -- Python 3.12.3, pytest-9.1.1, pluggy-1.7.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /workspace
configfile: pyproject.toml
plugins: typeguard-2.13.3
collecting ... collected 9 items

tests/test_cdk_cors_ban.py::test_cdk_no_cors_allow_origins_star PASSED   [ 11%]
tests/test_cdk_route_authorizer.py::test_every_http_route_has_authorizer_except_get_health PASSED [ 22%]
tests/test_exclusao.py::test_put_creates_latest_and_history PASSED       [ 33%]
tests/test_exclusao.py::test_get_latest_missing PASSED                   [ 44%]
tests/test_exclusao.py::test_confirm_payment_updates_latest_and_history PASSED [ 55%]
tests/test_exclusao.py::test_confirm_payment_wrong_request_fails PASSED  [ 66%]
tests/test_http_contract.py::test_get_health_returns_200_healthy PASSED  [ 77%]
tests/test_http_contract.py::test_solicitar_missing_cliente_id_returns_400 PASSED [ 88%]
tests/test_http_contract.py::test_happy_path_request_status_confirm PASSED [100%]

============================== 9 passed in 2.68s ===============================
npx --yes aws-cdk@2 synth

Route lines from that synth:

AuthorizationType: JWT
RouteKey: POST /solicitar-exclusao-cliente
AuthorizationType: JWT
RouteKey: GET /status-exclusao/{cliente_id}
AuthorizationType: JWT
RouteKey: POST /confirmar-pagamento
AuthorizationType: NONE
RouteKey: GET /health

The synth stdout continues with the CloudFormation template and ends with 83 feature flags are not configured. Run 'cdk flags --unstable=flags' to learn more. Exit code 0.

Principles

Encode lessons in structure. The CAB follow-up on PR #21 said the authorizer rule should become a synth test. That became tests/test_cdk_route_authorizer.py. The ADR paragraph is unchanged.

Prove it works. The test went red on a temporary route with AuthorizationType='NONE', then green on the real stack. make check was run after the probe route was gone.

Test behavior, not implementation. The assertion reads the synthesized route key and authorization fields that API Gateway enforces. Renaming the Python authorizer variable leaves the test green. A route that synthesizes as NONE turns it red.

Laziness protocol. The diff is the test plus the CI packages that test needs.

Open in Web Open in Cursor 

Note

Low Risk
Test-only and CI dependency changes; no runtime or infrastructure code modified, but future unauthenticated routes will be blocked at merge time.

Reviewed by Cursor Bugbot for commit 91908b8. Bugbot is set up for automated code reviews on this repo. Configure here.

Synthesize ExclusaoClienteStack and reject any HttpApi route with no
authorizer, except GET /health. Install the CDK library in the CI test
job so the gate runs there.

Co-authored-by: Rodrigo Patote <patote85@users.noreply.github.com>
@patote85

Copy link
Copy Markdown
Owner Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 91908b8. Configure here.

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