- 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
79 lines
3.3 KiB
Markdown
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 |
|