Lead>code
Security architecture

Isolation is a directory,
not a switch.

How Leadcode keeps every client's agents inside that client's accounts — and why the router refuses to launch rather than guess. This page is the architecture, limits included.

//01The boundary problem

An agent acts with whatever credentials it finds.

Several clients, one laptop. A coding agent shells out to gh, gcloud, aws — and acts with whatever credentials are ambient in the environment it inherited.

One commit authored as the wrong identity, one API call billed to the wrong client, and you are writing an incident report instead of code. The boundary between clients has to hold without you thinking about it — especially while an agent is doing the thinking.

//02The architecture project → persona → router → session

Identity is resolved before the shell exists.

Every session launch walks the same path. A project belongs to a persona — the client identity. The persona's account bindings go through the credential router, which sets each provider's own isolation lever. Only then does a PTY exist for anything to run in.

identity resolution — every launch
Project
~/work/nw-billing a folder on disk
Persona — the client identity
Northwind which accounts may act here
Credential router
scrubs ambient credentials · injects the declared bindings · fails closed
Per-provider levers
claude
CLAUDE_CONFIG_DIR
codex
CODEX_HOME
gh
GH_CONFIG_DIR
gcloud
CLOUDSDK_CONFIG
firebase
its own config home
aws
AWS_CONFIG_FILE + credentials file
each points at an app-managed per-account directory — accounts/acc_northwind/claude-code, never ~/.claude
PTY session
the provider's own claude — signed in as exactly one account

Every lever is the provider's own mechanism. Leadcode's job is that it is always set, always per-account, and never falling back.

//03Fail closed

No binding, no launch.

Before every launch, ambient credentials — ANTHROPIC_API_KEY, CLAUDE_CODE_OAUTH_TOKEN, GH_TOKEN, GITHUB_TOKEN and the rest — are scrubbed from the inherited environment, and only the declared binding is injected.

A missing or unhealthy binding refuses to launch. There is no fallback to whatever the shell had, because the router already removed it. Refusing is a feature: the wrong identity doing the work looks like success until the invoice arrives.

Ambient credentials scrubbed
ANTHROPIC_API_KEY CLAUDE_CODE_OAUTH_TOKEN GH_TOKEN GITHUB_TOKEN
Declared binding injected
CLAUDE_CONFIG_DIR →
accounts/acc_northwind/claude-code
no binding → no launch. Never a fallback to your shell.
//04The obvious question export CLAUDE_CONFIG_DIR=…

Why not just export CLAUDE_CONFIG_DIR?

You can — it is the right first instinct, and it is the same lever Leadcode uses. The honest answer to why that is not enough has three parts.

01The Keychain moved under you

On macOS, Claude Code does not keep its OAuth credential in the config dir — it keeps it in the Keychain. Current versions namespace that entry per config dir: the service name is "Claude Code-credentials-" plus the first 8 hex characters of the SHA-256 of the config dir path. We verified this against Claude Code 2.1.238 on macOS.

Earlier versions shared one un-namespaced entry across every config dir — two "isolated" accounts silently overwriting each other's login. That is exactly how "just export the variable" earned its bad reputation.

macOS Keychain · service names
Claude Code 2.1.238
"Claude Code-credentials-" + sha256(config dir)[0..8]
✓ one entry per config dir — accounts stay apart
earlier versions
one shared entry — no per-dir suffix
✗ the last login wins, for every config dir
02Hand-rolled exports fail open

The variable was never the hard part. The failure mode is: a forgotten export, a new terminal, an agent-spawned subshell — and the CLI silently falls back to your ambient login. It still works, which is the problem. The wrong identity does the work and nothing looks wrong.

Leadcode's router fails closed and scrubs the ambient credentials first, so there is nothing to fall back to. The forgotten-export case becomes a refused launch, not a quiet mistake.

hand-rolled — fails open
# new terminal — export forgotten
claude
✗ still works — as your ambient login
Leadcode — fails closed
# ambient credentials already scrubbed
binding missing → launch refused
nothing to fall back to
03One variable is one provider

CLAUDE_CONFIG_DIR isolates Claude Code. A real client boundary is Claude Code + Codex + gh + gcloud + Firebase + AWS at once — six levers that all have to point at the same client, stay healthy, get validated before launch, and leave an audit trail.

That is the part you would end up building. It is the part the app is.

claude codex gh gcloud firebase aws
all bound to one persona · kept healthy · validated before launch · auditable afterwards
//05Secrets

Your keys never touch the database.

API keys live in the macOS Keychain, and only there. The local SQLite registry stores an opaque reference — a name to look the secret up by, never the value.

And there is no server. Leadcode is a local-only app: no proxy in front of your providers, no cloud copy of your workspaces, nowhere to send a secret even by mistake.

//06Proof

Provable, not promised.

"Prove this identity" shows you exactly what a session gets: the resolved command, the config home, the injected variables, the scrubbed credentials. Not a summary — the actual resolution.

The secret-leak audit goes further: it pulls every stored credential from the Keychain and searches the database and every session log for those exact bytes. Not patterns — the bytes.

prove this identity · Northwind
commandclaude
config homeaccounts/acc_northwind/claude-code
injectedCLAUDE_CONFIG_DIR
scrubbedANTHROPIC_API_KEY · CLAUDE_CODE_OAUTH_TOKEN · GH_TOKEN · GITHUB_TOKEN
secret-leak audit
every stored credential ← Keychain
searched: database file · every session log
those exact bytes — found nowhere
//07Honest limits

What this is not.

This is process isolation — per-account config homes plus a scrubbed environment — not containers. A determined process can still read your home directory. An OS-level sandbox boundary is the next step, not a shipped one.

And Leadcode is macOS only today. The Keychain and PTY integration are the platform-specific parts.

Verified against Claude Code 2.1.238 · gcloud 554.0.0 · firebase-tools 15.22.4 · aws-cli 2.27.48

Watch it fail closed on your own laptop.

Download for macOS

macOS 13+ · no cloud service · secrets stay in your Keychain