Wire gateway-auth secret and M2M token into integ tests#461
Open
Wire gateway-auth secret and M2M token into integ tests#461
Conversation
Unsticks the deploy pipeline that has been stuck since #458 merged: the auth dependency was landed without attaching a Modal secret to the gateway function or teaching the beta integ tests to mint a bearer token, so every push to main has failed beta tests and skipped the prod deploy. Gateway side: attach modal.Secret.from_name("gateway-auth") to the asgi_app so GATEWAY_AUTH_ISSUER and GATEWAY_AUTH_AUDIENCE are present in the container at request time. The same secret also holds CLIENT_ID/CLIENT_SECRET so rotating the Auth0 M2M app updates every consumer in one place. Deploy side: modal-sync-secrets.sh now upserts the gateway-auth secret from the four GATEWAY_AUTH_* GitHub Actions secrets, and the reusable workflow plumbs them through so both beta (staging) and prod (main) Modal environments stay in sync on every deploy. Integ tests: modal-run-integ-tests.sh fetches a client_credentials token from Auth0 up front and exports simulation_integ_test_access_token so the existing conftest fixture swaps in AuthenticatedClient. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merged
4 tasks
Fixes from subagent review of PR #461: - Startup guard for misconfig: enforce_auth_configured_guard() crashes the ASGI factory at boot when auth is enabled but GATEWAY_AUTH_ISSUER or GATEWAY_AUTH_AUDIENCE is missing from the container environment. Previously this surfaced only as 503 per request, which meant a gateway-auth Modal secret attach failure would silently ship and look green in deploy logs. - Issuer trailing-slash normalisation: _get_decoder() appends "/" if missing so Auth0's iss claim and JWKS URL construction line up even when operators store the GH secret without the slash. Sync script now also normalises before writing the Modal secret. - Authenticated smoke test that runs in both beta and prod: new tests/simulation/test_auth_smoke.py hits GET /jobs/<unknown> with and without a bearer token and asserts 403/401 vs 404. Previously the prod integ run only exercised /ping (ungated), so a bad gateway-auth secret in main would not be caught. The smoke test skips automatically when no access token is configured (dev). - Token-mint JSON safety: modal-run-integ-tests.sh now builds the Auth0 request body with Python so any quote/backslash/newline in the client secret is encoded correctly. Also switched curl to --fail-with-body so Auth0's error message reaches CI logs, and improved the access-token extractor to print the full response on missing-token. - Sync script fails loud: modal-sync-secrets.sh upserts gateway-auth only when all four vars are present; errors on partial config; drops the `|| true` that was silently hiding modal-cli failures. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Unsticks the Modal deploy pipeline that has been frozen since #458 merged: the
require_authdependency was landed without attaching a Modal secret to the gateway function or teaching the beta integ tests to mint a bearer token. Every push tomainsince then has failed beta integ tests and skipped the prod deploy (#460 is also stuck behind this).Auth0 tenant + M2M client +
gateway-authModal secret were set up by Anthony tonight; this PR is the code side.Changes
Gateway container —
projects/policyengine-api-simulation/src/modal/gateway/app.pymodal.Secret.from_name("gateway-auth")to theweb_appfunction soGATEWAY_AUTH_ISSUER/GATEWAY_AUTH_AUDIENCEare present at request time for_get_decoder().CLIENT_ID/CLIENT_SECRETride along in the same secret so rotating the Auth0 M2M app updates every consumer from one place.Deploy sync —
.github/scripts/modal-sync-secrets.sh,.github/workflows/modal-deploy.reusable.ymlmodal-sync-secrets.shnow upserts thegateway-authsecret from the fourGATEWAY_AUTH_*org-wide GH Actions secrets on every deploy, so beta (staging) and prod (main) Modal environments stay in sync and future rotations only need a GH secret update.Integ tests —
.github/scripts/modal-run-integ-tests.sh,.github/workflows/modal-deploy.reusable.ymlclient_credentialsaccess token and export it assimulation_integ_test_access_token. The existing conftest fixture already swaps toAuthenticatedClientwhen that env var is set, so the test client sendsAuthorization: Beareron every gateway call.Test plan
Sync Modal secrets from GitHubincludesgateway-auth)test_calculate_*andtest_pingall greenbeta_only)#460deploy can now ride the pipeline tooNotes
The
policyengine-api(v1) side — fetching a token and attachingAuthorization: Beareron every outbound sim-gateway call — is tracked separately; that PR will be opened after this one lands so the prod gateway actually has auth available before v1 starts sending tokens.🤖 Generated with Claude Code