Saphan StudioDocs
Security

Identity and PKI

Which keys exist, who holds each, what each may sign, and how a signature is checked.

Cryptographic inventory

purposemechanism
Owner root identity, delegations, governance log, standing rulesEd25519
A person's approvals (orders, owner acts, sign-in)passkeys (WebAuthn, P-256)
Owner presence through the gatewaya passphrase-sealed owner key
Per-run seat keysshort-lived Ed25519 keys whose private half never leaves the process that runs the agent
Intermediate CA and machine certificatesX.509, ECDSA P-256 with SHA-256
Record and capture integrity within a workspaceHMAC-SHA-256, 32-byte key
Content identity (artifacts, rule documents, transfers)SHA-256
Key identifiersSHA-256 over a domain-separation label and the public key, truncated to 12 bytes, hex-encoded, with a class prefix
Management interfaceSaphan Studio's own OAuth authorization server; outside OpenID Connect issuers are trusted only from a list, signing with RS256 or ES256

The accepted algorithm set is closed, and the algorithm name is part of the signed material — so a signature produced under one algorithm cannot be reinterpreted under another. On the instruction path Ed25519 is pinned and an HMAC envelope is refused before any key material is touched: a local process holding the shared workspace HMAC key can sign records, but cannot mint a standing rule or an instruction. An unknown version is refused, never guessed.

The trust root is born on paper

The owner root is an Ed25519 key pair created in a ceremony (saphan ceremony root), whose purpose is to produce a root whose private half exists only on paper.

  1. The engine generates the key pair with the platform's secure random generator.
  2. It renders the private half as a numbered word list over a 2,048-word dictionary built into the binary, eleven bits per word. No printer driver, no external tool, no clipboard, no shell-out to any cryptographic utility.
  3. It requires proof of capture: a witness reads the words back from the paper and the engine compares them position by position.
  4. Only on an exact match does it erase the private key and the word list from disk. The public key stays, as proof that a root exists.

A mismatch erases nothing and refuses by name, reporting word counts and positions only, never a word value — so the failure message is safe to paste into a ticket. A read-back pointed at the engine's own word-list file is refused.

Root creation refuses to overwrite an existing root, because re-minting would silently invalidate every earlier signature. If the machine is lost, saphan ceremony root --restore rebuilds the root from the paper words on a new machine, checked against the expected key fingerprint.

The ceremony also creates a narrower identity-signing key, granted by the root and kept on disk, which signs machine admissions from then on, so the root itself never needs to come back.

⚠ After the ceremony, compromising the control machine does not compromise the root, because the root is not on it. It does expose the identity-signing key, which can sign identity records until you revoke it. That grant has no expiry.

Intermediate authority

The intermediate CA issues the short-lived leaf certificates machines use. It is a P-256 key with its own self-signed certificate (saphan ceremony intermediate, valid 365 days by default); it is not signed by the root.

⚠ Today the intermediate key is a software file readable only by its owner. Hardware custody — an HSM or a secure enclave — is not available in this release.

Actors and delegation

An actor is a named identity in an append-only registry with a status. A delegation is a grant naming the delegate, their key identifier, the scope and the validity window. The signature covers every field, so a grant cannot be widened after signing.

  • The scope list is closed: four scopes — order signing, identity signing, seat issuing and owner presence — each allowing exactly one kind of signature. Any other scope is refused; nothing fails open into general authority.
  • Order-signing grants carry a not-before and an expiry; the ceremony's identity-signing grant has no expiry. An expiry is a ceiling, never a trigger: nothing gains permission through the passage of time.
  • Only the root ratifies standing rules and grants delegate keys. A person's signed order can also authorise one dispatching key to place the follow-up orders it lists, within a budget and a time window; this never covers merges, admissions or trust acts.
  • Actor status is checked independently of the grant, so a retired actor is refused even with a valid signature and an unexpired grant.
  • The owner can revoke an actor, a delegated key, an identity provider or a person's sign-in. Each revocation is a signed record, and verifiers refuse revoked keys. See Documented limits for what revocation does not cover.

Standing rules and orders

Ratifying rules produces a root-signed manifest listing each document with its SHA-256, carrying a signed serial number that rises with each ratification. Given a document the engine walks the chain: these bytes hash to this ratified entry, in this manifest, signed by this root. ⚠ Automatic refusal of an older manifest is not implemented yet.

Every order a run receives must carry a person's passkey approval: it binds the exact order text, is single-use, and is valid for four hours by default (24 hours at most). Checking an order's signature chain back to the root is a separate setting, trust.enforce (off, warn, enforce); only enforce refuses an order that fails it, and off — the default — admits it and records the fact.

Verification is structural: internally, "this document was verified" is a value that can only be built by walking the chain, so an unverified document cannot be mistaken for a verified one downstream.

Private key handling

controldetail
PermissionsOwner read/write only. Any group or other permission bit is a refusal.
Check orderThe path is inspected without following symbolic links → it must be a regular file → permission mask → exact key length → only then is the value read.
Machine keysGenerated on the machine that will use them; the certificate request is signed there, so no key material leaves it.
TransmissionNothing in the system transmits a private key. SSH identities are recorded as paths, never values.
In memoryThe workspace secret and seat keys render as fingerprints, so ordinary logging cannot leak them.

On this page