Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

How secrets are kept

A secret is only safe where nothing hostile runs beside it. So the secrets live in one place, the keep, which never opens the content of a job and never runs a capability. The core, which does handle jobs, holds no secret: it asks the keep to send a request, and the keep adds the secret on the way out.

The keep is the only part of sandcastle that reads a secret and the only one that reaches the network. sandcastle keep listens on a Unix socket, $XDG_RUNTIME_DIR/sandcastle-keep/keep.sock, in a folder only you can open. The rest of sandcastle sends it a closed envelope that names a destination, and the keep does the rest:

{"destination":"notes","method":"POST","path":"/jobs/claim","headers":{…},"body":{…}}
  • Only GET and POST. The path is added to the destination’s address, and is refused when it holds .., //, \, a scheme, a query or a fragment, written or encoded. A field the envelope does not have, such as a url, is refused.
  • The headers it takes are content-type, accept and anthropic-version. An authentication header is refused: the keep adds the secret itself, as x-api-key for claude and as Authorization: Bearer for a source.
  • It reads the secret for every request. A secret it cannot use stops the request with unusable secret: <name>, and nothing of its content: the claude job is released and the capability rests, or the source is left out until its next round.
  • It connects only to the destination’s name and port (or its internal ip:port), always verifies TLS, and never follows a redirect. It gives back only the status, content-type, retry-after and a body of up to 32 MiB.
  • Its log has one line per envelope: the destination, the method, the path and the status. Never a body or a secret. It ends with 0 on SIGTERM.

The keep reads the configuration when it starts: restart it after changing a destination.

On disk

Each secret is a file of its own in ~/.local/share/sandcastle/secrets/, readable only by you, and the keep reads it again for every request, so a changed secret counts at once. The files are not encrypted: they are guarded by their permissions alone. Encrypting the disk, and keeping the values in a password manager, are yours to do; the threat model says so. Manage secrets says how to set, list and remove them.