One Go binary with two roles that never share a process. Custody holds the signing keys and signs for the consumers it grants a key. The witness reads the record without writing to it, remembers how much of it has been read and the hash of that, and reports when something it saw is gone. Neither role sits on a request path.
The witness is there to disagree with custody if custody is ever compromised, so the two run as separate processes with separate keys and data directories, and the launcher gives each its own uid (stack-single does).
Keys of three algorithms, each wrapped under AES-256-GCM with a key derived from the root key and bound to its name and id. A private half is never written in the clear, and a record that is moved or edited refuses to start.
A consumer authenticates one way: its own socket, a bearer key compared by digest, or a Kubernetes token. It signs only with the keys its policy grants. A refusal answers a status and nothing else, and the reason goes to the operator's log.
A high-rate signer generates its own key and proves it holds it. Custody certifies the key for a bounded life and publishes it with an overlap, so a verifier that caches the set keeps verifying through a rotation.
The witness records how many bytes of each stream it has read and their SHA-256, and hashes the stream again from byte zero each interval (hourly for a stream over 256 MiB). It keeps no copy, so it can tell that a byte changed, never what it was. A changed byte is reported as a rewrite, a shorter stream as a truncation, and a new chain in the middle as a restart. Its own log is an RFC 9162 tree, and each head is signed with ECDSA P-384 and ML-DSA-65 side by side.
keyryx verify checks a witness log, or streams and their checkpoints, from files alone. An empty directory is reported as measured nothing, never as OK.
Verifiers read the published key sets and never call custody for each request. In stack-single the witness reads the event bus and writes its findings to a volume of its own; by default the binary writes them to keyryx.ndjson on the bus.
go build -o keyryx ./cmd/keyryx && ./keyryx versionNo. It is a process you run beside the stack, with a wrapped key store on disk under a root key that is a file. It has no cloud key management. None is built: a cloud key adapter would be a metered dependency, which is an operator's decision and never a default.
No. Verifiers cache the key sets it publishes and keep verifying when it is down. The synchronous calls are rare by design: an approval being granted, a seal, and the renewal of a delegated key.
No. It reads the record, reports what it finds and countersigns what it sees. Whatever follows from a finding is the operator's decision, and the finding stays in its own log either way.