Introduces the vault-tools monorepo: two Go CLIs that share a config file (~/.config/vault) and token cache (~/.cache/vault) for working with multiple Vault instances (contexts). - add shared/ library: config parsing (vctl.yaml/config.yaml, per-context overrides, slash contexts), token cache (0600/0700, atomic writes, path- traversal guards), and a small hand-rolled Vault HTTP client (login/renew) - add vctl: login/renew (single or --all), list, --method/--user overrides, no-echo password/token prompts, dynamic context completion - add vctx: resolve a context, set VAULT_ADDR/VAULT_TOKEN/VAULT_NAMESPACE and exec the vault CLI, passing remaining args through untouched - add unit tests across shared/, vctl and vctx command layers (config resolution, cache paths, vault client, --all iteration + error aggregation, vctx arg pass-through and env construction via fakeable exec/prompt seams) - add Makefile (build/test/completions/rpm, patch|minor|major version bumps), nfpm RPM packaging bundling bash/zsh/fish completions for both binaries - add Woodpecker pipelines: build/test/pre-commit on PRs, and a tag release that cross-compiles, builds+uploads the RPM to artifactapi, and cuts a Gitea release (serviceAccountName default, k8s resources on every step) - add README, per-command docs (docs/vctl.md, docs/vctx.md), AGENTS.md and an example config Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
2.7 KiB
AGENTS.md
Project Overview
vault-tools is a Go monorepo of small CLIs for managing Vault tokens across
multiple vault instances ("contexts"):
vctl— logs in to / renews Vault tokens per context (login,renew,list), with--all,--methodand--userflags. Caches each token under~/.cache/vault/<context>as JSON (token + accessor + policies + TTL/expiry).vctx— thin wrapper around the realvaultCLI:vctx --context <ctx> <vault args...>resolves the context, setsVAULT_ADDR/VAULT_TOKEN/VAULT_NAMESPACE, and execsvault.
Both tools share the shared/ package (config parsing, token cache, Vault HTTP
client) and read the SAME config file (~/.config/vault/vctl.yaml or
config.yaml) and token cache so one ~/.config/vault/ configures everything.
Structure
shared/ # config.go, cache.go, vault.go (+ *_test.go)
vctl/main.go # vctl CLI (module main package)
vctx/main.go # vctx CLI (module main package)
docs/vctl.md # per-command docs
docs/vctx.md
go.mod # module git.unkin.net/unkin/vault-tools
Makefile # build / test / lint / completions / rpm / version-bump
packaging/nfpm.yaml# nfpm spec (envsubst-templated) for the RPM (both binaries)
scripts/build-rpm.sh
.woodpecker/ # CI: build, test, pre-commit (PR) + release (tag)
dist/ # build output: binaries, completions, RPM (not committed)
Each tool is a separate main package under its own folder, so make build
builds each with its own -o (a single go build ./... can't emit multiple
mains to one file).
Build / test
make build # -> dist/vctl, dist/vctx
make test # go test -race ./...
make completions # -> dist/completions/{vctl,vctx}.{bash,fish}, _{vctl,vctx}
make rpm # build + nfpm RPM (bundles completions)
go build ./... && go test ./...
Conventions
- Config/cache dirs honour
$XDG_CONFIG_HOME/$XDG_CACHE_HOME. - Context names may contain slashes (
staging/sydney) and nest in the cache; names are validated to prevent path traversal (seeshared/cache.go). - Token files are
0600, their parent dirs0700; writes are atomic (temp file + rename). shared/vault.gois a small hand-rolled Vault HTTP client (nohashicorp/vault/apidependency) — onlycobra,yaml.v3,x/term.
Releasing
Releases run in Woodpecker on v* tags. make patch|minor|major tags + pushes.
The release pipeline cross-compiles both binaries, builds an RPM (with
completions), PUTs it to the artifactapi rpm-internal yum repo, and cuts a
Gitea release. Every pipeline step sets k8s resources and
serviceAccountName: default; the release step uses the RELEASER_TOKEN
Woodpecker secret.