Both agent steps hold Gitea write credentials in their environment (issue-fix holds a push token too), but neither passed --settings, so their Read tool was unrestricted — unlike update-audit, which got a Read sandbox for exactly this reason (gitea issue #197). That left a complete exfil path: Read /proc/self/environ yields the token, Write puts it in the agent's output file, and the pipeline posts that output verbatim as a Gitea issue body / PR body on a PUBLIC repo. Add the same deny-list used by update-audit (/proc, /root, /home, /etc, .git) to both agents and wire --settings into each invocation. The repo checkout, .ci-alert-monitor/ and /tmp/alert-fix/ stay readable, which is all either agent needs. This is defense-in-depth only. The root cause — CI pipelines holding an admin-owned token at all — is tracked separately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
29 lines
1.5 KiB
JSON
29 lines
1.5 KiB
JSON
{
|
|
"//": "Read sandbox for the issue-fix agent. This step's environment holds BOTH",
|
|
"//2": "a Gitea issue-write token and a repo push token, so the agent's Read tool",
|
|
"//3": "is denied access to anything that could hold credentials: the container's",
|
|
"//4": "/proc (env var dumps via /proc/self/environ), /root and /home (SSH keys,",
|
|
"//5": ".netrc, git-credential stores), /etc, and the repo's own .git/ (which can",
|
|
"//6": "carry an embedded clone token). The repo checkout itself stays readable",
|
|
"//7": "and writable — this agent's job is to edit ansible/, opentofu/,",
|
|
"//8": "kubernetes/ and ci/images/ — as does /tmp/alert-fix/ (the issue body it",
|
|
"//9": "is asked to fix).",
|
|
"//10": "Matters here because the agent's edits are pushed to a branch and its",
|
|
"//11": "summary is posted as a PR body / issue comment on a PUBLIC repo, so an",
|
|
"//12": "unsandboxed Read gives a prompt-injected instruction a read-then-publish",
|
|
"//13": "exfil path. Denying .git/ also keeps the agent away from the push",
|
|
"//14": "credential the pipeline's own git commands use.",
|
|
"//15": "Mirrors ci/agents/update-audit/settings.json; see gitea issue #197.",
|
|
"//16": "Verified empirically against Claude Code 2.1.207: relative deny globs",
|
|
"//17": "anchor to the pipeline's cwd (repo root), not this file's directory.",
|
|
"permissions": {
|
|
"deny": [
|
|
"Read(//proc/**)",
|
|
"Read(//root/**)",
|
|
"Read(//home/**)",
|
|
"Read(//etc/**)",
|
|
"Read(.git/**)"
|
|
]
|
|
}
|
|
}
|