Files
zerogravity/docs/standalone-ls-todo.md
Nikketryhard d4de436856 feat: MITM interception for standalone LS with UID isolation
- 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
2026-02-14 17:50:12 -06:00

79 lines
3.3 KiB
Markdown

# 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:
1. Discovers `extension_server_port` and `csrf_token` from the real LS (via `/proc/PID/cmdline`)
2. Picks a random free port
3. Builds init metadata protobuf (via `proto::build_init_metadata()`)
4. Spawns the LS binary with correct args and env vars
5. Feeds init metadata via stdin, then closes it
6. Waits for TCP readiness (retry loop)
7. Kills the child on proxy shutdown (via `Drop`)
### UID Isolation (MITM mode)
When `scripts/mitm-redirect.sh install` has been run:
1. The `antigravity-ls` system user exists
2. iptables redirects that UID's port-443 traffic → MITM proxy port
3. The proxy spawns the LS via `sudo -n -u antigravity-ls`
4. Environment variables (`SSL_CERT_FILE`, etc.) are passed via `/usr/bin/env`
5. A combined CA bundle (system CAs + MITM CA) is written to `/tmp/antigravity-mitm-combined-ca.pem`
6. Only the standalone LS traffic is intercepted — no impact on other software
## Usage
```bash
# 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 |