Part IV · Secrets & Agents · Mechanism 05 · SHIPPED (core) · p. 47–48
Handles, not values
A narrow idea with a wide consequence: the thing doing the work gets the ability to act without ever receiving the value it acts with.
An agent needs to push to a repository. Pushing requires a token. Therefore the agent needs the token. That reasoning is wrong, and finding where it is wrong is the whole design. The agent needs the capability to push. It does not need the value of the token.
The agent needs the capability to push. It does not need the value of the token. Everything here follows from noticing that those are different.
A human who sees a token generally does not write it down. An agent operates in a context window that may be logged, summarized into memory, included in a trace, sent to a model provider, or echoed into a transcript. A secret that enters an agent’s context has entered every downstream system that touches that context. Not maybe — by construction.
Late binding at the execution boundary
- A user or agent requests an action, referring to a secret by a handle — a stable name, never a value.
- SecureGit validates the requested action against the handle’s profile.
- Only then does it resolve the actual value from the backing store.
- The value is injected directly into the child process, HTTP client, or credential callback.
- The value is redacted from all observed output — stdout, stderr, logs, error messages, structured responses.
- A metadata-only audit event is recorded. Never the value.
securegit run --with-secret OPENAI_API_KEY=openai-dev -- npm test
securegit ui
OPENAI_API_KEY_VALUE=... securegit secret set openai-dev --value-env OPENAI_API_KEY_VALUE --yesThe local UI binds loopback only — http://127.0.0.1:7469 — no auth prompt, because it never leaves the machine. Writes never pass through shell history: storing a secret reads the value from an environment variable rather than an argument. Command-line arguments are visible in process listings and durable in shell history.