- Spawn standalone LS as dedicated 'antigravity-ls' user via sudo - UID-scoped iptables redirect (port 443 → MITM proxy) via mitm-redirect.sh - Combined CA bundle (system CAs + MITM CA) for Go TLS trust - Transparent TLS interception with chunked response detection - Google SSE parser for streamGenerateContent usage extraction - Timeouts on all MITM operations (TLS handshake, upstream, idle) - Forward response data immediately (no buffering) - Per-model token usage capture (input, output, thinking) - Update docs and known issues to reflect resolved TLS blocker
3.3 KiB
3.3 KiB
Standalone LS for Proxy Isolation
Status: ✅ FULLY IMPLEMENTED (incl. MITM interception)
The standalone LS is fully working via --standalone flag on the proxy.
All cascade types (sync, streaming, multi-turn) and all endpoints work.
MITM interception captures real token usage from Google's API.
Implementation
Module: src/standalone.rs
The proxy spawns a standalone LS as a child process:
- Discovers
extension_server_portandcsrf_tokenfrom the real LS (via/proc/PID/cmdline) - Picks a random free port
- Builds init metadata protobuf (via
proto::build_init_metadata()) - Spawns the LS binary with correct args and env vars
- Feeds init metadata via stdin, then closes it
- Waits for TCP readiness (retry loop)
- Kills the child on proxy shutdown (via
Drop)
UID Isolation (MITM mode)
When scripts/mitm-redirect.sh install has been run:
- The
antigravity-lssystem user exists - iptables redirects that UID's port-443 traffic → MITM proxy port
- The proxy spawns the LS via
sudo -n -u antigravity-ls - Environment variables (
SSL_CERT_FILE, etc.) are passed via/usr/bin/env - A combined CA bundle (system CAs + MITM CA) is written to
/tmp/antigravity-mitm-combined-ca.pem - Only the standalone LS traffic is intercepted — no impact on other software
Usage
# Setup (one-time, requires sudo)
sudo ./scripts/mitm-redirect.sh install
# Run
RUST_LOG=info ./target/release/antigravity-proxy --standalone
# Check intercepted usage
curl -s http://localhost:8741/v1/usage | jq .
Root Cause of Original Failure
The bash script (scripts/standalone-ls.sh) used MODEL_PLACEHOLDER_M3 — an
unassigned/invalid model enum. The LS silently drops cascades with unknown models.
Fix: Use correct model enums (M18=Flash, M26=Opus4.6) via the proxy's byte-exact protobuf encoder.
Key Technical Details
- Init metadata protobuf field 34 =
detect_and_use_proxy(1=ENABLED) - Model IDs: M18=Flash, M8=Pro-High, M7=Pro-Low, M26=Opus4.6, M12=Opus4.5
- LS binary:
/usr/share/antigravity/resources/app/extensions/antigravity/bin/language_server_linux_x64 - API endpoint:
daily-cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse - SSE response format:
{"response": {"usageMetadata": {"promptTokenCount", "candidatesTokenCount", "thoughtsTokenCount"}, "modelVersion": "..."}}
Test Results (2026-02-14)
| Endpoint | Result |
|---|---|
GET /health |
✅ |
GET /v1/models |
✅ 5 models |
GET /v1/sessions |
✅ |
GET /v1/quota |
✅ real plan/credits |
GET /v1/usage |
✅ real MITM tokens |
POST /v1/responses (sync) |
✅ |
POST /v1/responses (stream) |
✅ SSE events |
POST /v1/responses (multi-turn) |
✅ context preserved |
POST /v1/chat/completions |
✅ |
| MITM interception | ✅ TLS decrypt + parse |
| MITM usage capture | ✅ per-model token counts |
| UID isolation | ✅ no side effects |