{"id":49812793,"url":"https://github.com/marcofortina/custodia","last_synced_at":"2026-05-15T20:01:23.956Z","repository":{"id":355135231,"uuid":"1226929734","full_name":"marcofortina/custodia","owner":"marcofortina","description":"Privacy-first encrypted secrets vault with mTLS, client-side crypto, audit integrity, Lite/FULL deployment profiles, and official multi-language SDKs.","archived":false,"fork":false,"pushed_at":"2026-05-10T01:17:32.000Z","size":2354,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-10T03:24:04.751Z","etag":null,"topics":["access-control","audit-trail","client-side-encryption","compliance","credential-management","data-protection","encrypted-secrets","enterprise-security","golang","mtls","mutual-tls","on-prem","password-manager","sdk","secret-sharing","secrets-management","secure-storage","security-tools","self-hosted","vault"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/marcofortina.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/SECURITY_MODEL.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-02T01:46:26.000Z","updated_at":"2026-05-10T01:17:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/marcofortina/custodia","commit_stats":null,"previous_names":["marcofortina/custodia"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/marcofortina/custodia","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcofortina%2Fcustodia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcofortina%2Fcustodia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcofortina%2Fcustodia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcofortina%2Fcustodia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcofortina","download_url":"https://codeload.github.com/marcofortina/custodia/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcofortina%2Fcustodia/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32964522,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-12T23:30:32.555Z","status":"online","status_checked_at":"2026-05-13T02:00:07.132Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["access-control","audit-trail","client-side-encryption","compliance","credential-management","data-protection","encrypted-secrets","enterprise-security","golang","mtls","mutual-tls","on-prem","password-manager","sdk","secret-sharing","secrets-management","secure-storage","security-tools","self-hosted","vault"],"created_at":"2026-05-13T02:15:13.693Z","updated_at":"2026-05-15T20:01:23.929Z","avatar_url":"https://github.com/marcofortina.png","language":"Go","funding_links":["https://paypal.me/marcofortina"],"categories":[],"sub_categories":[],"readme":"# Custodia\n\n[![CI](https://github.com/marcofortina/custodia/actions/workflows/ci.yml/badge.svg)](https://github.com/marcofortina/custodia/actions/workflows/ci.yml)\n[![Release artifacts](https://github.com/marcofortina/custodia/actions/workflows/release.yml/badge.svg)](https://github.com/marcofortina/custodia/actions/workflows/release.yml)\n[![License: AGPL-3.0-only](https://img.shields.io/badge/license-AGPL--3.0--only-blue.svg)](LICENSE)\n[![Wiki](https://img.shields.io/badge/wiki-project%20portal-forestgreen.svg)](https://github.com/marcofortina/custodia/wiki)\n\nCustodia is a REST vault for encrypted secrets. The server authenticates clients with mTLS, authorizes access, stores opaque encrypted blobs and returns only the caller's opaque envelope. Encryption, decryption, private-key handling, key rotation and key trust stay outside the server. Custodia may store authenticated client application public keys and fingerprints as metadata to simplify recipient discovery, but it is not a decryption service or a key-trust oracle.\n\n## Start here\n\nNew to Custodia? Start with the document that matches your task:\n\n| Task | Document | Use it when |\n| --- | --- | --- |\n| Choose deployment target and profile | [`docs/DEPLOYMENT_MATRIX.md`](docs/DEPLOYMENT_MATRIX.md) | You need to decide between bare metal, Kubernetes, Lite and Full. |\n| Browse the documentation index | [`docs/README.md`](docs/README.md) | You want the repository documentation map grouped by task. |\n| Install on bare metal | [`docs/QUICKSTART.md`](docs/QUICKSTART.md) | You want the first package/source install path and Lite bootstrap. |\n| Install Full on bare metal | [`docs/BARE_METAL_FULL_INSTALL.md`](docs/BARE_METAL_FULL_INSTALL.md) | You already have PostgreSQL/CockroachDB, Valkey and signer dependencies. |\n| Install on Kubernetes | [`docs/KUBERNETES_INSTALL.md`](docs/KUBERNETES_INSTALL.md) | You are deploying a Git-built image with the Helm chart. |\n| Prepare Kubernetes Secrets | [`docs/KUBERNETES_BOOTSTRAP_MATERIAL.md`](docs/KUBERNETES_BOOTSTRAP_MATERIAL.md) | You need mTLS, signer and Web MFA material before Helm install. |\n| Sign off a release candidate | [`docs/RELEASE_READINESS_MATRIX.md`](docs/RELEASE_READINESS_MATRIX.md) | You are validating release artifacts and production-readiness gates. |\n| Review stable security/compatibility boundaries | [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md) and [`docs/API_COMPATIBILITY_POLICY.md`](docs/API_COMPATIBILITY_POLICY.md) | You need the 1.0 threat model or compatibility promise. |\n| Publish a release | [`docs/RELEASE_PUBLISHING.md`](docs/RELEASE_PUBLISHING.md) | You need the end-to-end local release flow, tag checks and asset verification. |\n| Smoke-test Kubernetes | [`docs/KUBERNETES_RUNTIME_SMOKE.md`](docs/KUBERNETES_RUNTIME_SMOKE.md) | You need a read-only runtime check against an installed cluster. |\n| Smoke-test Lite backup/restore | [`docs/LITE_BACKUP_RESTORE_SMOKE.md`](docs/LITE_BACKUP_RESTORE_SMOKE.md) | You need disposable SQLite backup/restore validation. |\n| Run the end-to-end operator rehearsal | [`docs/END_TO_END_OPERATOR_SMOKE.md`](docs/END_TO_END_OPERATOR_SMOKE.md) | You are rehearsing server/admin, Alice, Bob and backup flows. |\n| Configure client CA trust | [`docs/CLIENT_TRUSTED_CA.md`](docs/CLIENT_TRUSTED_CA.md) | You want real clients to enroll without `--insecure`. |\n\nIf you are not sure what to choose, use the package install path. It covers Debian/Ubuntu `.deb`, Fedora `.rpm`, the server/client/SDK package split, Lite bootstrap, admin certificate setup, Web TOTP, the first API check and the first encrypted client smoke test.\n\n## What is implemented\n\n- Go vault server with TLS 1.3 / mTLS support and optional client CRL rejection.\n- Client identity extraction from certificate SAN/CN.\n- REST API for encrypted secret create/read/delete/share/new-version plus metadata-only secret listing and authenticated client public-key metadata, with namespace/key lookup for normal user-facing workflows.\n- Admin API/CLI and metadata-only Web Console workflows for client metadata create/list/revoke, enrollment tokens, secret version/access inspection and future access-grant revocation.\n- Pending grant request/activation workflow: admins can request access, but a client with `share` must upload the target envelope.\n- Per-version access grants with `read`, `write`, `share` bitmask and optional future `expires_at`.\n- Configurable recipient-envelope cap for create/new-version requests, defaulting to 100.\n- Future revocation semantics: revoked grants stop future reads; already downloaded material is not invalidated.\n- PostgreSQL-compatible schema contract plus optional `pgx` store implementation behind the `postgres` build tag.\n- In-memory store for local development and tests.\n- Hash-chained audit event model with admin audit listing and verification API/CLI.\n- Memory and Valkey-compatible rate limiter backends with readiness checks.\n- Minimal admin CLI for metadata operations exposed by the API.\n- Go, Python and Node.js / TypeScript client libraries with raw transport helpers; all three include high-level client-side crypto wrappers that keep plaintext, DEKs and private keys outside the server.\n- Java, C++ and Rust client libraries with raw transport helpers plus high-level client-side crypto wrappers that use the shared AES-256-GCM/HPKE-v1 vectors.\n- Go `custodia-client` CLI for encrypted namespace/key put/get/share/update, access revoke/delete workflows, server-published application public-key metadata, reusable JSON client profiles and one-shot enrollment for client-side mTLS CSR signing.\n- Docker, Compose, Helm and Lite/Full deployment examples, with the install/profile split documented in [`docs/DEPLOYMENT_MATRIX.md`](docs/DEPLOYMENT_MATRIX.md), a Full bare-metal runbook, Kubernetes bootstrap material guidance, Kubernetes example values and render guardrails via `make helm-check`, runtime and operational readiness smoke runbooks, and a final sign-off matrix in [`docs/RELEASE_READINESS_MATRIX.md`](docs/RELEASE_READINESS_MATRIX.md), plus a human security hardening review in [`docs/SECURITY_HARDENING_FINAL_REVIEW.md`](docs/SECURITY_HARDENING_FINAL_REVIEW.md).\n- Dedicated `custodia-signer` service for enrollment-backed client CSR signing.\n- Custodia Lite profile with YAML config, SQLite build-tag artifact, local CA bootstrap, backup helper and Lite-to-Full readiness checks.\n\n## What is deliberately not implemented server-side\n\n- No plaintext handling.\n- No DEK/wrapped-DEK handling.\n- No private application-key custody.\n- No server-side DEK unwrap, recipient-envelope generation or application decryption.\n- No server-side public-key trust decision; published public-key metadata is discovery data, not proof that a key should be trusted.\n\n## Community and security\n\n- Contributions are welcome, but they must preserve Custodia's metadata-only security boundary. See [`CONTRIBUTING.md`](CONTRIBUTING.md).\n- All participants are expected to follow the [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md).\n- Do not open public issues for vulnerabilities or sensitive disclosures; follow [`SECURITY.md`](SECURITY.md).\n\n\n## License\n\nCopyright (c) 2026 Marco Fortina.\n\nCustodia is licensed under the **GNU Affero General Public License v3.0 only** (`AGPL-3.0-only`). See [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE).\n\nCustodia is open source, but the AGPL network-copyleft terms are intentional: if you modify Custodia and make that modified version available to users over a network, you must make the corresponding source code available under the AGPL.\n\nCommercial licensing, enterprise support and integration work may be available separately from the maintainer.\n\n## Client SDKs\n\nThe canonical repository-level SDK matrix is [`docs/CLIENT_LIBRARIES.md`](docs/CLIENT_LIBRARIES.md). Use that document as the source of truth for implemented client surfaces and verification status.\n\n- Go: [`docs/GO_CLIENT_SDK.md`](docs/GO_CLIENT_SDK.md)\n- Python: [`docs/PYTHON_CLIENT_SDK.md`](docs/PYTHON_CLIENT_SDK.md)\n- Node.js / TypeScript transport and crypto: [`docs/NODE_CLIENT_SDK.md`](docs/NODE_CLIENT_SDK.md)\n- Java transport and crypto: [`docs/JAVA_CLIENT_SDK.md`](docs/JAVA_CLIENT_SDK.md)\n- C++ transport and crypto: [`docs/CPP_CLIENT_SDK.md`](docs/CPP_CLIENT_SDK.md)\n- Rust transport and crypto: [`docs/RUST_CLIENT_SDK.md`](docs/RUST_CLIENT_SDK.md)\n- Encrypted client CLI: [`docs/CUSTODIA_CLIENT_CLI.md`](docs/CUSTODIA_CLIENT_CLI.md)\n- Alice/Bob first encrypted secret smoke test: [`docs/CUSTODIA_ALICE_BOB_SMOKE.md`](docs/CUSTODIA_ALICE_BOB_SMOKE.md)\n- Kubernetes runtime smoke: [`docs/KUBERNETES_RUNTIME_SMOKE.md`](docs/KUBERNETES_RUNTIME_SMOKE.md) and [`docs/OPERATIONAL_READINESS_SMOKE.md`](docs/OPERATIONAL_READINESS_SMOKE.md)\n- Lite backup/restore smoke: [`docs/LITE_BACKUP_RESTORE_SMOKE.md`](docs/LITE_BACKUP_RESTORE_SMOKE.md)\n- End-to-end operator release-candidate smoke: [`docs/END_TO_END_OPERATOR_SMOKE.md`](docs/END_TO_END_OPERATOR_SMOKE.md)\n- Bash SDK helper: [`docs/BASH_SDK.md`](docs/BASH_SDK.md)\n- Shared crypto contract: [`docs/CLIENT_CRYPTO_SPEC.md`](docs/CLIENT_CRYPTO_SPEC.md)\n- Client crypto threat model: [`docs/CLIENT_CRYPTO_THREAT_MODEL.md`](docs/CLIENT_CRYPTO_THREAT_MODEL.md)\n- Namespace/key secret keyspace model: [`docs/SECRET_KEYSPACE_MODEL.md`](docs/SECRET_KEYSPACE_MODEL.md)\n- SDK examples and compatibility matrix: [`docs/SDK_EXAMPLES_AND_COMPATIBILITY.md`](docs/SDK_EXAMPLES_AND_COMPATIBILITY.md)\n- SDK test vectors: [`docs/SDK_TEST_VECTORS.md`](docs/SDK_TEST_VECTORS.md)\n- SDK release policy: [`docs/SDK_RELEASE_POLICY.md`](docs/SDK_RELEASE_POLICY.md)\n- SDK publishing readiness checklist: [`docs/SDK_PUBLISHING_READINESS.md`](docs/SDK_PUBLISHING_READINESS.md)\n- Threat model: [`docs/THREAT_MODEL.md`](docs/THREAT_MODEL.md)\n- API and compatibility policy: [`docs/API_COMPATIBILITY_POLICY.md`](docs/API_COMPATIBILITY_POLICY.md)\n- Linux DEB/RPM packaging: [`docs/LINUX_PACKAGES.md`](docs/LINUX_PACKAGES.md) including the installed `/usr/sbin/custodia-operational-readiness-smoke` helper\n- Start here / install quickstart: [`docs/QUICKSTART.md`](docs/QUICKSTART.md)\n- Full bare-metal install: [`docs/BARE_METAL_FULL_INSTALL.md`](docs/BARE_METAL_FULL_INSTALL.md)\n- Kubernetes bootstrap material: [`docs/KUBERNETES_BOOTSTRAP_MATERIAL.md`](docs/KUBERNETES_BOOTSTRAP_MATERIAL.md)\n- Release readiness matrix: [`docs/RELEASE_READINESS_MATRIX.md`](docs/RELEASE_READINESS_MATRIX.md)\n- Release publishing runbook: [`docs/RELEASE_PUBLISHING.md`](docs/RELEASE_PUBLISHING.md)\n- Release notes for 1.0.0: [`docs/RELEASE_NOTES_1_0_0.md`](docs/RELEASE_NOTES_1_0_0.md)\n- SBOM artifacts: [`docs/SBOM.md`](docs/SBOM.md)\n\n## Linux packages\n\nBuild local DEB/RPM packages with:\n\n```bash\nVERSION=1.0.0 REVISION=1 make package-deb\nVERSION=1.0.0 REVISION=1 make package-rpm\n```\n\nGenerate release verification files:\n\n```bash\nVERSION=1.0.0 REVISION=1 make package-checksums\ncd dist/packages \u0026\u0026 sha256sum -c SHA256SUMS\n```\n\nAutomate the full local GitHub release flow from checks through tag, package build, draft release creation, asset upload and remote asset verification. See [`docs/RELEASE_PUBLISHING.md`](docs/RELEASE_PUBLISHING.md) for the complete step-by-step publishing runbook, including annotated tag checks and post-download checksum verification:\n\n```bash\nVERSION=1.0.0 REVISION=1 ./scripts/release-publish.sh dry-run\nVERSION=1.0.0 REVISION=1 RELEASE_CONFIRM=YES ./scripts/release-publish.sh draft\n```\n\nSmoke-test package contents without installing them into the host system:\n\n```bash\nmake package-smoke\n```\n\nValidate package installation on a disposable clean VM/container before publishing:\n\n```bash\nmake package-install-smoke\nmake lite-backup-restore-smoke\n# On the clean test machine, after copying artifacts:\nexport CUSTODIA_PACKAGE_INSTALL_CONFIRM=YES\nsudo -E ./scripts/package-install-smoke.sh install-verify\n```\n\nGenerate a release SBOM:\n\n```bash\nVERSION=1.0.0 make sbom\n```\n\nFor a clean machine first run, start with **[`docs/QUICKSTART.md`](docs/QUICKSTART.md)**. For the release scope and final pre-release guardrails, see **[`docs/RELEASE_NOTES_1_0_0.md`](docs/RELEASE_NOTES_1_0_0.md)**.\n\nThe package split is:\n\n- `custodia-server`: server, admin CLI, signer, hardened systemd units, server docs, YAML examples and SQLite backup helper;\n- `custodia-client`: encrypted `custodia-client` CLI.\n- `custodia-sdk`: SDK source snapshots, shared vectors and SDK docs.\n\nSee [`docs/LINUX_PACKAGES.md`](docs/LINUX_PACKAGES.md).\n\n## Local development\n\n```bash\ncp .env.example .env\nmake\nmake run-dev\n```\n\nThe default `make` target runs `make all`, which executes the Go test suite, builds the main binaries and generates local manual pages. Use `make test` when you only want the Go tests, `make build` when you only want binaries, `make man` when you only want manual pages, and `make check` for the full multi-language/release-like verification pass. Install all locally built server, client and SDK artifacts plus manual pages with `sudo make install`; use `sudo make install-server`, `sudo make install-client` or `sudo make install-sdk` for partial installs. Override `PREFIX`, `BINDIR`, `MANDIR`, `SHAREDIR`, `DOCDIR`, `SYSTEMDUNITDIR` or `DESTDIR` for staged installs.\n\nThe development mode uses the in-memory store and insecure HTTP only when `CUSTODIA_DEV_INSECURE_HTTP=true` is set. Production must use `CUSTODIA_TLS_CERT_FILE`, `CUSTODIA_TLS_KEY_FILE` and `CUSTODIA_CLIENT_CA_FILE`. Set `CUSTODIA_CLIENT_CRL_FILE` to a PEM CRL signed by the configured client CA to fail closed on revoked client certificate serials.\n\n## Build metadata\n\nRelease builds can stamp version, commit and date into every binary. Use `make release-metadata-check VERSION=1.0.0` before publishing artifacts, or `make release VERSION=1.0.0` to run the metadata guardrail plus the default build/test/manpage flow. The values are exposed through `GET /v1/status`, `/web/status`, `custodia-admin version`, `custodia-client version`, `custodia-server version` and `custodia-signer version`. Development builds print `dev unknown unknown` until release `-ldflags` are supplied. See `docs/BUILD_METADATA.md`.\n\n## Audit export integrity\n\nAudit JSONL exports include SHA-256 and event-count headers for offline verification. `custodia-admin audit verify-export` verifies exported body/digest/count artifacts. See `docs/AUDIT_EXPORT_INTEGRITY.md`.\n\n## PostgreSQL store\n\nThe default `make build`/`make install` path builds a universal `custodia-server` with both `sqlite` and `postgres` store support. Select PostgreSQL at runtime with configuration, not by installing a different product:\n\n```bash\nmake\n```\n\nThen configure:\n\n```bash\nCUSTODIA_STORE_BACKEND=postgres\nCUSTODIA_DATABASE_URL=postgres://custodia:secret@127.0.0.1:5432/custodia?sslmode=require\n```\n\nRun `migrations/postgres/001_init.sql` before starting the server. Container builds can enable the optional store with `CUSTODIA_GO_BUILD_TAGS=postgres docker compose build custodia` after the `pgx/v5` dependency is present in `go.mod`. The store persists only opaque ciphertext/envelope bytes and metadata; it does not add any server-side cryptographic key handling.\n\n## Custodia Lite / SQLite store\n\nLite is a single-node profile of the same codebase. The default build is universal and includes SQLite support, so Lite and Full use the same installed server binary. Select SQLite at runtime with configuration:\n\n```bash\nmake\n```\n\nThen configure:\n\n```bash\nCUSTODIA_PROFILE=lite\nCUSTODIA_STORE_BACKEND=sqlite\nCUSTODIA_DATABASE_URL=file:/var/lib/custodia/custodia.db\n```\n\nLite keeps mTLS, Web MFA, audit integrity and the opaque crypto boundary. It removes mandatory external runtime services; it does not create a weaker server-side crypto model.\n\n## API permissions\n\n```text\nshare = 1\nwrite = 2\nread  = 4\nall   = 7\n```\n\n## Example encrypted secret payload\n\n```json\n{\n  \"namespace\": \"oracle-prod\",\n  \"key\": \"user:sys\",\n  \"ciphertext\": \"Y2lwaGVydGV4dA==\",\n  \"crypto_metadata\": { \"format\": \"client-defined\" },\n  \"envelopes\": [\n    { \"client_id\": \"client_alice\", \"envelope\": \"ZW52ZWxvcGUtZm9yLWFsaWNl\" }\n  ],\n  \"permissions\": 7\n}\n```\n\nThe server validates authorization, the configured envelope-count cap and base64 transport syntax, then stores opaque transport data. It does not interpret the cryptographic content. Permission bitmasks must be non-zero combinations of `share`, `write` and `read`; the PostgreSQL schema enforces the same non-zero range guardrail.\n\n## Admin client metadata\n\n```bash\ncustodia-admin client create --client-id client_bob --mtls-subject client_bob\ncustodia-admin client list\ncustodia-admin client revoke --client-id client_bob --reason compromised\ncustodia-admin audit list --limit 100\ncustodia-admin audit verify --limit 500\n```\n\nClient creation registers metadata only. Secret sharing is performed by the client workflow with `namespace/key`; the server stores only opaque ciphertext and recipient envelopes. Certificate issuance/signing remains outside the vault server and belongs to the dedicated `custodia-signer` service. Lite package installs include `custodia-signer.service`; source installs can copy `deploy/examples/custodia-signer.service`.\n\nDevelopment signer example:\n\n```bash\nmake run-signer-dev\n```\n\nProduction signer mode requires mTLS and a dedicated CA material backend. See `docs/CA_SIGNING_SERVICE.md`.\n\n## Web metadata console\n\nThe admin web console is intentionally metadata-only. It requires an admin mTLS identity, uses a TOTP/passkey-capable web session, applies SameSite cookies plus same-origin browser mutation guards, and never renders ciphertext, envelopes, plaintext, or key material. Client drilldown pages show only metadata such as visible keyspace, owner/relationship and share permissions, and Kubernetes-safe operations such as one-shot client enrollment, future client revocation, client-CRL status, client CRL PEM download, CRL serial checks and browser-downloadable audit JSONL evidence. See `docs/WEB_CONSOLE.md` for the current page map and security boundary.\n\n## HTTP timeout guardrails\n\nThe server has bounded HTTP timeouts by default: read/write 15s, idle 60s and graceful shutdown 10s. Override with `CUSTODIA_HTTP_READ_TIMEOUT_SECONDS`, `CUSTODIA_HTTP_WRITE_TIMEOUT_SECONDS`, `CUSTODIA_HTTP_IDLE_TIMEOUT_SECONDS` and `CUSTODIA_SHUTDOWN_TIMEOUT_SECONDS`.\n\n## Verification and operations\n\n### PostgreSQL integration tests\n\nThe default test suite does not require external services. To exercise the optional PostgreSQL store, install the `postgres` build-tag dependencies and provide a disposable database URL:\n\n```bash\ngo get github.com/jackc/pgx/v5\nTEST_CUSTODIA_POSTGRES_URL=postgres://user:pass@localhost:5432/custodia_test?sslmode=disable make test-postgres\n```\n\n\n### Optional PostgreSQL integration check\n\nThe default test target is dependency-free. To verify the optional PostgreSQL store, provide a live test database and run:\n\n```bash\nTEST_CUSTODIA_POSTGRES_URL=postgres://user:pass@localhost:5432/custodia_test?sslmode=disable make test-postgres\n```\n\n\n### Runtime diagnostics\n\nUse `custodia-admin diagnostics read` or `GET /v1/diagnostics` with an admin mTLS client to inspect runtime metadata. On a standard local install, `custodia-admin diagnostics read` and `custodia-admin status read` derive the server URL and admin mTLS paths from `/etc/custodia/custodia-server.yaml`. The diagnostics output is metadata-only and never includes secret payloads or client-side cryptographic material.\n\nFor install diagnostics, use read-only doctor commands. See the dedicated\n[doctor diagnostics runbook](docs/DOCTOR.md) for offline, systemd, network and\nclient-profile examples.\n\n\n### Operational runbooks\n\nThe operational documentation is grouped by the workflow it supports, rather than by the order in which the documents were added. For the complete repository documentation index, see [`docs/README.md`](docs/README.md).\n\n**Release readiness and closure**\n\n- [Release readiness matrix](docs/RELEASE_READINESS_MATRIX.md)\n- [Release publishing runbook](docs/RELEASE_PUBLISHING.md)\n- [Production checklist](docs/PRODUCTION_CHECKLIST.md)\n- [Production readiness gate](docs/PRODUCTION_READINESS_GATE.md)\n- [Production external evidence gate](docs/PRODUCTION_EVIDENCE.md)\n- [Release check](docs/RELEASE_CHECK.md)\n- [Formal verification scope](docs/FORMAL_VERIFICATION.md)\n\n**Project planning and history**\n\n- [Project history index](docs/PROJECT_HISTORY.md)\n- [Custodia Wiki](https://github.com/marcofortina/custodia/wiki)\n- [GitHub Project roadmap](https://github.com/marcofortina/custodia/projects)\n\n**Deployment model and install paths**\n\n- [Deployment matrix](docs/DEPLOYMENT_MATRIX.md)\n- [Custodia bare-metal install quickstart](docs/QUICKSTART.md)\n- [Linux packages](docs/LINUX_PACKAGES.md)\n- [Kubernetes install](docs/KUBERNETES_INSTALL.md)\n- [Kubernetes Lite backup and restore](docs/KUBERNETES_LITE_BACKUP_RESTORE.md)\n- [Kubernetes runtime smoke](docs/KUBERNETES_RUNTIME_SMOKE.md)\n- [End-to-end operator release-candidate smoke](docs/END_TO_END_OPERATOR_SMOKE.md)\n- [k3s CockroachDB HA profile](docs/K3S_COCKROACHDB_HA.md)\n\n**Lite deployment and upgrade path**\n\n- [Custodia bare-metal install quickstart](docs/QUICKSTART.md)\n- [Custodia Lite profile](docs/LITE_PROFILE.md)\n- [Custodia Lite configuration](docs/LITE_CONFIG.md)\n- [Configuration reference](docs/CONFIG_REFERENCE.md)\n- [Doctor diagnostics](docs/DOCTOR.md)\n- [Lite installation guide](docs/LITE_INSTALL.md)\n- [Lite SQLite store](docs/LITE_SQLITE_STORE.md)\n- [Lite local CA bootstrap](docs/LITE_CA_BOOTSTRAP.md)\n- [Lite backup and restore](docs/LITE_BACKUP_RESTORE.md)\n- [Lite backup/restore smoke](docs/LITE_BACKUP_RESTORE_SMOKE.md)\n- [Kubernetes Lite backup and restore](docs/KUBERNETES_LITE_BACKUP_RESTORE.md)\n- [Lite migration readiness](docs/LITE_MIGRATION_READINESS.md)\n- [Lite to Full upgrade path](docs/LITE_TO_FULL_UPGRADE.md)\n\n**High availability, backup and disaster recovery**\n\n- [Backup and restore runbook](docs/BACKUP_RESTORE_RUNBOOK.md)\n- [Disaster recovery runbook](docs/DR_RUNBOOK.md)\n- [Database HA runbook](docs/DATABASE_HA_RUNBOOK.md)\n- [k3s CockroachDB HA profile](docs/K3S_COCKROACHDB_HA.md)\n\n**Identity, certificates and web authentication**\n\n- [CA signing service design](docs/CA_SIGNING_SERVICE.md)\n- [Client certificate lifecycle](docs/CLIENT_CERTIFICATE_LIFECYCLE.md) — includes one-shot enrollment and client-side CSR signing\n- [CRL and OCSP operations](docs/CRL_OCSP_RUNBOOK.md)\n- [PKCS#11 and SoftHSM signer bridge](docs/PKCS11_SOFTHSM.md)\n- [Web MFA](docs/WEB_MFA.md)\n- [Web passkey support](docs/WEB_PASSKEY.md)\n\n**Audit, evidence and shipment**\n\n- [Audit archive runbook](docs/AUDIT_ARCHIVE_RUNBOOK.md)\n- [Audit shipment runbook](docs/AUDIT_SHIPMENT_RUNBOOK.md)\n- [S3 Object Lock audit shipment](docs/S3_OBJECT_LOCK_AUDIT_SHIPMENT.md)\n- [SIEM and WORM audit export](docs/SIEM_WORM_EXPORT.md)\n\n**Client SDKs and crypto contracts**\n\n- [Custodia client libraries specification](docs/CLIENT_LIBRARIES.md)\n- [Client crypto specification](docs/CLIENT_CRYPTO_SPEC.md)\n- [Client crypto threat model](docs/CLIENT_CRYPTO_THREAT_MODEL.md)\n- [Namespace/key secret keyspace model](docs/SECRET_KEYSPACE_MODEL.md)\n- [Go client SDK](docs/GO_CLIENT_SDK.md)\n- [Custodia client CLI](docs/CUSTODIA_CLIENT_CLI.md)\n- [Python client SDK](docs/PYTHON_CLIENT_SDK.md)\n- [Node.js / TypeScript client SDK](docs/NODE_CLIENT_SDK.md)\n- [Java client SDK](docs/JAVA_CLIENT_SDK.md)\n- [C++ client SDK](docs/CPP_CLIENT_SDK.md)\n- [Rust client SDK](docs/RUST_CLIENT_SDK.md)\n- [Bash SDK helper](docs/BASH_SDK.md)\n- [SDK examples and compatibility matrix](docs/SDK_EXAMPLES_AND_COMPATIBILITY.md)\n- [SDK test vectors](docs/SDK_TEST_VECTORS.md)\n- [SDK release policy](docs/SDK_RELEASE_POLICY.md)\n- [SDK publishing readiness checklist](docs/SDK_PUBLISHING_READINESS.md)\n\n\n### Formal verification\n\nServer-side authorization invariants have executable Go model tests and a TLA+ model under `formal/`. Run `make formal-check` when TLC is installed.\n\n### Production readiness gate\n\nValidate offline production readiness/evidence environment files before promotion:\n\n```bash\ncustodia-admin production check --env-file .env.production\n```\n\nThe command fails on unsafe development defaults and missing external production dependencies.\n\n### Revocation serial status\n\n`custodia-signer` exposes a CRL-backed JSON revocation responder at `/v1/revocation/serial`. Use `custodia-admin revocation check-serial --serial-hex HEX` for operator drills. See `docs/CRL_OCSP_RUNBOOK.md`.\n\n\nSource install smoke:\n\n```bash\nmake install-smoke\n```\n\n\nValidate runtime configuration without starting daemons:\n\n```bash\ncustodia-server config validate --config /etc/custodia/custodia-server.yaml\ncustodia-signer config validate --config /etc/custodia/custodia-signer.yaml\n```\n\n\nRender starter runtime configuration templates:\n\n```bash\ncustodia-server config render --profile lite\ncustodia-server config render --profile full\ncustodia-signer config render\n```\n\n\nAudit log permission guardrail:\n\n```bash\nmake audit-log-permissions-check\n```\n\n- Reproducible build notes: [`docs/REPRODUCIBLE_BUILDS.md`](docs/REPRODUCIBLE_BUILDS.md)\n\n## Support the project\n\nCustodia is maintained as an open-source privacy-first secret-management project. If this repository helps your lab, research, compliance work, or integration testing, sponsorship helps keep development, testing, documentation, and security hardening moving.\n\nWays to support the project:\n\n- GitHub Sponsors: use the repository **Sponsor** button or sponsor `@marcofortina`.\n- PayPal: `https://paypal.me/marcofortina`.\n- Bitcoin: `36jDV57roGb4o59TwK1CB7viPrXToQHGiP`.\n\nBitcoin URI:\n\n```text\nbitcoin:36jDV57roGb4o59TwK1CB7viPrXToQHGiP\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcofortina%2Fcustodia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcofortina%2Fcustodia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcofortina%2Fcustodia/lists"}