162 lines
5.5 KiB
Markdown
162 lines
5.5 KiB
Markdown
# 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`](vctx.md) 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`).
|
|
|
|
```yaml
|
|
# ~/.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`)
|
|
as JSON. Slash contexts nest: `staging/sydney` →
|
|
`~/.cache/vcm/staging/sydney`. Parent directories are created `0700` and token
|
|
files are written `0600`.
|
|
|
|
Each file stores enough to inspect and later revoke the token:
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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).
|