A small secret manager for machine identities
Key/value secrets, gap-free access auditing, and path-based authorization. The name contains CI: the primary consumer is a build and deploy pipeline, not a human.
Status: v0.14.0 released and usable end to end,
including the CI-side binary described under Integrate. This page
describes what exists and says so where something does not.
Why it exists
Storing deployment secrets as forge secrets and rendering them into .env files
works, and it cannot answer three questions:
- Who read which secret, and when? There is no access log.
- Can service A's runner reach service B's secrets? Yes, and nothing prevents it.
- Where is the authoritative value? In two places at once — the forge and the host.
ciphr answers all three. It is deliberately small: key/value secrets, an audit trail, and policies. No PKI, no SSH CA, no dynamic secrets. If those are ever needed, OpenBao is the right answer rather than this project.
The design in one screen
- Envelope encryption. A master key wraps a root key; the root key wraps one data encryption key per secret version. One key encrypts exactly one payload, so nonce reuse cannot occur on a value. Path and version are bound as additional authenticated data, so a ciphertext cannot be moved from one path to another.
- Fail-closed auditing. If no audit device accepts the record, the request is refused and no secret is served. Entries form a hash chain, so tampering is detectable rather than merely unlikely. A full audit volume is an outage, not a logging gap — which is intended, and needs monitoring.
- Deny by default. Path-based capabilities with glob matching. Policies come from configuration under version control, not from a write API, so the commit history is itself an audit trail.
- Secrets cannot be logged. Secret-bearing types implement neither
Debug,DisplaynorSerialize, which makes logging one a compile error rather than a code-review question. This is the main reason the implementation language is Rust. - Runner-agnostic access. The API is HTTPS plus a bearer token, so the minimal
client is
curl. No agent, no plugin, no forge integration required — and for a CI job there is a binary that adds the masking a forge does not do. - TLS terminates at the service, not at the reverse proxy. A deviation on purpose: the content of these connections is plaintext secrets, and a compromised container on a shared network is a realistic adversary. The proxy connects over HTTPS with a pinned internal certificate.
- The viewer is a separate container, and read-only. It cannot write a secret, change a policy or issue a token, and the server has no mode that serves it — so asset handling never runs in the process that holds plaintext.
What it is not
A password manager for humans, Bitwarden API compatibility, feature parity with Vault, multi-tenancy, and high availability. Each of those is a recorded decision rather than a gap, and the reasoning for each is in the plan.
The boundary this project does not pretend about
Root on the host reads the master key and process memory. That is a deliberate consequence of choosing unattended startup — an availability decision, not a cryptographic one. The realistic end state is one secret per host, not zero, plus an audit trail, plus rotation, plus a bounded blast radius per token.
And a secret that has left ciphr is the pipeline's problem: the trail records that a runner read a value, never what it did with it afterwards. The security notes say what that means for the code you are about to write.
Where to go next
-
Integrate
The four ways a consumer gets a value — a CI job, a container, an application, plain
curl— with the code for each and the capabilities it needs. -
Security notes
What the integration has to get right: the token, the masking, least privilege, and the three things this design deliberately does not defend.
-
Security layers
The interactive diagram: every ring is a boundary with a gate, every element names the record that decided it, and the two cuts that ignore the rings entirely.
-
Documentation
The threat model, the architecture records, the cryptographic design, and the operational procedures for what is hard to undo.