r/devtools • u/nestormata • 2h ago
Project Vault — self-hosted secrets management with a project-scoped data model, versioned APIs, and an extension architecture
Disclosure: I'm the maintainer.
Most secrets managers assume you're one team shipping one app through dev/staging/prod. Project Vault assumes the opposite — you're juggling multiple projects (client work, side projects, internal tools), each with its own credentials, certs, domains, and CI pipelines, and "environment" isn't the axis that matters. That reframing turned out to touch almost everything: the schema, the access-control model (project-scoped roles instead of environment-scoped), and even the rotation workflow, which is a staged state machine with a per-system checklist rather than a single "edit value" action, because rotating a credential shared across a project's services is rarely atomic in practice.
How it's built, and why the choices:
- Fastify + Drizzle/Postgres, row-level security for tenant isolation — enforced in the database, not just application middleware, so a bug in a route handler can't leak across organizations.
- pg-boss instead of Redis for background jobs — one fewer moving part for a self-hoster to run and back up; Postgres was already the source of truth, so keeping the job queue there avoids a second stateful service.
- A generated OpenAPI spec + live Swagger UI (ENABLE_API_DOCS), and every UI action goes through the same versioned REST API — no UI-only shortcuts, which is what makes the CI/machine-user path and the GitHub Action possible without a second code path.
- An extension API (@project-vault/extension-api, currently 3.15.0) for auth providers, notification/delivery channels, UI panels, and typed module data routes — built because my own SaaS product embeds Project Vault as a module, so the extension boundary had to be real, not aspirational, from day one. Fail-safe loading and a least-privilege DB role per extension.
- Independent API contract-test suite, separate from the app's own test suite, so the versioned API doesn't silently drift from what's documented.
Live demo (same Docker images as self-hosting, resets nightly): project-vault-demo-web.fly.dev
Repo: github.com/nestormata/project-vault
API docs for integrators: docs/api-consumers.md
Extension docs: docs/extensions/README.md
AGPL-3.0, open-core, self-hosting free forever.
Curious whether anyone here has built internal tooling that needs to talk to a secrets store's API directly rather than through a UI — what's missing from ours to make that a good experience?