Skip to content

Backend abuse controls for the public Cloud Run proxy - #1

Merged
eman-cickusic merged 1 commit into
mainfrom
feat/backend-abuse-controls
Jul 16, 2026
Merged

Backend abuse controls for the public Cloud Run proxy#1
eman-cickusic merged 1 commit into
mainfrom
feat/backend-abuse-controls

Conversation

@eman-cickusic

Copy link
Copy Markdown
Owner

What

Lands the backend half of the abuse controls flagged as the remaining production caution after the GCP migration. /analyze and /chat are publicly callable (allUsersroles/run.invoker) and hit paid Vertex AI with no attestation, rate limit, or cost cap.

Changes

  • backend/app_check.py — Firebase App Check (Play Integrity) token verification, enforced on /analyze and /chat. Gated OFF (APP_CHECK_ENABLED=false), so it's a no-op until the app ships tokens and the flag is flipped — safe to deploy now, won't break the currently shipped app. Fails closed if enabled-but-misconfigured.
  • pyjwt[crypto] dependency; Dockerfile copies the new module.
  • backend/tests/test_app_check.py — disabled-passthrough, missing/invalid/valid token, fail-closed, /chat protected, /healthz open. Full suite: 25 passed.
  • Fixed a stale assertion in test_app.py (maxOutputTokens == 700 → the live cap of 4096 since GCP Backend Migration | /chat Endpoint benevolentbandwidth/ultraprocessed#22).
  • documentation/12-backend-abuse-controls.md — exposure, mitigations, why App Check over the alternatives, and the ordered rollout.

Already applied outside this PR (GCP)

  • Cloud Run --max-instances capped 100 → 10 (revision -00004) to bound the Vertex cost/quota blast radius. Reversible.

Not in this PR — needs Play Console + an app release (see doc 12)

  1. Firebase + Play Integrity setup (console).
  2. Android: attach the X-Firebase-AppCheck header (snippet in doc 12).
  3. After the token-sending build has adoption: redeploy with APP_CHECK_ENABLED=true,FIREBASE_PROJECT_NUMBER=894254677159.

⚠️ Enforcement must come after the app ships tokens, or every installed app gets 401.

🤖 Generated with Claude Code

/analyze and /chat are public (allUsers run.invoker) and hit paid Vertex AI
with no attestation, rate limit, or cost cap. This lands the backend half of
the fix without breaking the currently shipped app (which sends no token):

- app_check.py: Firebase App Check (Play Integrity) token verification,
  enforced on /analyze and /chat via a dependency. Gated OFF by default
  (APP_CHECK_ENABLED=false) so it is a no-op until the app sends tokens.
  Fails closed if enabled but misconfigured.
- pyjwt[crypto] added; Dockerfile copies app_check.py.
- tests/test_app_check.py: disabled-passthrough, missing/invalid/valid token,
  fail-closed, /chat protected, /healthz open.
- Fix stale test_app.py assertion (maxOutputTokens 700 -> the live cap).
- documentation/12-backend-abuse-controls.md: exposure, mitigations, and the
  ordered rollout (Firebase/Play setup -> app token header -> flip the flag).

Cloud Run --max-instances also capped 100 -> 10 (applied separately) to bound
the Vertex cost/quota blast radius.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@eman-cickusic
eman-cickusic merged commit e3afba1 into main Jul 16, 2026
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