A from-scratch secrets manager in Go. It stores and generates secrets behind an encrypted, sealed barrier — and speaks a Vault-compatible HTTP API, so tools you already have can talk to it unchanged.
ubixvault server -data <dir> [-audit-log <file>] [-tls-cert <f> -tls-key <f>] ubixvault operator init | unseal | seal-status
All data at rest is AES-256-GCM encrypted — storage never sees plaintext, and the storage path is bound into the ciphertext so blobs can't be relocated.
The vault boots sealed. Its master key is reconstructed from Shamir k-of-n key shares before any secret is readable — or, given a key-encryption key, the vault can auto-unseal itself on restart, with recovery keys to regenerate a lost root token. Access is default-deny, path-based tokens with ACL policies, and audit logging is fail-closed — the client token is HMAC'd, never logged in the clear.
A built-in web console at /ui/ manages secrets (with version history), policies, and tokens, and a Prometheus metrics endpoint exposes seal state and request counts for scraping.
# build and run in dev mode (plain HTTP, audit on) $ go build -o bin/ubixvault ./cmd/ubixvault $ ./bin/ubixvault server -data ./data -audit-log ./audit.log
# 3 unseal shares, threshold 2 $ curl -s -X POST $VAULT/v1/sys/init \ -d '{"secret_shares":3,"secret_threshold":2}' -> {"keys":["k0","k1","k2"], "root_token":"uv...."}
$ curl -s -X POST $VAULT/v1/sys/unseal -d '{"key":"k0"}' $ curl -s -X POST $VAULT/v1/sys/unseal -d '{"key":"k1"}' $ curl -sH "$T" -X POST $VAULT/v1/secret/data/app \ -d '{"data":{"api_key":"sk-123"}}'
# single-node chart: StatefulSet, auto-unseal, TLS $ kubectl create secret generic uv-kek \ --from-literal=auto-unseal-key=$(head -c32 /dev/urandom|xxd -p|tr -d '\n') $ helm install vault ./deploy/charts/ubixvault \ --set tls.existingSecret=uv-tls --set autoUnseal.existingSecret=uv-kek
$ curl -s $VAULT/v1/sys/health # readiness (200/503/501) $ curl -s $VAULT/v1/sys/metrics # Prometheus text format # manage it from the web console at $VAULT/ui/
/ui/ to manage KV secrets (with version history), ACL policies, and tokens — served from the binary, no external assets.The settings you'll actually reach for — the full reference lives in the deployment docs.
| Setting | Default | Notes |
|---|---|---|
| server -data <dir> | ./data | Directory for the encrypted storage backend. |
| server -tls-cert / -tls-key | — | Enable HTTPS. Without them the server logs a loud no-TLS warning (dev only). |
| server -audit-log <path> | — | Turns on fail-closed audit logging to that file. |
| server -auto-unseal-key <hex> | $UBIXVAULT_AUTO_UNSEAL_KEY | Hex 32-byte key-encryption key; enables auto-unseal on restart. |
| operator init -shares / -threshold | 5 / 3 | Shamir k-of-n split created at initialization. |
| -address | $UBIXVAULT_ADDR | Client → server address for the CLI. |
| -token | $UBIXVAULT_TOKEN | Client auth token for the CLI. |
| -ca-cert / -tls-skip-verify | — | Client TLS trust. Skipping verification is insecure — dev only. |
| Value | Default | Notes |
|---|---|---|
| containerPort / service.port | 8200 | Vault-compatible API port. |
| persistence.size / mountPath | 1Gi · /var/lib/ubixvault | Encrypted data volume (StatefulSet PVC). |
| autoUnseal.existingSecret | — | Secret holding the KEK; auto-unseal is on by default. |
| tls.existingSecret / tls.certManager | — | Bring your own cert, or issue one via cert-manager. |
| audit.enabled | false | Fail-closed audit log to its own PVC. |
| rateLimit.enabled / perSecond | false · 20 | Per-client token-bucket limit (burst 40). |
| kubernetesAuth.enabled | true | Pods authenticate with their ServiceAccount token. |
| metrics.serviceMonitor.enabled | false | Scrape via the Prometheus Operator. |
| ingress.enabled | false | Expose over an ingress with TLS. |
Every request passes down through the same layers, and everything at rest sits below the barrier.
A request enters through the Vault-compatible HTTP API (or the ubixvault CLI), is authenticated to a token, and checked against default-deny path ACLs before any secrets engine runs. Every request and response passes through the audit broker on the way through.
Beneath all of it sits the barrier: everything written to storage is AES-256-GCM encrypted, with the storage path and format version bound in as authenticated data — so a ciphertext only decrypts at the exact path it was written to, and can't be relocated.
The vault boots sealed, holding only ciphertext. Unsealing reconstructs the master key from Shamir k-of-n shares. The key hierarchy — unseal shares → master key → barrier key → data — lets the barrier key rotate without re-sharing.