Start here · 3 of 3
Status
Every capability below carries its status; the landing page's status strip reads the same file, so the two cannot disagree.
Secrets 0.6.0 ships the service, its workload client, the named-storage library over the OS
keychain and this service, and secretsctl, the local CLI. Shipped means in a release and held by task check; planned
means specified and on the plan only.
| Capability | Status | Detail |
|---|---|---|
| Service | ||
| Workload routes: put, get, exists, list, delete | Shipped | Behind Kubernetes TokenReview and a local grant file; one action per route. |
| User routes: list, detail, revoke, delete | Shipped | Behind Identity; metadata only, and only for secrets the caller owns. |
| Prepared batches | Shipped | Prepare, commit and abort; sealed like a value, applied in one transaction, expiring after 600 seconds. |
| Stable refusal codes | Shipped | Every refusal is {"error", "code"} and echoes no part of the request. |
| Security | ||
| Envelope encryption with associated data | Shipped | AES-256-GCM per version, a versioned keyring mounted read-only, and key rotation with secrets rewrap. |
| Audit events for every change | Shipped | Written in the same transaction; no API reads them, and some actors are caller-chosen. |
| Rewrap of every stored version | Shipped | secrets rewrap re-encrypts every stored version under another key, current or older. |
| Verified principal as every audit actor | Planned | — |
| Clients | ||
| Rust workload client | Shipped | secrets-client covers every workload route. |
| Specification | ||
| ESS specification and conformance suite | Shipped | secrets.custody retrofitted from the code and secrets.storage; 111, 110 and 89 scenarios run against the service, the library and the secretsctl binary on every check, every one answered. |
| Library | ||
| Named, scoped secrets over several backends | Shipped | The secrets.storage library: OS keychain and this service behind one interface, one backend per namespace, the local authorizer first; the value a read returns is asserted by the conformance suite on both backends. |
| Read-only 1Password backend | Planned | — |
| Local CLI that never prints a secret | Shipped | secretsctl put, read --out, describe, list, delete, rename, namespace, mount set, bind and unbind in the local scope; --tenant and --user other than default are denied; a value only from a hidden prompt, a pipe or a mode-0600 file, and back only into a new mode-0600 file. |
As of 2026-10-05 · Secrets' status record, maintained in the repository and checked against main
Known limitations
These describe 0.6.0 as it is.
Audit actors can be caller-chosen
POST /v1/workload/secrets:deleterecords the body'sactorwhen one is given.- A prepared batch records the prepare request's
actoron every event its commit writes. PUT /v1/workload/secretsrecords theowner_subjectthe workload sets.
Treat those actors as claims of an authorized workload, not verified identities. A fix is planned.
Other gaps
- No user route returns a value, whatever the disclosure; workload reads ignore disclosure.
- Serving requires Kubernetes: there is no local or development authority.
- Delete is not cryptographic erasure; backups stay decryptable with the keyring.
- Grant and keyring changes need a restart, and a workload subject acts in one tenant.
- Audit events cannot be read through the API;
/metricsexposes onlysecrets_up.
Named secrets over several backends
An in-process Rust library for named secrets such as openai or team/openai, with several
backends behind one interface. It is the secrets.storage domain of the
specification, and its conformance suite runs on every check.
- Scope. Each secret belongs to one tenant, namespace and user, and is unique by scope and
name. Names are
/-separated segments ofa-z0-9._-, at most 128 bytes and 64 per segment. Values are at most 1 MiB, or what the backend accepts. - Backends. Each namespace is mounted on exactly one backend, with no fallback between them.
The OS keychain and this service read, write, delete and list. This service as a backend maps a
name to
{tenant, namespace, key = "<user>/<name>"}with the user as owner, and holds values up to about 768 KiB. - Operations. Add, remove and re-mount a namespace; bind and unbind a name; write, read,
delete, rename; list metadata, never a value. The local authorizer allows tenant and user
defaultand denies every other before any backend call. Errors are closed codes:not-found,denied,unsupported,unavailable,invalid-name,too-large,conflict. - Local CLI.
secretsctlruns these operations on this machine and never prints a value; it hands one over only as a new mode-0600 file (read --out). See Getting started.
Planned: named secrets over several backends
Nothing in this section is built; names and limits may change before it ships.
- 1Password. A read-only backend; a name is bound to a locator such as
op://<vault>/<item>/<field>before it is read. - Also planned. The verified principal on every audit event.
- Not planned. HashiCorp Vault as a backend, namespace-wide secrets without an owner, and an external authorization service.
Build from source
git clone https://github.com/beyond10x/secrets.git
cd secrets
task check
See Getting started for the tools and the database task check needs.