How To

Vault Monitoring: The 7 Security Signals That Actually Matter

Vault monitoring is less about uptime and more about drift: root tokens that never got revoked, orphan tokens with no TTL, wildcard policies with sudo, audit devices nobody reads, and KV access patterns that signal a leaked credential. Part one of our HashiCorp Vault security audit series walks through the 7 signals that matter — seal and HA health, token sprawl, policy anti-patterns, audit-device gaps, anomalous reads, and lease hygiene — with one copy-pasteable detection command for each and the sober consequence of ignoring it.

·
vaultsecuritysecretshashicorpdevsecopsmonitoring
Cover Image for Vault Monitoring: The 7 Security Signals That Actually Matter

Vault Monitoring: The 7 Security Signals That Actually Matter

Somewhere in your infrastructure there is probably a root token that was generated during vault operator init, used to bootstrap the cluster, and never revoked. It has no TTL. It answers to no policy. It has been valid for two years, and the engineer who created it left last spring.

That token is the canonical Vault finding, and it illustrates why Vault monitoring is different from monitoring most infrastructure. Vault is rarely down — HashiCorp built it to stay up. What Vault does instead is drift: tokens accumulate, policies widen, audit devices silently stop being read, and the blast radius of a single leaked credential grows month over month while every dashboard stays green. Uptime checks won't catch any of it.

This guide covers the seven signals that matter — health, tokens, policies, audit devices, access patterns, and lease hygiene — with what "bad" looks like for each, one real detection command, and the sober version of what happens if you ignore it. You can run every check today with the Vault CLI and a token that has read access to the sys/ backend.

This is part one of a three-part series. Part two is a hands-on Vault audit using only native tools; part three covers running the same audit continuously with an AI agent.

1. Seal status and HA health

What it is. A sealed Vault serves nothing: every application depending on it for database credentials, API keys, or PKI certs starts failing on its next renewal. In an HA cluster, a sealed or partitioned standby is quieter but worse — you think you have failover, and you don't. Nodes reseal after host restarts, storage failures, or auto-unseal misconfigurations (an unreachable KMS key is a classic).

What bad looks like. Any node reporting Sealed: true, a raft cluster with fewer voters than you provisioned, or a standby that hasn't caught up with the active node.

How to detect it.

vault status
curl -s $VAULT_ADDR/v1/sys/health | jq

The sys/health endpoint is built for monitoring: it returns 200 for an unsealed active node, 429 for a healthy standby, and 503 for a sealed node — wire those status codes into whatever checker you already run. On raft clusters, add vault operator raft list-peers and alert when the peer count drops.

Typical consequence. An unnoticed sealed standby turns a routine active-node failure into a full outage of every service that fetches or renews credentials — commonly most of production.

2. Root tokens that never got revoked

What it is. Root tokens bypass all policy checks and never expire. HashiCorp's own guidance is to revoke the initial root token as soon as setup finishes and regenerate one only for break-glass operations. In practice, the setup token survives — kept "just in case," pasted in a wiki, exported in someone's shell history.

What bad looks like. Any live token carrying the root policy outside of an active, documented break-glass event.

How to detect it. Sweep every token accessor and flag the ones holding root (this needs a token with sudo on auth/token/accessors):

vault list -format=json auth/token/accessors | jq -r '.[]' | \
while read -r acc; do
  vault token lookup -format=json -accessor "$acc" | \
    jq -r 'select(.data.policies | index("root")) |
      "\(.data.accessor)  display=\(.data.display_name)  created=\(.data.creation_time)"'
done

Typical consequence. Whoever obtains that token owns every secret in Vault, can disable audit logging, and can rewrite every policy — with nothing standing between them and the KV store but the token string itself.

3. Token sprawl: long-lived and orphan tokens

What it is. Root tokens are the extreme case; the common case is hundreds of ordinary tokens minted by CI jobs, provisioning scripts, and humans, with TTLs measured in months or not at all. Orphan tokens are the worst offenders: they have no parent, so revoking the credential tree that created them leaves them alive.

What bad looks like. Tokens with expire_time: null or multi-month TTLs attached to service accounts that only needed the token for one deploy. Accessor counts growing steadily quarter over quarter is the sprawl signature.

How to detect it. The same accessor sweep, filtered for tokens that never expire:

vault list -format=json auth/token/accessors | jq -r '.[]' | \
while read -r acc; do
  vault token lookup -format=json -accessor "$acc" | \
    jq -r 'select(.data.expire_time == null) |
      "\(.data.accessor)  orphan=\(.data.orphan)  policies=\(.data.policies|join(","))"'
done

Typical consequence. Every long-lived token is a credential that behaves like a password from 2010: leak it once — a CI log, a laptop backup, a git commit — and it works indefinitely. On mature clusters it's common for this sweep to surface dozens of never-expiring tokens nobody can attribute.

