Skip to content

Backend abuse controls for the public Cloud Run proxy (App Check, gated off) - #26

Open
eman-cickusic wants to merge 2 commits into
benevolentbandwidth:mainfrom
eman-cickusic:feat/abuse-controls-upstream
Open

Backend abuse controls for the public Cloud Run proxy (App Check, gated off)#26
eman-cickusic wants to merge 2 commits into
benevolentbandwidth:mainfrom
eman-cickusic:feat/abuse-controls-upstream

Conversation

@eman-cickusic

Copy link
Copy Markdown
Contributor

Closes the remaining production caution from the GCP backend migration: /analyze and /chat are publicly callable (allUsersroles/run.invoker) and hit paid Vertex AI with no attestation, rate limit, or cost cap.

This lands the backend half and conforms to the repo's version/decision-log process. It does not change runtime behavior until enforcement is turned on.

Changes

  • backend/app_check.py — Firebase App Check (Play Integrity) token verifier, enforced on /analyze and /chat via a FastAPI dependency. Gated OFF (APP_CHECK_ENABLED=false) — a no-op until the app sends tokens. Fails closed if enabled-but-misconfigured. /healthz and /version stay open.
  • pyjwt[crypto] dependency; Dockerfile copies the module (repo-root build context).
  • backend/tests/test_app_check.py — disabled-passthrough, missing/invalid/valid token, fail-closed, /chat protected, /healthz open. Full suite: 28 passed.
  • documentation/15-backend-abuse-controls.md — exposure, mitigations, why App Check over the alternatives, and the ordered rollout.
  • Process conformance: VERSION_LOG.md 1.0.4, module_versions.json bump, 14-decision-log.md + 13-agent-brief.md updated.

Already applied to prod (outside this PR)

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

⚠️ Rollout order — do NOT flip the flag yet

Setting APP_CHECK_ENABLED=true before an app build that sends tokens has adoption will 401 every installed app. Order (detail in doc 15):

  1. Firebase + Play Integrity setup (console).
  2. Android: attach the X-Firebase-AppCheck header.
  3. After adoption: redeploy with APP_CHECK_ENABLED=true,FIREBASE_PROJECT_NUMBER=894254677159.

This is the App Check / Play Integrity backend groundwork flagged as the pre-broad-rollout caution.

🤖 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. Land the backend half without
breaking the currently shipped app (which sends no token):

- backend/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. /healthz and /version stay open.
- pyjwt[crypto] added; Dockerfile copies app_check.py (repo-root context).
- backend/tests/test_app_check.py: disabled-passthrough, missing/invalid/valid
  token, fail-closed, /chat protected, /healthz open. Full suite 28 passed.
- documentation/15-backend-abuse-controls.md: exposure, mitigations, ordered rollout.
- Conform to repo process: VERSION_LOG 1.0.4, module_versions.json bump,
  decision-log + agent-brief updated.

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>
verifyModuleVersionManifest (the Android build guard) failed on PR benevolentbandwidth#26 because the
backend-proxy bump to 1.0.4 was in module_versions.json + VERSION_LOG but not in
documentation/12-module-versioning.md, which the guard requires to match. Update the
doc table, and bump the documentation module to 1.0.1 for the added abuse-controls doc.

Verified locally: ./gradlew :app:verifyModuleVersionManifest -> BUILD SUCCESSFUL.

Co-Authored-By: Claude Opus 4.8 (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