Merge pull request 'fix: External actions (publish, deploy, post) must go through vault — agents cannot hold tokens directly (#745)' (#763) from fix/issue-745 into main
This commit is contained in:
commit
04696b35a9
5 changed files with 62 additions and 4 deletions
13
.env.example
13
.env.example
|
|
@ -47,6 +47,19 @@ WOODPECKER_DB_USER=woodpecker # [CONFIG] Postgres user
|
||||||
WOODPECKER_DB_HOST=127.0.0.1 # [CONFIG] Postgres host
|
WOODPECKER_DB_HOST=127.0.0.1 # [CONFIG] Postgres host
|
||||||
WOODPECKER_DB_NAME=woodpecker # [CONFIG] Postgres database name
|
WOODPECKER_DB_NAME=woodpecker # [CONFIG] Postgres database name
|
||||||
|
|
||||||
|
# ── Vault-only secrets (DO NOT put these in .env) ────────────────────────
|
||||||
|
# These tokens grant access to external systems (GitHub, ClawHub, deploy targets).
|
||||||
|
# They live ONLY in .env.vault.enc and are injected into the ephemeral vault-runner
|
||||||
|
# container at fire time (#745). lib/env.sh explicitly unsets them so agents
|
||||||
|
# can never hold them directly — all external actions go through vault dispatch.
|
||||||
|
#
|
||||||
|
# GITHUB_TOKEN — GitHub API access (publish, deploy, post)
|
||||||
|
# CLAWHUB_TOKEN — ClawHub registry credentials (publish)
|
||||||
|
# (deploy keys) — SSH keys for deployment targets
|
||||||
|
#
|
||||||
|
# To manage vault secrets: disinto secrets edit-vault
|
||||||
|
# See also: vault/vault-run-action.sh, vault/vault-fire.sh
|
||||||
|
|
||||||
# ── Project-specific secrets ──────────────────────────────────────────────
|
# ── Project-specific secrets ──────────────────────────────────────────────
|
||||||
# Store all project secrets here so formulas reference env vars, never hardcode.
|
# Store all project secrets here so formulas reference env vars, never hardcode.
|
||||||
BASE_RPC_URL= # [SECRET] on-chain RPC endpoint
|
BASE_RPC_URL= # [SECRET] on-chain RPC endpoint
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ Humans write these. Agents read and enforce them.
|
||||||
| AD-003 | The runtime creates and destroys, the formula preserves. | Runtime manages worktrees/sessions/temp. Formulas commit knowledge to git before signaling done. |
|
| AD-003 | The runtime creates and destroys, the formula preserves. | Runtime manages worktrees/sessions/temp. Formulas commit knowledge to git before signaling done. |
|
||||||
| AD-004 | Event-driven > polling > fixed delays. | Never `waitForTimeout` or hardcoded sleep. Use phase files, webhooks, or poll loops with backoff. |
|
| AD-004 | Event-driven > polling > fixed delays. | Never `waitForTimeout` or hardcoded sleep. Use phase files, webhooks, or poll loops with backoff. |
|
||||||
| AD-005 | Secrets via env var indirection, never in issue bodies. | Issue bodies become code. Agent secrets go in `.env.enc`, vault secrets in `.env.vault.enc` (both SOPS-encrypted). Referenced as `$VAR_NAME`. Vault-runner gets only vault secrets; agents get only agent secrets. |
|
| AD-005 | Secrets via env var indirection, never in issue bodies. | Issue bodies become code. Agent secrets go in `.env.enc`, vault secrets in `.env.vault.enc` (both SOPS-encrypted). Referenced as `$VAR_NAME`. Vault-runner gets only vault secrets; agents get only agent secrets. |
|
||||||
|
| AD-006 | External actions go through vault dispatch, never direct. | Agents build addressables; only the vault exercises them (publishes, deploys, posts). Tokens for external systems (`GITHUB_TOKEN`, `CLAWHUB_TOKEN`, deploy keys) live only in `.env.vault.enc` and are injected into the ephemeral vault-runner container. `lib/env.sh` unsets them so agents never hold them. PRs with direct external actions without vault dispatch get REQUEST_CHANGES. |
|
||||||
|
|
||||||
**Who enforces what:**
|
**Who enforces what:**
|
||||||
- **Gardener** checks open backlog issues against ADs during grooming; closes violations with a comment referencing the AD number.
|
- **Gardener** checks open backlog issues against ADs during grooming; closes violations with a comment referencing the AD number.
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,10 @@ services:
|
||||||
DISINTO_CONTAINER: "1"
|
DISINTO_CONTAINER: "1"
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
|
# IMPORTANT: agents get .env only (forge tokens, CI tokens, config).
|
||||||
|
# Vault-only secrets (GITHUB_TOKEN, CLAWHUB_TOKEN, deploy keys) live in
|
||||||
|
# .env.vault.enc and are NEVER injected here — only the vault-runner
|
||||||
|
# container receives them at fire time (AD-006, #745).
|
||||||
depends_on:
|
depends_on:
|
||||||
- forgejo
|
- forgejo
|
||||||
- woodpecker
|
- woodpecker
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,40 @@ already contains a similar item (same resource, same ask). List the
|
||||||
vault directories to inspect existing items. If a duplicate or
|
vault directories to inspect existing items. If a duplicate or
|
||||||
near-duplicate exists, REQUEST_CHANGES and reference the existing item.
|
near-duplicate exists, REQUEST_CHANGES and reference the existing item.
|
||||||
|
|
||||||
## 5. Re-review (if previous review is provided)
|
## 5. External action detection (token separation)
|
||||||
|
|
||||||
|
Agents must NEVER execute external actions directly. Any action that touches
|
||||||
|
an external system (publish, deploy, post, push to external registry, API
|
||||||
|
calls to third-party services) MUST go through vault dispatch — i.e., the
|
||||||
|
agent files a vault item (`vault/pending/*.json`) and the vault-runner
|
||||||
|
container executes it with injected secrets.
|
||||||
|
|
||||||
|
Scan the diff for these patterns:
|
||||||
|
|
||||||
|
- **Direct publish commands**: `clawhub publish`, `npm publish`,
|
||||||
|
`cargo publish`, `docker push`, `gh release create`, or similar
|
||||||
|
- **Direct deploy commands**: `ssh ... deploy`, `rsync` to external hosts,
|
||||||
|
`kubectl apply`, `helm install`, cloud CLI deploy commands
|
||||||
|
- **Direct external API calls**: `curl`/`wget` to external services with
|
||||||
|
auth tokens, posting to social media APIs, sending emails
|
||||||
|
- **Token usage**: Direct references to `GITHUB_TOKEN`, `CLAWHUB_TOKEN`,
|
||||||
|
or other vault-only secrets in agent code (outside of vault/ directory)
|
||||||
|
|
||||||
|
If ANY of these patterns appear in agent code (scripts in `dev/`, `action/`,
|
||||||
|
`planner/`, `gardener/`, `supervisor/`, `predictor/`, `review/`, `formulas/`,
|
||||||
|
`lib/`) WITHOUT routing through vault dispatch (`vault/pending/`, `vault-fire.sh`,
|
||||||
|
`vault-run-action.sh`), **REQUEST_CHANGES**.
|
||||||
|
|
||||||
|
Explain that external actions must use vault dispatch per AD-006. The agent
|
||||||
|
should file a vault item instead of executing directly.
|
||||||
|
|
||||||
|
**Exceptions** (do NOT flag these):
|
||||||
|
- Code inside `vault/` — the vault system itself is allowed to handle secrets
|
||||||
|
- References in comments or documentation explaining the architecture
|
||||||
|
- `bin/disinto` setup commands that manage `.env.vault.enc`
|
||||||
|
- Local operations (git push to forge, forge API calls with `FORGE_TOKEN`)
|
||||||
|
|
||||||
|
## 6. Re-review (if previous review is provided)
|
||||||
|
|
||||||
If the orchestrator injected a previous review and incremental diff:
|
If the orchestrator injected a previous review and incremental diff:
|
||||||
1. For each finding in the previous review, check if it was addressed
|
1. For each finding in the previous review, check if it was addressed
|
||||||
|
|
@ -118,7 +151,7 @@ If the orchestrator injected a previous review and incremental diff:
|
||||||
Focus on the incremental diff for finding-by-finding status, but use the
|
Focus on the incremental diff for finding-by-finding status, but use the
|
||||||
full diff to check overall correctness.
|
full diff to check overall correctness.
|
||||||
|
|
||||||
## 6. Follow-up issues (pre-existing tech debt)
|
## 7. Follow-up issues (pre-existing tech debt)
|
||||||
|
|
||||||
If you discover pre-existing issues (NOT introduced by this PR), create
|
If you discover pre-existing issues (NOT introduced by this PR), create
|
||||||
tech-debt issues via API so they are tracked separately:
|
tech-debt issues via API so they are tracked separately:
|
||||||
|
|
@ -148,7 +181,7 @@ tech-debt issues via API so they are tracked separately:
|
||||||
Only create follow-ups for clear, actionable tech debt. Do not create
|
Only create follow-ups for clear, actionable tech debt. Do not create
|
||||||
issues for minor style nits or speculative improvements.
|
issues for minor style nits or speculative improvements.
|
||||||
|
|
||||||
## 7. Verdict
|
## 8. Verdict
|
||||||
|
|
||||||
Choose one:
|
Choose one:
|
||||||
- **APPROVE**: Change is correct, complete, and follows conventions
|
- **APPROVE**: Change is correct, complete, and follows conventions
|
||||||
|
|
@ -159,7 +192,7 @@ Bias toward APPROVE for small, correct changes. Use REQUEST_CHANGES only
|
||||||
for actual problems (bugs, security issues, broken functionality, missing
|
for actual problems (bugs, security issues, broken functionality, missing
|
||||||
required behavior). Use DISCUSS sparingly.
|
required behavior). Use DISCUSS sparingly.
|
||||||
|
|
||||||
## 8. Output
|
## 9. Output
|
||||||
|
|
||||||
Write a single JSON object to the file path from REVIEW_OUTPUT_FILE.
|
Write a single JSON object to the file path from REVIEW_OUTPUT_FILE.
|
||||||
Use jq to ensure proper JSON escaping of the markdown content:
|
Use jq to ensure proper JSON escaping of the markdown content:
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,13 @@ export WOODPECKER_REPO_ID="${WOODPECKER_REPO_ID:-}"
|
||||||
export WOODPECKER_SERVER="${WOODPECKER_SERVER:-http://localhost:8000}"
|
export WOODPECKER_SERVER="${WOODPECKER_SERVER:-http://localhost:8000}"
|
||||||
export CLAUDE_TIMEOUT="${CLAUDE_TIMEOUT:-7200}"
|
export CLAUDE_TIMEOUT="${CLAUDE_TIMEOUT:-7200}"
|
||||||
|
|
||||||
|
# Vault-only token guard (#745): external-action tokens (GITHUB_TOKEN, CLAWHUB_TOKEN)
|
||||||
|
# must NEVER be available to agents. They live in .env.vault.enc and are injected
|
||||||
|
# only into the ephemeral vault-runner container at fire time. Unset them here so
|
||||||
|
# even an accidental .env inclusion cannot leak them into agent sessions.
|
||||||
|
unset GITHUB_TOKEN 2>/dev/null || true
|
||||||
|
unset CLAWHUB_TOKEN 2>/dev/null || true
|
||||||
|
|
||||||
# Disable Claude Code auto-updater, telemetry, error reporting in factory sessions.
|
# Disable Claude Code auto-updater, telemetry, error reporting in factory sessions.
|
||||||
# Factory processes must never phone home or auto-update mid-session (#725).
|
# Factory processes must never phone home or auto-update mid-session (#725).
|
||||||
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
|
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue