Gemini Quota Enforcement Bypass

Google Antigravity / Cloud Code Assist

Host: daily-cloudcode-pa.googleapis.com

Discovered by: Satyam Pandey

Primary target: gemini-3.1-flash-lite (text responses after quota exhausted, as observed in our tests).
Also tested: gemini-3.1-flash-image (image responses while flash returned 429, as observed in our tests).
Sensitive values redacted as **** / YOUR_ACCESS_TOKEN_HERE. Pure API issue — Curl/Postman enough; no video required.

Interactive Attack Flow

Click Next — short steps, less scrolling. Step 3 = primary claim. Step 4 = also tested on image model.

Setup 429 Primary Image Done
1
2
3
4
5

Ready to walk through the PoC

Same token · flash 429 → lite 200 (primary, as observed) · image also tested

Full technical appendix (headers, all curls, matrix, impact text)

Headers (every call)

Authorization: Bearer YOUR_ACCESS_TOKEN_HERE User-Agent: antigravity/ide/2.1.1 darwin/arm64 Content-Type: application/json X-Goog-Api-Client: google-cloud-sdk vscode_cloudshelleditor/0.1 Client-Metadata: {"ideType":9,"platform":2,"pluginType":2} x-request-source: local
export AG_TOKEN='YOUR_ACCESS_TOKEN_HERE' export AG_PROJECT='****'

Token (macOS)

  1. Open Antigravity, sign in, send a short chat.
  2. Capture HTTPS to daily-cloudcode-pa.googleapis.com (Charles / Proxyman / mitmproxy).
  3. Copy Authorization: Bearer …. Tokens expire (~1h).
  4. Reuse project if present (tests: sage-*****-rvmxc****), else "".

Or use public Antigravity IDE OAuth (loopback) → access_token; local Keychain/App Support may cache refresh tokens (own machine only).

Preconditions

  • Free Google account with Antigravity / Cloud Code Assist
  • Valid Bearer token · can call the host above
  • Shared Gemini quota exhausted before lite/image comparison steps
  • No other-user privileges

Fast path

If flash already 429: Step 2 → Step 3 (primary lite) → optional Step 4 (image). Skip burn.

Postman: POST .../v1internal:generateContent + headers above. Body Step 2 JSON → 429. Change only model to lite → 200. Optional image body → 200 + JPEG.

Step 1 burn (only if quota still remaining)

POST .../fetchAvailableModels then repeat large generateContent until pool ≈ 0.

{ "project": "****", "model": "gemini-3.1-pro-low", "userAgent": "antigravity", "requestType": "agent", "requestId": "agent/11111111-1111-1111-1111-111111111111/1700000000000/22222222-2222-2222-2222-222222222222/1", "request": { "sessionId": "33333333-3333-3333-3333-3333333333331700000000000", "contents": [{ "role": "user", "parts": [{ "text": "Write a long detailed CRM reply. At least 60 lines, numbered. Context: Sharma Traders PO-88421 SKU-A 1200 pcs Indore. Repeat context as needed. Sections: summary, actions, email draft, risks." }] }], "generationConfig": { "maxOutputTokens": 8192, "temperature": 0.4 } } }

Example: after ~38 calls, pool 0.034 → 0.0003.

Model matrix after exhaustion

429 examples: gemini-3-flash, gemini-3.1-pro-high/low, gemini-3.6-flash-*, gemini-pro-agent, …

Still 200 (strong): gemini-3.1-flash-lite, gemini-3.1-flash-image. Also 200 with stubs: gemini-3.5-flash-low / extra-low, gemini-3-flash-agent.

Impact

As observed in our tests: after QUOTA_EXHAUSTED, gemini-3.1-flash-lite still returned real text (primary) and gemini-3.1-flash-image returned real images. Messaging vs behaviour appeared inconsistent; model-serving compute continued in those probes. Not claimed: other-user data, ATO, cross-user priv-esc.