Files
vault-tools/docs/vcm.md
T
unkin-agent 42048ae6ee
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Encrypt cached tokens with a kernel keyring key
2026-10-23 23:07:35 +11:00

5.9 KiB

vcm

vcm manages Vault tokens for multiple vault instances ("contexts"). It logs in to (or renews tokens for) one or all configured contexts and caches each resulting token under ~/.cache/vcm/<context> for use by vctx and other tooling.

Synopsis

vcm login <context>      # log in to one context
vcm login --all          # log in to every configured context
vcm renew <context>      # renew one context's cached token
vcm renew --all          # renew every context that has a cached token
vcm list                 # show contexts + cached-token status
vcm version

Flags

Both login and renew accept:

Flag Default Description
--all false Operate on every configured context.
--method <m> context/config, else ldap Override the auth method (ldap, userpass, okta, radius, token, oidc).
--user <u> context/config, else $USER Override the login username.

login also accepts:

Flag Default Description
--role <r> context role, else mount default OIDC role to log in with.
--listen <a> context oidc_listen, else localhost:8250 OIDC callback listen address.

A context name or --all is required (but not both).

Configuration

vcm reads ~/.config/vcm/config.yaml ($XDG_CONFIG_HOME is honoured in place of ~/.config).

# ~/.config/vcm/config.yaml
defaults:
  method: ldap          # applied to any context that doesn't set its own
  user: ben
  namespace: ""

contexts:
  sydney:
    address: https://vault.syd1.au.unkin.net

  staging/sydney:                       # slashes are allowed; they nest on disk
    address: https://vault-staging.syd1.au.unkin.net
    namespace: staging
    user: svc-ben                       # per-context override

  legacy:
    address: https://vault-legacy.example.net
    method: userpass
    path: userpass2                      # override the auth mount path (default = method)

  sydney/admin:                         # OIDC: one context per role
    address: https://vault.syd1.au.unkin.net
    method: oidc
    role: admin

Field resolution

For each context, every field is resolved with the chain context value → file defaults → built-in default:

  • method — built-in default ldap.
  • user — built-in default $USER.
  • namespace — no built-in default (unset means the root namespace).
  • path — the auth mount path; defaults to the resolved method.
  • role — OIDC role; unset uses the mount's default_role.
  • oidc_listen — OIDC callback listener on a loopback host (localhost, 127.0.0.1 or [::1]); defaults to localhost:8250.

--method / --user on the command line override the resolved values. When --method changes the method and the context did not pin an explicit path, the auth path follows the new method.

Auth methods

  • Password methods (ldap, userpass, okta, radius): vcm prompts for a password (no echo) and POSTs to auth/<path>/login/<user>.
  • token: vcm prompts for a raw Vault token (no echo), verifies it with auth/token/lookup-self, and caches its details.
  • oidc: the same flow as vault login -method=oidc. vcm listens on oidc_listen, requests auth/<path>/oidc/auth_url with redirect_uri=http://<oidc_listen>/oidc/callback, opens the URL with xdg-open (printing it too), and exchanges the returned code via auth/<path>/oidc/callback. It gives up after 2 minutes. The redirect URI must be in the role's allowed_redirect_uris. --all runs each OIDC context's browser login in turn.

Token cache

Tokens are written to ~/.cache/vcm/<context> (honouring $XDG_CACHE_HOME) encrypted (AES-256-GCM) with a random key held in the kernel user keyring (description vcm, shared with vctx). The key lives only until reboot, so after a reboot cached tokens can no longer be decrypted: vcm list shows them as locked — run 'vcm login <context>' and vctx errors with the same hint. Files written by older, plaintext versions show as locked too; logging in again replaces them. Slash contexts nest: staging/sydney → ~/.cache/vcm/staging/sydney. Parent directories are created 0700 and token files are written 0600.

The decrypted payload stores enough to inspect and later revoke the token:

{
  "context": "staging/sydney",
  "address": "https://vault-staging.syd1.au.unkin.net",
  "namespace": "staging",
  "token": "s....",
  "accessor": "hmac-...",
  "policies": ["default", "kv-read"],
  "renewable": true,
  "lease_duration_seconds": 3600,
  "issued_at": "2026-07-26T12:00:00Z",
  "expires_at": "2026-07-26T13:00:00Z"
}

The accessor lets you revoke the token later without exposing the secret (vault token revoke -accessor <accessor>).

Examples

# Log in to one context (prompts for password)
vcm login sydney

# Log in everywhere at once
vcm login --all

# Log in to a context overriding the method + user
vcm login sydney --method okta --user someone.else

# OIDC login with a different role than the context's
vcm login sydney/admin --role readonly

# Renew a slash-named context
vcm renew staging/sydney

# Renew everything that currently has a cached token
vcm renew --all

# See what is configured and which tokens are still valid
vcm list

Shell completion

vcm completion bash > /etc/bash_completion.d/vcm
vcm completion zsh  > ~/.zsh/completions/_vcm

Context names complete dynamically from the config file (the RPM installs these completions automatically).