4. Policy anti-patterns: wildcards and sudo

What it is. Vault token policies are deny-by-default, which is excellent right up until someone unblocks a deploy with path "secret/*" and capabilities = ["create", "read", "update", "delete", "list"]. Wildcard paths, blanket capability lists, and casually granted sudo (which unlocks protected sys/ endpoints) convert least-privilege into most-convenience.

What bad looks like. Policies granting * on broad path prefixes, sudo outside a small admin policy, or a default-adjacent policy that half the org inherits with write access to shared mounts.

How to detect it. Grep every policy for wildcards and sudo:

for p in $(vault policy list); do
  vault policy read "$p" | grep -nE '(\*|sudo)' | sed "s/^/$p: /"
done

Then confirm what a real token can actually do on a sensitive path with vault token capabilities — policies lie by omission; capability checks don't.

Typical consequence. Over-broad policies mean a compromised low-value credential (a staging CI token, say) reads production secrets. The gap between what a workload needs and what its policy grants is your lateral-movement surface.

5. Missing or unread audit devices

What it is. Vault refuses to complete a request it cannot audit — but only if an audit device is enabled at all. Plenty of clusters run with none, or with a file device writing to a disk nobody ships, rotates, or reads. An unread audit log is a compliance artifact, not a control.

What bad looks like. vault audit list returning nothing; a single device with no shipping pipeline behind it; or an audit log whose last human read was during the incident that prompted enabling it.

How to detect it.

vault audit list -detailed

Empty output is the finding. If a file device exists, follow up on the host: is the path on rotated storage, and does anything downstream consume it?

Typical consequence. When (not if) you investigate a suspected secret leak, the vault audit log is the only record of who read what and when. Without it, your incident report says "unknown scope, assume everything" — which means rotating every credential in the cluster.

6. KV access patterns that indicate a leaked credential

What it is. Having an audit device is step one; reading it is the control. A leaked token doesn't announce itself — it shows up as behavioral change in the vault audit log: one identity suddenly reading ten times its baseline, list-then-read enumeration across a KV mount, or reads from a source address that identity has never used.

What bad looks like. A service account that normally reads three paths at boot enumerating secret/ at 2 a.m.; a human identity active from two networks at once; read volume spiking without a matching deploy.

How to detect it. Rank identities by KV read volume from the file audit device:

jq -r 'select(.type == "response" and .request.operation == "read" and
       (.request.path | startswith("secret/data/"))) |
       .auth.display_name' /var/log/vault_audit.log | sort | uniq -c | sort -rn | head

Anything at the top you can't explain deserves a per-identity look at .request.path and .request.remote_address.

Typical consequence. The difference between catching a leaked token in hours versus weeks is roughly the difference between rotating one credential and running a full-scope breach response. Enumeration patterns in particular mean the reader is mapping what you have — that's reconnaissance, not an integration bug.

7. Lease and TTL hygiene

What it is. Dynamic secrets are Vault's best feature, and leases are their exhaust. Every dynamic database credential and every renewable token holds a lease; when defaults are generous (the token mount defaults to 32-day maximums) and consumers renew forever, the lease count climbs and credential lifetimes stretch far past anything you'd design on purpose.

What bad looks like. Lease counts growing without bound, mount-level TTLs still at defaults on sensitive mounts, and "dynamic" credentials that are functionally permanent because renewal never stops.

How to detect it. Watch the lease gauge via Vault telemetry and check what the token mount actually enforces:

curl -s -H "X-Vault-Token: $VAULT_TOKEN" \
  "$VAULT_ADDR/v1/sys/metrics?format=prometheus" | grep vault_expire_num_leases
vault read sys/auth/token/tune

Typical consequence. Unbounded lease growth degrades cluster performance and can destabilize storage; more quietly, long-lived dynamic credentials reopen the exact exposure window dynamic secrets were adopted to close.

Why the annual Vault review keeps missing these

None of these signals stays fixed. Tokens are minted daily, policies get widened during incidents and never re-narrowed, audit pipelines break on a log-shipper upgrade, and access baselines shift with every deploy. A point-in-time review — quarterly, annual, pre-audit — captures a snapshot of a system that drifts continuously, which means each finding is weeks old before anyone reads it, and the root token minted the day after the review is invisible until the next one.

The pragmatic sequencing: run the seven checks above this week, fix what they surface, then work through the DIY audit guide to script them with native tooling — and be honest about the point at which scheduled scripts stop being enough.

Make the checks continuous

Everything in this guide can run on watch instead of on calendar. Olivier, CloudThinker's security agent, connects to Vault with a read-only token and monitors seal and HA health, token sprawl, policy wildcards, audit-device gaps, and anomalous KV access continuously — surfacing findings the day they appear, with nothing revoked or changed without your approval. Try CloudThinker free — 100 premium credits, no card required — or continue with the hands-on DIY Vault audit.