Land the Vault ACL policies and an idempotent apply script. 18 policies:
service-{forgejo,woodpecker}, bot-{dev,review,gardener,architect,planner,
predictor,supervisor,vault,dev-qwen}, runner-{GITHUB,CODEBERG,CLAWHUB,
NPM,DOCKER_HUB}_TOKEN + runner-DEPLOY_KEY, and dispatcher.
tools/vault-apply-policies.sh diffs each file against the on-server
policy text before calling hvault_policy_apply, reporting created /
updated / unchanged per file. --dry-run prints planned names + SHA256
and makes no Vault calls.
vault/policies/AGENTS.md documents the naming convention (service-/
bot-/runner-/dispatcher), the KV path each policy grants, the rationale
for one-policy-per-runner-secret (AD-006 least-privilege at dispatch
time), and what lands in later S2.* issues (#880-#884).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
29 lines
881 B
HCL
29 lines
881 B
HCL
# vault/policies/dispatcher.hcl
|
|
#
|
|
# Edge dispatcher policy: needs to enumerate the runner secret namespace
|
|
# (to check secret presence before dispatching) and read the shared
|
|
# ops-repo credentials (token + clone URL) it uses to fetch action TOMLs.
|
|
#
|
|
# Scope:
|
|
# - kv/disinto/runner/* — read all per-secret values + list keys
|
|
# - kv/disinto/shared/ops-repo/* — read the ops-repo creds bundle
|
|
#
|
|
# The actual ephemeral runner container created per dispatch gets the
|
|
# narrow runner-<NAME> policies, NOT this one. This policy stays bound
|
|
# to the long-running dispatcher only.
|
|
|
|
path "kv/data/disinto/runner/*" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
path "kv/metadata/disinto/runner/*" {
|
|
capabilities = ["list", "read"]
|
|
}
|
|
|
|
path "kv/data/disinto/shared/ops-repo/*" {
|
|
capabilities = ["read"]
|
|
}
|
|
|
|
path "kv/metadata/disinto/shared/ops-repo/*" {
|
|
capabilities = ["list", "read"]
|
|
}
|