Secrets is an encrypted, tenant-scoped custody service for credentials that belong to people and to the workloads acting for them. A workload hands Secrets a value; Secrets encrypts it in the application, stores only ciphertext in PostgreSQL, and gives it back only to a workload that is authorized for that exact tenant and action. The person who owns the value can see its metadata, revoke it or delete it, but in this release no one can read a stored value back through a user endpoint.
Status: development, version 0.4.0. The HTTP contract is OpenAPI 3.1.
Services that call external providers on a user's behalf end up holding that user's tokens and keys. Keeping those bytes in each service's own database spreads plaintext, key material and ad-hoc access rules across the platform. Secrets gives them one place with one set of rules:
- Encrypted before storage. Every version of every value gets its own data key, wrapped by a versioned key-encryption key that PostgreSQL never sees.
- Tenant-bound. Every reference names a tenant, a namespace and a key, and the caller's verified tenant must match before storage is touched.
- Least privilege. Workloads are Kubernetes service accounts granted explicit actions; people are verified by an Identity authority and can act only on what they own.
- Custody, not provider logic. OAuth exchange, refresh and upstream revocation stay in the integrating service. Secrets holds bytes, versions, bindings and audit records.
The first consumer is the remote secret-store backend of Connectors.
| Page | What it covers |
|---|---|
| Getting started | Build, create a keyring, migrate a local database |
| Security model | Envelope encryption, associated data, disclosure, revoke and delete, audit |
| Authentication | Workload tokens and grants, user tokens, the action list |
| HTTP API | Every route, its action, body and status codes |
| Rust client | The secrets-client crate for workloads |
| Operations | Configuration, probes, logs, key rotation, backups, image |
| Architecture | Ownership, request path, deployment boundary |
| Known limitations | What the current release does not do, or does differently from what you might expect |
| Roadmap | Planned: named, scoped secrets across several storage backends |
Requirements: Rust 1.97, PostgreSQL 16 or later, and task.
export SECRETS_DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/secrets
cargo run -p secretsctl -- generate-keyring > keyring.json
cargo run -p secrets-app -- migrate --keyring-file keyring.jsonkeyring.json holds a raw encryption key: keep it out of version control. Serving needs a
Kubernetes cluster; see Getting started.
secrets-core: resource model and storage portsecrets-crypto: envelope encryption and versioned keyringsecrets-postgres: migrations and transactional storesecrets-auth: Identity and Kubernetes authority adapterssecrets-http: HTTP API and embedded docssecrets-client: official Rust workload clientsecrets-app: thesecretsservice, migration and rewrap binarysecretsctl: operator helpers
task checktask check runs formatting, tests, clippy, the documentation build, plan validation and a
provenance check. The PostgreSQL lifecycle test runs only when SECRETS_TEST_DATABASE_URL points
at a disposable database.
Apache-2.0.
Secrets documentation · Start · Ecosystem · Impact · Releases