Version
gh-aw v0.77.5 (also present on main as of b07b62e4a9), firewall image 0.25.58.
Summary
sandbox.agent.config.filesystem.allowWrite is documented as a restriction but implemented as a permission grant. A workflow author following the schema description will believe they have added a write boundary while having actually widened the agent's tool permissions.
What the schema says
pkg/parser/schemas/main_workflow_schema.json:
allowWrite — "Array of path patterns that allow write access in the sandboxed environment. Paths outside these patterns are read-only."
What actually happens
Adding this to a workflow that already has a network: block (so the AWF sandbox is auto-enabled):
sandbox:
agent:
config:
filesystem:
allowWrite:
- /home/runner/work
- /tmp
compiles cleanly (0 errors) and produces:
-
No filesystem section in the generated awf-config.json. The runtime config still contains only network, apiProxy and container. Confirmed by reading awf-config.json from a real run's agent artifact both before and after.
-
Four additional allowed tools. The only functional change in the compiled lock:
+ # - Edit(/home/runner/work/*)
+ # - MultiEdit(/home/runner/work/*)
+ # - Read(/home/runner/work/*)
+ # - Write(/home/runner/work/*)
Tracing it, pkg/workflow/claude_tools.go → appendSandboxWritableTools consumes AllowWrite solely to append Read(p) / Write(p) / Edit(p) / MultiEdit(p) to the agent's allowed-tools list. Nothing outside the list is denied anywhere.
Why this is worse than a no-op
For the Claude engine the compiled allowed-tools already contain unqualified grants:
Edit
MultiEdit
Read
Write
An unqualified Write permits writing anywhere the process can reach, so path-scoped Write(...) entries cannot narrow it — they are strictly additive. The net effect of following the documentation is a permission set that is the same or broader, presented in the diff as hardening.
Expected
Either:
- Implement the documented behaviour — emit
filesystem into awf-config.json so the AWF sandbox enforces the boundary in-kernel (strongest, and what the description implies), or
- Correct the schema description to say
allowWrite grants path-scoped tool permissions and does not restrict anything, so authors do not mistake it for a boundary.
How we found it
We ran it as a deliberate one-workflow canary before fleet rollout, and inspected the compiled lock and the runtime awf-config.json rather than trusting the compile succeeding. Had we merged on the green compile, we would have shipped a change that reads as a write boundary in review and loosens permissions in fact.
Happy to supply the full before/after lock diff if useful.
Version
gh-aw
v0.77.5(also present onmainas ofb07b62e4a9), firewall image0.25.58.Summary
sandbox.agent.config.filesystem.allowWriteis documented as a restriction but implemented as a permission grant. A workflow author following the schema description will believe they have added a write boundary while having actually widened the agent's tool permissions.What the schema says
pkg/parser/schemas/main_workflow_schema.json:What actually happens
Adding this to a workflow that already has a
network:block (so the AWF sandbox is auto-enabled):compiles cleanly (0 errors) and produces:
No
filesystemsection in the generatedawf-config.json. The runtime config still contains onlynetwork,apiProxyandcontainer. Confirmed by readingawf-config.jsonfrom a real run'sagentartifact both before and after.Four additional allowed tools. The only functional change in the compiled lock:
Tracing it,
pkg/workflow/claude_tools.go→appendSandboxWritableToolsconsumesAllowWritesolely to appendRead(p)/Write(p)/Edit(p)/MultiEdit(p)to the agent's allowed-tools list. Nothing outside the list is denied anywhere.Why this is worse than a no-op
For the Claude engine the compiled allowed-tools already contain unqualified grants:
An unqualified
Writepermits writing anywhere the process can reach, so path-scopedWrite(...)entries cannot narrow it — they are strictly additive. The net effect of following the documentation is a permission set that is the same or broader, presented in the diff as hardening.Expected
Either:
filesystemintoawf-config.jsonso the AWF sandbox enforces the boundary in-kernel (strongest, and what the description implies), orallowWritegrants path-scoped tool permissions and does not restrict anything, so authors do not mistake it for a boundary.How we found it
We ran it as a deliberate one-workflow canary before fleet rollout, and inspected the compiled lock and the runtime
awf-config.jsonrather than trusting the compile succeeding. Had we merged on the green compile, we would have shipped a change that reads as a write boundary in review and loosens permissions in fact.Happy to supply the full before/after lock diff if useful.