← All projects
Secrets management

uBixVault

Beta · v0.2.0-beta.5 Go · BSD-3-Clause · Vault-compatible API

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.

Language
Go
License
BSD-3-Clause
Interface
Vault-compatible HTTP
At rest
AES-256-GCM
Synopsis
shell
ubixvault server -data <dir> [-audit-log <file>]
          [-tls-cert <f> -tls-key <f>]
ubixvault operator init | unseal | seal-status
Description

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.

Examples
build & run (dev)
# 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
initialize
# 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...."}
unseal & write a secret
$ 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"}}'
deploy on Kubernetes (Helm)
# 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
operate
$ 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/
Capabilities
Encryption barrier
AES-256-GCM at rest; the storage path is bound into the ciphertext so blobs can't be relocated.
Seal / unseal
In-house, constant-time Shamir over GF(2⁸). Nothing is readable until it's unsealed.
Tokens & ACL policies
Default-deny, path-based capabilities. Hand out scoped, non-root tokens.
KV v2 & Transit
Versioned secrets, plus encryption-as-a-service — keys never leave the vault.
Dynamic database credentials
Short-lived MariaDB users generated on demand and auto-revoked on lease expiry.
Web admin console
A built-in console at /ui/ to manage KV secrets (with version history), ACL policies, and tokens — served from the binary, no external assets.
Metrics & health
Prometheus metrics (seal state, uptime, request counts) and a readiness endpoint for probes and load balancers.
Kubernetes-native
Deploy with the bundled single-node Helm chart; pods authenticate with their ServiceAccount token, and the vault auto-unseals on restart — with recovery keys to regenerate a lost root token.
Machine authentication
AppRole (role_id + secret_id) and Kubernetes ServiceAccount auth methods, so automation logs in without a human-held token.
Rate limiting
Optional per-client token-bucket throttling to blunt brute-force against unseal shares and tokens; health, metrics, and the console are exempt.
Certificate authority
A built-in PKI engine: generate an internal root CA (its key never leaves the vault) and issue short-lived, role-constrained TLS certificates on demand.
Flexible auto-unseal
Shamir shares, a local key-encryption key, or a transit seal that unwraps the master key via another vault — no KEK on the host.
Configuration

Configuration reference.

The settings you'll actually reach for — the full reference lives in the deployment docs.

Server & CLI
SettingDefaultNotes
server -data <dir>./dataDirectory for the encrypted storage backend.
server -tls-cert / -tls-keyEnable 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_KEYHex 32-byte key-encryption key; enables auto-unseal on restart.
operator init -shares / -threshold5 / 3Shamir k-of-n split created at initialization.
-address$UBIXVAULT_ADDRClient → server address for the CLI.
-token$UBIXVAULT_TOKENClient auth token for the CLI.
-ca-cert / -tls-skip-verifyClient TLS trust. Skipping verification is insecure — dev only.
Helm chart · values.yaml
ValueDefaultNotes
containerPort / service.port8200Vault-compatible API port.
persistence.size / mountPath1Gi · /var/lib/ubixvaultEncrypted data volume (StatefulSet PVC).
autoUnseal.existingSecretSecret holding the KEK; auto-unseal is on by default.
tls.existingSecret / tls.certManagerBring your own cert, or issue one via cert-manager.
audit.enabledfalseFail-closed audit log to its own PVC.
rateLimit.enabled / perSecondfalse · 20Per-client token-bucket limit (burst 40).
kubernetesAuth.enabledtruePods authenticate with their ServiceAccount token.
metrics.serviceMonitor.enabledfalseScrape via the Prometheus Operator.
ingress.enabledfalseExpose over an ingress with TLS.
Architecture

Layered, and sealed at the base.

Every request passes down through the same layers, and everything at rest sits below the barrier.

The stack
HTTP API · CLI
clients enter here — Vault-compatible /v1/*
Auth Methods → Token & Lease Manager
Policy (ACL) engine · Identity
Secrets Engines
KV v2 · Transit · Database-dynamic
Audit Devices
broker → file / syslog · fail-closed
Barrier — AES-256-GCM at rest
Seal / Unseal · Shamir k-of-n
Storage Backend
file today · Raft later
How it holds

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.