14 KiB
Configuration Reference
Complete guide to SecretumVault configuration via svault.toml.
Quick Start Configuration
Minimal working configuration:
[vault]
crypto_backend = "openssl"
[server]
address = "0.0.0.0"
port = 8200
[storage]
backend = "etcd"
[storage.etcd]
endpoints = ["http://localhost:2379"]
[seal]
seal_type = "shamir"
threshold = 2
shares = 3
[engines.kv]
path = "secret/"
versioned = true
[logging]
level = "info"
format = "json"
[telemetry]
prometheus_port = 9090
[auth]
default_ttl = 24
[vault] Section
Global vault settings.
[vault]
# Crypto backend: "openssl" (stable) | "aws-lc" (PQC ready) | "rustcrypto" (planned)
crypto_backend = "openssl"
Options
| Option | Type | Default | Description |
|---|---|---|---|
crypto_backend |
string | "openssl" |
Cryptographic backend for encrypt/decrypt/sign operations |
Valid Values
openssl- OpenSSL backend with classical crypto (RSA, ECDSA)aws-lc- AWS-LC with post-quantum support (requires featureaws-lc)rustcrypto- Pure Rust implementation (requires featurerustcrypto)
Example
[vault]
crypto_backend = "aws-lc" # Enable AWS-LC with ML-KEM, ML-DSA
[server] Section
HTTP server configuration.
[server]
# Binding address
address = "0.0.0.0"
# Port for API
port = 8200
# TLS certificate (optional)
# tls_cert = "/etc/secretumvault/tls.crt"
# TLS private key (optional)
# tls_key = "/etc/secretumvault/tls.key"
# Client CA for mTLS (optional)
# tls_client_ca = "/etc/secretumvault/client-ca.crt"
Options
| Option | Type | Default | Description |
|---|---|---|---|
address |
string | "0.0.0.0" |
IP address to bind to |
port |
integer | 8200 |
Port for HTTP/HTTPS |
tls_cert |
string | null | Path to TLS certificate file |
tls_key |
string | null | Path to TLS private key |
tls_client_ca |
string | null | Path to client CA certificate for mTLS |
Examples
Development (HTTP only):
[server]
address = "127.0.0.1"
port = 8200
Production (HTTPS):
[server]
address = "0.0.0.0"
port = 8200
tls_cert = "/etc/secretumvault/tls.crt"
tls_key = "/etc/secretumvault/tls.key"
With mTLS:
[server]
address = "0.0.0.0"
port = 8200
tls_cert = "/etc/secretumvault/tls.crt"
tls_key = "/etc/secretumvault/tls.key"
tls_client_ca = "/etc/secretumvault/client-ca.crt"
[storage] Section
Backend storage configuration.
[storage]
backend = "etcd" # etcd | surrealdb | postgresql | filesystem
[storage.etcd]
endpoints = ["http://localhost:2379"]
# username = "vault" # optional
# password = "secret" # optional
[storage.surrealdb]
url = "ws://localhost:8000"
# password = "secret" # optional
[storage.postgresql]
connection_string = "postgres://vault:secret@localhost:5432/secretumvault"
[storage.filesystem]
path = "/var/lib/secretumvault/data"
Backend Options
etcd
[storage]
backend = "etcd"
[storage.etcd]
# List of etcd endpoints
endpoints = ["http://localhost:2379"]
# Authentication (optional)
# username = "vault"
# password = "secret"
# Key prefix for vault keys (optional, default "/vault/")
# prefix = "/secretumvault/"
SurrealDB
[storage]
backend = "surrealdb"
[storage.surrealdb]
# WebSocket URL
url = "ws://localhost:8000"
# Namespace (optional, default "vault")
# namespace = "secretumvault"
# Database (optional, default "secrets")
# database = "vault_db"
# Authentication
# username = "vault"
# password = "secret"
PostgreSQL
[storage]
backend = "postgresql"
[storage.postgresql]
# Standard PostgreSQL connection string
connection_string = "postgres://vault:password@localhost:5432/secretumvault"
# Or individual components
# host = "localhost"
# port = 5432
# username = "vault"
# password = "secret"
# database = "secretumvault"
Filesystem
[storage]
backend = "filesystem"
[storage.filesystem]
# Directory for storing secrets (will be created if missing)
path = "/var/lib/secretumvault/data"
Example Configurations
High Availability (etcd):
[storage]
backend = "etcd"
[storage.etcd]
endpoints = [
"http://etcd-1.example.com:2379",
"http://etcd-2.example.com:2379",
"http://etcd-3.example.com:2379"
]
username = "vault"
password = "${ETCD_PASSWORD}"
Production (PostgreSQL):
[storage]
backend = "postgresql"
[storage.postgresql]
connection_string = "postgres://vault:${DB_PASSWORD}@db.example.com:5432/secretumvault"
[crypto] Section
Cryptographic backend configuration.
[crypto]
# Backend-specific settings (if any)
# Currently unused, reserved for future extensions
[seal] Section
Seal/unseal mechanism configuration.
[seal]
# Type: "shamir" (Shamir Secret Sharing) | "auto" (planned)
seal_type = "shamir"
[seal.shamir]
# Number of unseal keys to generate
shares = 5
# Number of keys needed to unseal (threshold)
threshold = 3
Shamir Secret Sharing (SSS)
Splits master key into shares keys, requiring threshold to reconstruct.
| Config | Meaning | Example |
|---|---|---|
shares = 5, threshold = 3 |
5 keys generated, need 3 to unseal | Most common |
shares = 3, threshold = 2 |
3 keys, need 2 (faster unsealing) | Small teams |
shares = 7, threshold = 4 |
7 keys, need 4 (higher security) | Large organizations |
Example
[seal]
seal_type = "shamir"
[seal.shamir]
shares = 5
threshold = 3
Unsealing: Run POST /v1/sys/unseal 3 times with 3 different keys.
[engines] Section
Secrets engines to mount.
Each engine has:
path- Mount point (e.g., "secret/", "transit/")versioned- Support multiple versions (KV, Transit only)
KV Engine
[engines.kv]
# Mount at /v1/secret/
path = "secret/"
# Support versioning: read past versions, restore, etc.
versioned = true
Transit Engine
[engines.transit]
# Mount at /v1/transit/
path = "transit/"
# Support key versioning and rotation
versioned = true
PKI Engine
[engines.pki]
# Mount at /v1/pki/
path = "pki/"
# PKI doesn't support versioning
versioned = false
Database Engine
[engines.database]
# Mount at /v1/database/
path = "database/"
# Database dynamic secrets don't support versioning
versioned = false
Complete Example
[engines.kv]
path = "secret/"
versioned = true
[engines.transit]
path = "transit/"
versioned = true
[engines.pki]
path = "pki/"
versioned = false
[engines.database]
path = "database/"
versioned = false
Then access at:
GET /v1/secret/data/myapp- KV readPOST /v1/transit/encrypt/key- Transit encryptPOST /v1/pki/issue/role- PKI issuePOST /v1/database/config/postgres- Database config
[logging] Section
Structured logging configuration.
[logging]
# Level: "trace" | "debug" | "info" | "warn" | "error"
level = "info"
# Format: "json" | "pretty"
format = "json"
# Output: "stdout" | "stderr" | file path
output = "stdout"
# ANSI colors (for pretty format)
ansi = true
Options
| Option | Type | Values | Default |
|---|---|---|---|
level |
string | trace, debug, info, warn, error | "info" |
format |
string | json, pretty | "json" |
output |
string | stdout, stderr, file path | "stdout" |
ansi |
bool | true, false | true |
Examples
Development (Human-readable):
[logging]
level = "debug"
format = "pretty"
output = "stdout"
ansi = true
Production (JSON logs):
[logging]
level = "info"
format = "json"
output = "stdout"
ansi = false
To file:
[logging]
level = "info"
format = "json"
output = "/var/log/secretumvault/vault.log"
[telemetry] Section
Observability and metrics configuration.
[telemetry]
# Port for Prometheus metrics endpoint
prometheus_port = 9090
# Enable distributed tracing (future)
enable_trace = false
Options
| Option | Type | Default | Description |
|---|---|---|---|
prometheus_port |
integer | 9090 |
Port for /metrics endpoint |
enable_trace |
bool | false |
Enable OpenTelemetry tracing (planned) |
Metrics Endpoint
With prometheus_port = 9090:
curl http://localhost:9090/metrics
Returns Prometheus-format metrics:
vault_secrets_stored_total- Secrets storedvault_secrets_read_total- Secrets readvault_operations_encrypt- Encryption opsvault_tokens_created- Tokens created
Prometheus Scrape Config
scrape_configs:
- job_name: 'vault'
static_configs:
- targets: ['localhost:9090']
scrape_interval: 10s
[auth] Section
Authentication and authorization configuration.
[auth]
# Default token TTL in hours
default_ttl = 24
# Cedar policies directory
# cedar_policies_dir = "/etc/secretumvault/policies"
# Cedar entity entities file (optional)
# cedar_entities_file = "/etc/secretumvault/entities.json"
Options
| Option | Type | Default | Description |
|---|---|---|---|
default_ttl |
integer | 24 |
Token lifetime in hours |
cedar_policies_dir |
string | null | Directory containing .cedar policy files |
cedar_entities_file |
string | null | JSON file with Cedar entities |
Cedar Policies
Load policies from directory:
mkdir -p /etc/secretumvault/policies
cat > /etc/secretumvault/policies/admin.cedar <<'EOF'
permit (
principal == User::"admin",
action,
resource
);
EOF
cat > /etc/secretumvault/policies/readers.cedar <<'EOF'
permit (
principal,
action == Action::"read",
resource == Secret::*
) when {
principal has policies &&
principal.policies.contains("reader")
};
EOF
Config:
[auth]
default_ttl = 24
cedar_policies_dir = "/etc/secretumvault/policies"
Cedar Entities
Define attributes for principals and resources:
{
"User::alice": {
"policies": ["admin", "reader"],
"department": "engineering"
},
"User::bob": {
"policies": ["reader"],
"department": "finance"
},
"Secret::secret/database": {
"sensitivity": "high",
"owner": "engineering"
}
}
Config:
[auth]
cedar_entities_file = "/etc/secretumvault/entities.json"
Environment Variable Substitution
Use environment variables in configuration:
[storage.postgresql]
connection_string = "postgres://vault:${DB_PASSWORD}@db.example.com:5432/vault"
[storage.surrealdb]
password = "${SURREAL_PASSWORD}"
[storage.etcd]
username = "${ETCD_USER}"
password = "${ETCD_PASSWORD}"
At startup:
export DB_PASSWORD="secret123"
export SURREAL_PASSWORD="surrealpass"
export ETCD_USER="vault"
export ETCD_PASSWORD="etcdpass"
cargo run -- server --config svault.toml
Or in Docker:
docker run -e DB_PASSWORD=secret123 secretumvault:latest server --config svault.toml
Complete Production Configuration
[vault]
crypto_backend = "aws-lc"
[server]
address = "0.0.0.0"
port = 8200
tls_cert = "/etc/secretumvault/tls.crt"
tls_key = "/etc/secretumvault/tls.key"
tls_client_ca = "/etc/secretumvault/client-ca.crt"
[storage]
backend = "postgresql"
[storage.postgresql]
connection_string = "postgres://vault:${DB_PASSWORD}@db.prod.internal:5432/secretumvault"
[seal]
seal_type = "shamir"
[seal.shamir]
shares = 5
threshold = 3
[engines.kv]
path = "secret/"
versioned = true
[engines.transit]
path = "transit/"
versioned = true
[engines.pki]
path = "pki/"
versioned = false
[engines.database]
path = "database/"
versioned = false
[logging]
level = "info"
format = "json"
output = "stdout"
ansi = false
[telemetry]
prometheus_port = 9090
enable_trace = true
[auth]
default_ttl = 24
cedar_policies_dir = "/etc/secretumvault/policies"
cedar_entities_file = "/etc/secretumvault/entities.json"
Configuration Validation
Vault validates configuration at startup:
Config Loading
↓
Parse TOML
↓
Validate backends available
↓
Check path collisions (no duplicate mount paths)
↓
Validate seal config (threshold ≤ shares)
↓
Check required fields
↓
Success: Start vault
If validation fails, vault exits with error message.
Configuration Changes
Static Configuration
Configuration is loaded once at startup. To change:
- Edit
svault.toml - Restart vault process
- Re-unseal vault with keys
Hot Reload (Planned)
Future versions may support:
- Token policy updates without restart
- Log level changes
- Metrics port changes
For now, restart is required.
Troubleshooting
"Unknown backend: xyz"
Cause: Backend name doesn't exist or feature not enabled
Solution:
# Check available backends
grep "backend =" svault.toml
# Verify feature enabled
cargo build --features etcd-storage,postgresql-storage
"Duplicate mount path"
Cause: Two engines configured at same path
Solution:
# Wrong:
[engines.kv]
path = "secret/"
[engines.transit]
path = "secret/" # Conflict!
# Correct:
[engines.kv]
path = "secret/"
[engines.transit]
path = "transit/"
"Invalid seal config: threshold > shares"
Cause: Need more keys than generated
Solution:
# Wrong:
[seal.shamir]
shares = 3
threshold = 5 # Can't need 5 keys when only 3 exist!
# Correct:
[seal.shamir]
shares = 5
threshold = 3 # threshold ≤ shares
"Failed to connect to storage"
Cause: Backend endpoint wrong or unreachable
Solution:
# Test connectivity
curl http://localhost:2379/health # etcd
curl ws://localhost:8000 # SurrealDB
psql postgres://user:pass@host/db # PostgreSQL
For deployment-specific configuration, see Deployment Guide