# Standalone LS for Proxy Isolation ## Status: ✅ FULLY IMPLEMENTED (incl. headless mode + MITM) Two modes available: - **Normal standalone** (default) — steals config from running Antigravity, optional UID isolation - **Headless** (`--headless`) — fully independent, no running Antigravity required ## Headless Mode Pass `--headless` to the proxy. This: 1. Generates its own CSRF token (random UUID) 2. Passes `-extension_server_port=0` to the LS (disables extension server callbacks) 3. Passes `-standalone=true` to the LS binary (built-in standalone flag) 4. Uses `HTTPS_PROXY` env var for MITM (no iptables/sudo required) 5. No `/proc` scanning, no dependency on running Antigravity ```bash # Headless (no Antigravity needed) RUST_LOG=info ./target/release/antigravity-proxy --headless # With MITM disabled ./target/release/antigravity-proxy --headless --no-mitm ``` ## Normal Standalone Mode The default mode (disable with `--no-standalone`): 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 ## LS Binary Flags (Reference) From `language_server_linux_x64 --help`: | Flag | Default | Description | | ------------------------ | ------- | ------------------------------------- | | `-standalone` | `false` | Whether to run in standalone mode | | `-extension_server_port` | `0` | Extension server port. If 0, not used | | `-csrf_token` | `""` | CSRF token for RPC auth | | `-server_port` | `42100` | Port for LS ↔ extension | | `-enable_lsp` | `false` | Enable LSP protocol | | `-cloud_code_endpoint` | `""` | CCPA API URL | | `-parent_pipe_path` | `""` | Monitors parent process liveness | ## 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` ## Test Results (2026-02-15) | Endpoint | Result | | --------------------------------- | --------------------------- | | `GET /health` | OK | | `GET /v1/models` | OK, 5 models | | `GET /v1/sessions` | OK | | `GET /v1/quota` | OK, real plan/credits | | `GET /v1/usage` | OK, real MITM tokens | | `POST /v1/responses` (sync) | OK | | `POST /v1/responses` (stream) | OK, full SSE event set | | `POST /v1/responses` (multi-turn) | OK, context preserved | | `POST /v1/responses` (tools) | OK, function calls captured | | `POST /v1/responses` (images) | OK, MITM injection | | `POST /v1/chat/completions` | OK | | `POST /v1/gemini` | OK | | `GET/POST /v1/search` | OK, grounding + citations | | MITM interception | OK, TLS decrypt + parse | | MITM request modification | OK, tools/images/params | | MITM usage capture | OK, per-model token counts | | MITM error capture | OK, instant client feedback | | UID isolation | OK, no side effects |