Files
archy/core
archipelagoandClaude Opus 5 97921d9932 feat(13-02): session-gated model forwarder for /aiui/api/claude and /aiui/api/ollama
Adds core/archipelago/src/api/handler/model_proxy.rs: a Rust-daemon handler
that re-derives session auth from the request's own cookie (does not trust
nginx to have gated it already) before forwarding to Anthropic's Messages
API or local Ollama. Replaces the unauthenticated claude-api-proxy.py
sidecar (port 3142, its own ANTHROPIC_API_KEY copy) that let anyone who
could reach the node's web port spend the owner's API budget
(T-13-08/T-13-09/T-13-11).

- Unauthenticated/invalid-session requests get 401 before any upstream call
- Missing key ledger (data_dir/secrets/claude-api-key) returns 503 with a
  plain-language body, never 500, never the key path
- Inbound authorization/x-api-key/cookie headers are never forwarded
  upstream (T-13-14) — only content-type/accept survive the round trip
- Response streamed through rather than buffered, matching proxy.rs's
  peer-content streaming shape, so token-by-token replies still stream
- No log line at any level references a body or a key (AI-SPEC §7b)
- Wired into api/handler/mod.rs's path dispatch alongside the WebSocket
  auth-gated arms, matching the existing is_authenticated idiom

Tests (model_proxy::tests): claude_without_session_is_401,
ollama_without_session_is_401, claude_with_invalid_session_is_401,
missing_key_is_503_not_500, inbound_authorization_header_is_not_forwarded.

`cargo build --package archipelago` succeeds. `cargo test --package
archipelago model_proxy::` was still compiling (test-binary link step) when
this commit was made — see 13-02-SUMMARY.md for the honest status.

Continues WIP checkpoint 13b576da (reset --soft, recommitted atomically
per task per plan protocol).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 14:41:29 -04:00
..
2026-01-24 22:59:20 +00:00
2026-01-24 22:59:20 +00:00