A lightweight secret server built with Rust and Axum. π¦β‘
It is designed for Kubernetes External Secrets (ESO) and homelabs: small, self-hosted setups that want a straightforward way to store encrypted secrets and sync them into workloads.
- Lightweight alternative to larger secret platforms.
- Built for ESO webhook flows in Kubernetes. βΈοΈ
- Practical for homelabs and small teams. π
- Built with Codex. π€
- No warranty. Use at your own risk.
- Main functionality is working, but this project is still considered alpha and the code may undergo major refactoring.
- Code quality and security will be improved over time.
- Security experts are welcome: reviews, threat-model feedback, and hardening PRs are encouraged. π
- Rust + Axum HTTP service. π¦
- Postgres storage. π
- Secrets encrypted at rest (envelope encryption, KEK/DEK model). π
- Session-based web UI for users/admin flows. π₯οΈ
- Minimal JavaScript footprint.
- Planned Datastar integration for a reactive UI.
- API key support, including
eso:readscope for ESO. π - Health endpoints:
/healthz,/readyz. β€οΈ
- Rust (stable)
- Postgres (14+ recommended)
openssl(for key generation)
./scripts/postgres.sh upStop it with:
./scripts/postgres.sh downexport DATABASE_URL="postgres://postgres:postgres@localhost:5432/enigma"
export KEK_CURRENT_ID="dev"
export KEK_CURRENT_B64="$(openssl rand -base64 32)"
export ADMIN_EMAIL="admin@example.com"Optional:
export HTTP_BIND="0.0.0.0:8080"
export LOG_LEVEL="info"
export ENVIRONMENTS="dev,staging,prod"cargo runOn startup it runs migrations and (if needed) bootstraps an admin account.
Open:
http://localhost:8080/ui/login
If admin bootstrap runs, a temporary password is printed in logs.
- New writes always use
KEK_CURRENT_ID+KEK_CURRENT_B64. - Existing secrets can only be decrypted if their original KEK is still available.
- Keep old KEKs during rotation, for example with
KEK_OLD_KEYS_B64='[{\"id\":\"k1\",\"b64\":\"...\"}]'. - You can also use per-key vars like
KEK_OLD_k1_B64=\"...\".
This project exposes an ESO webhook-compatible fetch endpoint:
GET /api/v1/eso/fetch?ref=<project>/<env>/<path>/<key>POST /api/v1/eso/fetchwith body{ "ref": "<project>/<env>/<path>/<key>" }
Expected ref format:
<project>/<env>/<path>/<key>
Example:
acme/prod/apps/payment/DATABASE_URL
Use an API key with eso:read scope for webhook authentication.
Use just targets:
just postgres-upjust postgres-downjust run-dev
Playwright end-to-end tests live in e2e/ and cover key UI/auth flows, including:
- Login, logout, onboarding, and access control/error handling.
- Project navigation and project switching.
- Admin workflows (create user/project, assign members).
- Members management (add, role update, remove).
- Secrets and secret versions (list, create, update, delete, detail views).
- API key management (list, create, revoke).
How to run:
cd e2e
npm install
npx playwright install --with-deps
npm testOptional modes:
npm run test:headednpm run test:debug
Notes:
- The harness starts Postgres via Testcontainers and starts the Rust server automatically.
- Docker must be running for Testcontainers.
Contributions are welcome, especially around:
- Security hardening π
- Code cleanup/refactoring π§Ή
- Kubernetes + ESO production guidance βΈοΈ
- Documentation quality βοΈ