4.5 KiB
Status: written by Sage, lead. It follows docs/plans/BRIEF-TEMPLATE.md.
It answers Vikunja P19 #237. Jason confirmed it through Mos as "Q127:
yes" (sage-0110). Role sessions talk only to a local proxy, CLIProxyAPI
first, with keys the stack issues and rotates. The upstream tokens and
keys stay in the proxy, which is set once for the whole machine, and
nobody hand-edits a credential file. Decision 114's hold on session
traffic through CLIProxyAPI is lifted for #237 (lead decision 120). This
row is the test that comes before any design: it runs after rows 92 and
93, the redeploy and Jason's re-test.
A local model proxy for role sessions (2026-10-12)
Stand-in-key test of CLIProxyAPI for role sessions
Problem
Every role session logs in with the token in
~/.config/mosaic-dev/secrets/claude-session.env, which Jason made by
hand (decision 119). He wants credentials set by the stack, not by him.
The session allowlist already passes ANTHROPIC_BASE_URL,
ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY
(packages/seat/src/session.mjs:62-64), so a Claude Code session can
point at a gateway without a code change. Pi sessions can't, because no
OpenAI base-URL variable passes. CLIProxyAPI listens on
127.0.0.1:8317 (~/.local/opt/EasyCLIProxyAPI/cpa-core/cli-proxy-api,
running since 2026-10-06). Nobody has checked whether Claude Code or pi
works through it. Nobody has checked whether it can issue a key per
agent without its WebUI either.
Owner and reviewer
- Owner: Researcher.
- Reviewer: Dewey. Sage reruns every script at the gate.
Files owned
agents/researcher/work/i1-proxy-test/: scripts, a stand-in upstream, logs,REPORT.mdand a manifest. Nothing outside it.
What ships
All of this runs against a second CLIProxyAPI process that the test starts from the same binary. It gets its own made-up config, port, data directory and management key under the packet directory. The running proxy on 8317, its config and its data aren't touched, read or called. The upstream is a stand-in HTTP server in the packet. It records every request and answers like the Anthropic Messages API, including streamed answers and tool calls. The stand-in proxy is configured to use it as its Claude upstream. No real token or key exists anywhere in the test, and no request leaves the machine.
- The proxy's version, and the config fields and management endpoints the
test uses, each cited to its own docs or
--helpoutput. - Claude Code (the pinned binary,
MOSAIC_CLAUDE_BIN) and pi (the pinned version) each run one non-interactive turn through the stand-in proxy, using only the session's allowlisted variables. If pi can't, the report names the variable or adapter change it needs. For each, the stand-in upstream's log shows:- a streamed answer arriving intact;
- a tool call and its result making the round trip;
cache_controlblocks and theanthropic-betaandanthropic-versionheaders as the client sent them, or exactly what the proxy dropped or changed;- which client key the proxy saw, and that the upstream saw only the proxy's own made-up upstream key.
- Per-agent keys from the command line: the test creates two client keys through the stand-in proxy's management API or CLI, with no WebUI. A session with key A works. Revoking A refuses A's next request and leaves B working. Each request's key shows up in the proxy's usage or logs. The report says how many steps that takes and whether a restart is needed.
- The proxy's behavior with an unknown key, a missing key, and an upstream that is down. The report gives the error each client prints.
- A cleanup script that stops the stand-in processes and leaves no process, port or file outside the packet. The report says how to run everything again.
REPORT.mdlists what holds, what doesn't, and what the #237 design row has to settle. That includes where the issued keys live, how the bus hands one to a session, and rotation.
Out of scope
Any change to the running proxy, its config or its keys. That goes back to Mos (sage-0110). Reading its management key: no agent does that, ever. Real credentials or spend. Switching a live seat to the proxy, and the subscription-terms question: both go to Jason after this test. The #237 design and build rows. Containerized sessions (I1).
Gate
Dewey approves on the row's issue, naming the packet manifest. Sage reruns every script from the packet and checks that the running proxy's process, port and config modification time are unchanged and that nothing the test created is left behind.