Skip to content

Wire gateway-auth secret and M2M token into integ tests#461

Open
MaxGhenis wants to merge 2 commits intomainfrom
wire-gateway-auth-secret
Open

Wire gateway-auth secret and M2M token into integ tests#461
MaxGhenis wants to merge 2 commits intomainfrom
wire-gateway-auth-secret

Conversation

@MaxGhenis
Copy link
Copy Markdown
Contributor

Summary

Unsticks the Modal deploy pipeline that has been frozen since #458 merged: the require_auth dependency was landed without attaching a Modal secret to the gateway function or teaching the beta integ tests to mint a bearer token. Every push to main since then has failed beta integ tests and skipped the prod deploy (#460 is also stuck behind this).

Auth0 tenant + M2M client + gateway-auth Modal secret were set up by Anthony tonight; this PR is the code side.

Changes

Gateway containerprojects/policyengine-api-simulation/src/modal/gateway/app.py

  • Attach modal.Secret.from_name("gateway-auth") to the web_app function so GATEWAY_AUTH_ISSUER / GATEWAY_AUTH_AUDIENCE are present at request time for _get_decoder(). CLIENT_ID / CLIENT_SECRET ride 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.yml

  • modal-sync-secrets.sh now upserts the gateway-auth secret from the four GATEWAY_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.yml

  • Before pytest, fetch an Auth0 client_credentials access token and export it as simulation_integ_test_access_token. The existing conftest fixture already swaps to AuthenticatedClient when that env var is set, so the test client sends Authorization: Bearer on every gateway call.

Test plan

  • Beta deploy step succeeds (Sync Modal secrets from GitHub includes gateway-auth)
  • Beta integ tests pass: token mint succeeds, test_calculate_* and test_ping all green
  • Prod deploy step proceeds (no longer skipped)
  • Prod integ tests pass (subset excluding beta_only)
  • #460 deploy can now ride the pipeline too

Notes

The policyengine-api (v1) side — fetching a token and attaching Authorization: Bearer on 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

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

1 participant