Files
vault-tools/AGENTS.md
T
unkinben 123faf8bbf
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/test Pipeline failed
ci/woodpecker/pr/pre-commit Pipeline was successful
Add vctl and vctx Vault token CLIs
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
2026-07-26 23:28:05 +10:00

67 lines
2.7 KiB
Markdown

# 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`, `--method` and `--user` flags. Caches each token under
`~/.cache/vault/<context>` as JSON (token + accessor + policies + TTL/expiry).
- **`vctx`** — thin wrapper around the real `vault` CLI:
`vctx --context <ctx> <vault args...>` resolves the context, sets
`VAULT_ADDR`/`VAULT_TOKEN`/`VAULT_NAMESPACE`, and execs `vault`.
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
```bash
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 (see `shared/cache.go`).
- Token files are `0600`, their parent dirs `0700`; writes are atomic
(temp file + rename).
- `shared/vault.go` is a small hand-rolled Vault HTTP client (no
`hashicorp/vault/api` dependency) — only `cobra`, `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.