Skip to content

Commit f50e8f8

Browse files
committed
fix(scaffold): allow claude.exe and pi on the Vertex profile
Claude Code 2.1.2xx ships as a Bun-compiled binary named claude.exe even on Linux, and since #6647 the CLAUDE_CODE_VERSION-pinned install is the binary that runs in the sandbox. The scaffold Vertex profile only allowlisted **/claude, so OpenShell's OPA denied claude.exe the STS call and every Claude run on the 0.40.0 image failed on its first request with "API Error: Error code policy_denied" (0 tokens). The fleet copy in fullsend-ai/agents was fixed by fullsend-ai/agents#1118; this repo's embedded copy, which functional-tests and local runs load through --fullsend-dir, was not. Add **/claude.exe and **/pi so the binaries list matches the agents copy (**/pi is carried for parity with that copy; pi itself runs via node), pin the whole list in a scaffold test so the two copies cannot drift on this again, and update the bring-your-own-agent guide and the runtime egress diagram that still showed the old list. Refs #6971 Assisted-by: Claude (code, fix, review), Grok (review) Signed-off-by: Wayne Sun <gsun@redhat.com>
1 parent 48eac1a commit f50e8f8

4 files changed

Lines changed: 25 additions & 1 deletion

File tree

‎docs/contributing/runtime-implementation.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ flowchart TB
5555
end
5656
subgraph SB["Sandbox boundary — OpenShell + L7 egress policy (containment)"]
5757
direction TB
58-
EG["egress allowlist: *.googleapis.com · api.anthropic.com\n(+ api.openai.com POST /v1/responses with the openai provider)\nbinaries: **/claude · **/node (pi runs via node) · **/codex"]
58+
EG["egress allowlist: *.googleapis.com · api.anthropic.com\n(+ api.openai.com POST /v1/responses with the openai provider)\nbinaries: **/claude · **/claude.exe · **/node (pi runs via node) · **/pi · **/codex"]
5959
subgraph PROC["Runtime process — steering, defense in depth"]
6060
direction LR
6161
PRE["PreToolUse\nTirith · SSRF\ncanary · allowlist"]

‎docs/guides/user/bring-your-own-agent.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,13 @@ endpoints:
132132
enforcement: enforce
133133
binaries:
134134
- "**/claude"
135+
- "**/claude.exe"
135136
- "**/node"
137+
- "**/pi"
136138
```
137139

140+
> Claude Code 2.1.2xx installs its native binary at `bin/claude.exe` even on Linux, so the allowlist needs both `**/claude` and `**/claude.exe`; with only the former the run fails on its first call with `API Error: Error code policy_denied`.
141+
138142
> **Note (CI only):** the provider profile above controls network access only; real credentials are delivered via `host_files` (see [real-world example](#real-world-example-the-triage-agent)). Make sure you've completed the GCP prerequisites in [Before you begin](#before-you-begin).
139143

140144
**`agents/my-agent.md`:**

‎internal/scaffold/fullsend-repo/profiles/fullsend-vertex-ai.yaml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ endpoints:
2020
allow_uninspected_credentials: true
2121
binaries:
2222
- "**/claude"
23+
- "**/claude.exe"
2324
- "**/node"
25+
- "**/pi"

‎internal/scaffold/scaffold_test.go‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,3 +1022,21 @@ func TestPrependManagedHeaderNoHeader(t *testing.T) {
10221022
result := PrependManagedHeader("AGENTS.md", content)
10231023
assert.Equal(t, content, result, "files without headers should be returned unchanged")
10241024
}
1025+
1026+
func TestScaffoldVertexProfile_BinaryAllowlist(t *testing.T) {
1027+
data, err := FullsendRepoFile("profiles/fullsend-vertex-ai.yaml")
1028+
require.NoError(t, err)
1029+
1030+
var profile struct {
1031+
Binaries []string `yaml:"binaries"`
1032+
}
1033+
require.NoError(t, yaml.Unmarshal(data, &profile))
1034+
1035+
// Pin the whole list, not just the two entries #6971 added: this copy
1036+
// must stay in sync with profiles/fullsend-vertex-ai.yaml in
1037+
// fullsend-ai/agents (the fleet copy), which is what the sandbox
1038+
// actually enforces. Claude Code 2.1.2xx installs its native binary at
1039+
// bin/claude.exe even on Linux, so **/claude alone denies it STS access.
1040+
assert.ElementsMatch(t, []string{"**/claude", "**/claude.exe", "**/node", "**/pi"}, profile.Binaries,
1041+
"scaffold Vertex profile binaries drifted from the fullsend-ai/agents copy")
1042+
}

0 commit comments

Comments
 (0)