Skip to content

sandbox filesystem.allowWrite grants tool permissions instead of restricting writes (contradicts schema description) #54626

Description

@norrietaylor

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:

  1. 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.

  2. 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.goappendSandboxWritableTools 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions