Repository navigation
Conversation
Access only guards traffic that goes through Cloudflare, so staging's run.app URL skipped it. When ENV=staging, every request must now carry a valid Cf-Access-Jwt-Assertion for the configured Access application, and the service refuses to start without CF_ACCESS_TEAM_DOMAIN and CF_ACCESS_AUD.
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
Staging sits behind Cloudflare Access, but Access only guards traffic that goes through Cloudflare. The service still answered directly on its
run.appURL (and on Google's frontend for the mapped domain), and those routes skip Access. Staging holds a copy of prod's hacker data, so that bypass matters.When
ENV=staging, the app now checks for itself that every request came through Access:Cf-Access-Jwt-Assertion, the JWT that Access adds to each request it lets through to the origin.audmatches the Access application,issmatches the team, and it hasn't expired./v1/*and SuperTokens'/auth/*. The middleware runs ahead of everything else.CF_ACCESS_TEAM_DOMAINandCF_ACCESS_AUD.https://<team>/cdn-cgi/access/certs, refreshed hourly, and refetched when an unknown key ID appears, since Cloudflare rotates them.ENV=staging.Changes
cmd/api/cf_access.go: config, key fetching, token verification, middleware.cmd/api/api.go: mounts the middleware first when enabled.cmd/api/main.go: reads the two env vars, and on staging requires them and fetches the keys.go.mod:golang-jwt/jwt/v5andMicahParks/keyfunc/v2become direct dependencies. Both were already in the module graph via SuperTokens..env.example: documents the two vars.cmd/api/cf_access_test.go: covers a valid token, plus rejection of missing, wrong-key, wrong-aud, wrong-iss, expired, no-expand unsigned tokens. Also covers the middleware enforced versus off, and team-domain normalization.Deploy notes
Set these on
harp-stagingbefore merging:CF_ACCESS_TEAM_DOMAIN=acmutd.cloudflareaccess.comCF_ACCESS_AUD=<Application Audience (AUD) Tag of the HARP Staging Access app>Without them, the staging revision built from this merge fails to start. Cloud Run keeps serving the previous revision, so staging stays up but doesn't update.
No migrations. Prod (
ENV=prod) doesn't read these vars.🤖 Generated with Claude Code