Before Vault does anything clever — dynamic database credentials, PKI, transit encryption — it has to be stood up correctly. Most of the Vault trouble I get called into is not a failure of the fancy features. It is a broken baseline: an unseal ceremony nobody documented, a root token pasted into a deployment script, no audit device, and an app that authenticates as root because that was the token to hand.
This is the baseline done properly. One Vault node, initialised, serving versioned static secrets over the KV version 2 engine, with an audit trail and an app that authenticates as itself. Everything else you might want later is built on top of this. Get it wrong here and the clever features inherit the mistake.
Initialise, and respect what comes out
Assume Vault is installed and running against a storage backend — integrated Raft storage is the sensible default now — with TLS on the listener. A fresh Vault is sealed: it holds encrypted data it cannot read until it is unsealed. Initialisation is a one-time operation that generates the master key, splits it into unseal key shares using Shamir’s Secret Sharing, and issues the first root token.
Free · 4 minutes
Would you survive contact with a determined attacker — or an auditor?
Fourteen questions on access, patching, detection, and recovery — the basics that prevent most real incidents, and the ones most often assumed rather than verified. Banded finding on screen, full sheet by email.
# Point the CLI at your listener (use https in anything real)
export VAULT_ADDR='https://127.0.0.1:8200'
# Initialise: default is 5 key shares, any 3 required to unseal
vault operator init -key-shares=5 -key-threshold=3
# Output includes 5 Unseal Keys and one Initial Root Token.
# This is the ONLY time they are ever shown. Capture them now.
# Vault starts sealed. Unseal by supplying 3 distinct keys:
vault operator unseal <unseal-key-1>
vault operator unseal <unseal-key-2>
vault operator unseal <unseal-key-3>
vault status # Sealed false
Two things about that output matter more than anything else in this post. First, the five unseal keys are shown once and never again — Vault does not store them. If you lose enough of them to fall below the threshold, the data is unrecoverable. They should not all land with one person or in one system; the whole point of the threshold is that unsealing takes more than one human. Distribute them, and write down who holds which.
Second, the initial root token is a loaded weapon. Use it to bootstrap — enable audit, mount the engine, write the first policies — and then revoke it with vault token revoke. Do not bake it into a pipeline, do not leave it in your shell history, and never hand it to an application. If you keep a break-glass root token at all, keep it offline. Root exists to create the machinery that makes root unnecessary.
Turn on the audit device first
Enable auditing before you do anything else, because an audit device is what makes every subsequent action accountable. Vault can log to a file, to syslog, or to a socket. The file device is the usual starting point.
vault audit enable file file_path=/var/log/vault/vault_audit.log
vault audit list -detailed
Two behaviours to understand. Vault hashes sensitive values in the audit log with a salted HMAC, so the log records that a secret was accessed without leaking the secret itself. And by default, if Vault cannot write to any enabled audit device, it will refuse the request rather than proceed unlogged — auditing is fail-closed. That is the correct default for a regulated firm, but it means a full disk or a bad permission on the log directory can take Vault offline, so the log path needs the same monitoring as Vault itself.
Mount KV v2 and write a versioned secret
The KV version 2 engine stores static key/value secrets and keeps a version history, so an overwrite does not destroy the previous value and a bad rotation can be rolled back. Mount it explicitly at a path you choose.
# Mount the KV v2 engine at secret/
vault secrets enable -path=secret kv-v2
# Write a secret (this becomes version 1)
vault kv put secret/myapp/config db_password='s3cr3t-one' api_key='ak_live_123'
# Overwrite one field (this becomes version 2)
vault kv put secret/myapp/config db_password='s3cr3t-two' api_key='ak_live_123'
# Read the current version, then an older one
vault kv get secret/myapp/config
vault kv get -version=1 secret/myapp/config
# Inspect history
vault kv metadata get secret/myapp/config
The one gotcha that trips everybody: KV v2 rewrites the API path. When you run vault kv get secret/myapp/config, the CLI is really talking to secret/data/myapp/config, with a parallel secret/metadata/ path for version management. The vault kv subcommands hide this for you, but your policies do not get that courtesy — they must name the real path. This is the single most common reason a correctly-scoped policy still returns permission denied.
A policy and an AppRole, not the root token
An application should authenticate as itself, hold a short-lived token, and read only the secrets it needs. That is a policy plus an auth method. Write the policy against the real data/ path:
# myapp-policy.hcl — read-only on this app's config
path "secret/data/myapp/*" {
capabilities = ["read"]
}
# Allow it to see version metadata too (optional)
path "secret/metadata/myapp/*" {
capabilities = ["read", "list"]
}
vault policy write myapp myapp-policy.hcl
# Enable AppRole and bind the policy to a role
vault auth enable approle
vault write auth/approle/role/myapp \
token_policies="myapp" \
token_ttl=1h \
token_max_ttl=4h \
secret_id_ttl=24h
# The role_id is a stable identifier; the secret_id is the credential
vault read auth/approle/role/myapp/role-id
vault write -f auth/approle/role/myapp/secret-id
# The app exchanges the pair for a short-lived token
vault write auth/approle/login \
role_id=<role-id> secret_id=<secret-id>
AppRole splits identity into a role_id (which app) and a secret_id (proof it is that app), so you can ship the role_id in config and deliver the secret_id separately and briefly — pushed by an orchestrator, or fetched once at boot with a response-wrapped token. The login returns a token scoped to the myapp policy and nothing more. The same discipline that keeps API keys from becoming a liability — scope tightly, rotate, hash at rest — is what AppRole gives you for free, and the short-lived token it issues is exactly the kind of credential your services should be validating carefully rather than trusting blindly.
The parts people skip
Two loose ends decide whether this baseline survives contact with production. The first is unsealing. Manual Shamir unseal means every restart needs three humans and their key shares — fine for a demo, painful at 3am. Auto-unseal delegates the unseal key to a cloud KMS or an HSM via the seal stanza, so a restarted node comes back on its own while the recovery keys stay under threshold control. Decide which model you are running before you have an outage, not during one.
The second is backup. On integrated storage, vault operator raft snapshot save captures the encrypted state; a snapshot is worthless without the unseal or recovery keys to open it, so the two have to be protected together and tested together. And none of this helps if a secret was committed to git before it ever reached Vault — the migration into Vault is also the moment to put a pre-commit secret-scanning baseline in front of the repositories that used to hold those values in plaintext.
That is the whole baseline: initialised, audited, unsealable, backed up, and serving versioned secrets to apps that authenticate as themselves. Dynamic secrets, PKI and transit are worth doing — but every one of them assumes the boring parts above are already right. They usually aren’t, which is why the boring parts are the ones worth getting right first.
Build and rescue work
Hands-on delivery of this kind is handled by Sixteen Pillars Studio.
Free interactive tool
Website compliance checklist
What your site has to do, based on what it actually does
Answer as much or as little as you like — the list builds as you go. Nothing is stored against your name and no email is required.
Everything that applies
Ordered by what to do first: legal requirements you can close quickly, then larger pieces of work, then what is expected rather than required. Not exhaustive, and not a legal audit.
Dated PDF, yours to keep or circulate.
Most technology problems are not technology problems. They are control problems.
The systems exist. The investment has been made. The question is whether leadership can understand, direct, evidence, and sustain what those systems produce. Find out where control exists — and where it only appears to.