Extracting Tokens Is a Dead End: A Personal AI Gateway's Compliance Line
An LLM-Bridge postmortem: pulling OAuth tokens out of the CLI to hit the backend directly is the shortest path — and the first to die. Why it all fell back to official harnesses.
To put subscription-tier Claude and Codex behind your own API gateway, there’s one obviously shortest path: find where the CLI stores its OAuth token after login, read it out, and use it to hit the backend’s /v1/messages yourself.
The first version of LLM-Bridge did exactly that. It worked. It was fast, low-latency. Then it died. This post is about why it had to die, and what the project looks like now that it fell back.
The shortest path dies first
The pull-token-and-connect approach is genuinely tempting: skip the subprocess layer, hit the backend over HTTP directly, drop latency from seconds to hundreds of milliseconds, and get the full streaming event feed, token counts, and sampling params. Feature-wise, it’s the most complete solution.
The problem is it violates the vendors’ terms of service, and the vendors started enforcing for real.
Since January 2026, Anthropic added server-side detection — flagging requests that carry a subscription token but didn’t come from an official harness — and fully enforced it by April 2026. At that point, an extracted token sent to the backend gets a flat 403. Not throttled, not warned. Refused.
This kind of blocking only tightens, never loosens. Any scheme that depends on replaying a subscription token has a lifespan capped by the vendor’s next crackdown. Every line of bypass logic you write today is paper glued over a door that’s going to be shut.
Falling back to official harnesses — at what cost
So the project did a convergence: all three backends fell back to their respective official harnesses.
- claude goes through
claude-agent-sdk— the SDK bundles its own CLI and manages the subscription login; - codex goes through a
codex exec --jsonsubprocess; - agy goes through an
agy -p -subprocess.
The gateway itself touches zero tokens. Auth, refresh, billing — all the harness’s job. The gateway only feeds in an OpenAI-format request and converts the output back.
This path has a cost, and not a small one:
- High latency. Through a CLI subprocess, every request starts at 3–8 seconds — an order of magnitude slower than direct;
- Chat only. The CLIs/SDK don’t expose knobs like
temperature,max_tokens, nor a structured channel for tool calling, so the gateway can only be chat-only; - Low concurrency. Only 2 in-flight requests per provider — it’s a personal gateway, not a serving stack;
- claude usage bills against Agent SDK credits — the monthly allotment, not the pool you draw from running
claudeinteractively.
What those costs buy is a shape that won’t get 403’d next quarter. Slower, narrower — but it keeps running. A tool’s first property is “still alive”; everything else ranks below that.
The legal boundary of the word “personal”
Falling back to the harness doesn’t make everything fine — you still have to hold the line on “personal.” LLM-Bridge is positioned as: reuse your own already-paid-for subscription login, for you alone. That draws a few concrete lines:
- Single-user, localhost-first: binds
127.0.0.1by default, no multi-tenancy, stores no one’s credentials; - No token replay: goes through official harnesses, auth stays in the harness, the gateway never handles it;
- No sharing beyond the subscription’s terms: these are personal accounts; turning one into a service for a group of people basically breaks the subscription terms — even if it’s technically doable.
Even to use it across your own devices (--host 0.0.0.0), the README states it flatly: set an API key before opening the listener, or anyone on your subnet burns your quota; and the traffic is plain HTTP, so keep it inside a trusted network and never port-forward to the internet. Compliance isn’t a disclaimer you tack on — it has to land in every default and every reminder in the docs.
Write the line into the code, not into memory
The most likely relapse is: “direct is faster, let me just add it back temporarily.” To leave that thought no foothold, the line is written into the project’s conventions — the exact wording in CLAUDE.md:
Direct backend-API access with extracted CLI tokens was removed in July 2026 — providers ban it and the endpoints return 403. Do not reintroduce it.
There’s also a dedicated provider-adapter review role that lists “no direct-token access” as one of its red lines, to be run over any new provider and any change. An architectural invariant that lives only in the head of the person who wrote it will be changed by the next person — including you, three months later. Written into docs, into the review checklist, into an explicit list of “what not to do” — only then is it actually a constraint.
Takeaways
For a personal AI gateway, the shortest path is pulling tokens for a direct connection, and that path is dead:
- Vendors mean it: Anthropic shipped server-side blocking in January, enforced in April, direct backends return 403 — any token-replay scheme’s lifespan ends there;
- Official harnesses cost, but survive: high latency, chat only, low concurrency, billed to Agent SDK credits — in exchange for not being switched off by the next crackdown;
- Hold the line on “personal”: single-user, local, no replay, no external sharing — compliance landing in defaults and docs;
- Write the line into the code: invariants into
CLAUDE.mdand the review checklist, not into memory.
In one line: any compliance you can bypass, the vendor will eventually make un-bypassable; walking in the front door from the start is the only choice that keeps running.
Comments