Four layers of isolation. Each layer is sufficient on its own. Together, they make leakage structurally impossible.This page is the proof, not just the claim. AI tools running on this workstation cannot read the values behind the locked keychain, cannot obtain a GitHub write credential without taking a visible lease, and cannot read the file paths where keys live at rest.
Layer 1 — nothing is stored, so there is nothing to steal
There is no GitHub token at rest on the workstation. Every GitHub credential is an ephemeral GitHub App installation token minted at the moment of use and discarded with the process that asked for it.git never holds one of its own: a credential helper answers each request, mints a token scoped to that request, hands it to git, and forgets it.
The chain starts at a command that needs a credential and ends with nothing persisted. A stolen shell history, a leaked environment dump, or a recovered disk image yields no usable GitHub credential, because none was ever written.
Layer 2 — three credential tiers, and only one is ambient
The credential an agent can obtain without ceremony is deliberately the least useful one. Escalation is not a matter of reading a different secret; it is a different minting path with a different gate.
This is a stronger boundary than “which secret can you read.” A read credential cannot be widened into a write credential, because the write tier mints from a different endpoint under a policy that pins the repository parameter server-side. An agent that claims write on one repository still cannot touch a second one with that token. And the admin tier has no non-interactive path at all — there is nothing for an agent to read, unlock, or guess.
The lease is the visibility mechanism: a write claim is recorded, exclusive, and self-expiring, so two agents cannot silently both hold write on one repository. See GitHub access for the full model.
Layer 3 — the keychain split for what remains
Secrets that no engine mints still live in two separate macOS keychain databases. The detail is in macOS Keychain; the boundary that matters here is:
An AI subprocess cannot satisfy the unlock prompt, which is the whole point of the second database.
Layer 4 — explicit allow / deny lists in Claude Code
The Claude Code permission system bakes a deny list into the build. Even if the previous layers were bypassed, the harness refuses the file paths that would yield secret material.
The allow list lets the AI inspect metadata — “does a keychain entry with this service name exist?” — without ever returning the value.
Layer 5 — passwordless sudo, but only for darwin-rebuild
The nix-darwin configuration grants passwordless sudo exclusively for two paths: /run/current-system/sw/bin/darwin-rebuild and /nix/var/nix/profiles/system/activate. Both are declarative — they apply Nix store paths already built. No ad-hoc shell, no read access to anything else.
The launcher banner (verbatim)
Some launchers relaunchclaude under a scoped credential context — an AWS profile, for example. Each prints this to stderr before calling exec claude, so the banner lands in the AI’s tool-output stream and the agent knows what it can and cannot do this session:
What AI can and cannot do
Source files
For the literal Nix and shell sources behind each layer, see:nix-darwin/modules/darwin/scripts/openbao-github-creds.sh— the credential helper and the claim/release lease.nix-darwin/hosts/common/claude-launchers.zsh— the scoped launchers and banner.nix-claude-code/data/permissions/allow.nix— read-onlysecurityallow list.nix-claude-code/data/permissions/deny.nix— file-path deny globs.nix-darwin/modules/darwin/security.nix— sudoers path restriction.
See also
- GitHub access — the three credential tiers in detail.
- macOS Keychain — the two-database split.
- Doppler — for AI-readable CI secrets that should be present.
- BWS — programmatic AI-token bridge that respects the same scoping rules.