Boundlane Sheet D-201 / Policy file

D-201 Use

Policy file

A short file says what the agent may touch. Boundlane compiles it into the sandbox's own policy format and checks the result before anything starts.

File: boundlane.yamlSchema version 1

Where the policy comes from

PlanPolicy used
FreeThe built-in developer-default, plus boundlane.yaml in the project root if there is one.
TeamThe policy your security lead published, delivered as a signed file. A project file is not used. See Publish and revisions.

You do not need to learn the sandbox's policy language. You also cannot write something in this file that the sandbox cannot enforce. Fields that would need that are left out.

The default policy

This is developer-default. The project folder is writable. Three package registries and the GitHub API are readable. Everything else is closed. The full picture, including what each agent adds, is on Default access.

developer-default
version: 1
name: developer-default
agents: [claude, codex, grok, opencode]
workspace: read-write
hosts:
  - host: api.github.com
    access: read-only
  - host: registry.npmjs.org
    access: read-only
  - host: pypi.org
    access: read-only
  - host: files.pythonhosted.org
    access: read-only
approvals: person

The model API is not listed. Each agent's key comes with the endpoints it is allowed to reach, so the key and its destination stay together. See Keys and tokens.

Adding hosts for a project

Run boundlane init to create a boundlane.yaml in the project root, then add what this project needs.

boundlane.yaml
version: 1
hosts:
  - host: api.stripe.com
    access: read-only
  - host: api.github.com
    access: read-write
    allow:
      - GET /repos/acme/web/**
      - POST /repos/acme/web/pulls
paths:
  read_only: [/opt/fixtures]

Hosts merge with the default. A host listed in both uses the access level from the project file. Commit the file so everyone on the project runs with the same rules.

Wall: paths need a new sandbox

Changing paths or workspace takes effect the next time a sandbox is created. Changing hosts can apply to a running sandbox.

Fields

FieldValuesNotes
version1Required.
nameTextShown in the log and on Team.
agentsAgent namesWhich agents may run under this policy. See Agents.
workspaceread-write, read-onlyAccess to the project copy. Default read-write.
paths.read_onlyAbsolute pathsExtra paths inside the sandbox the agent may read. Paths under a home directory are rejected.
paths.read_writeAbsolute pathsExtra writable paths. / is rejected.
hosts[].hostExact host nameWildcards are not accepted.
hosts[].portNumberDefault 443.
hosts[].accessread-only, read-writeSee Host access.
hosts[].allowMETHOD /pathRequired with read-write. Each line is one allowed request shape.
approvalspersonThe only value. There is no setting for automatic approval.

Host access

read-only allows GET, HEAD, and OPTIONS, and blocks everything else. It is a rule about HTTP methods. It does not promise that a server's GET has no side effects.

read-write allows only the requests you list under allow. In a path, * matches within one segment and ** matches across segments. So /repos/acme/web/** covers everything under the repository, but not /repos/acme/web itself.

There is no level that allows every method on a host. If you need it, list the requests.

Every rule is enforced. The sandbox's own default for request rules is to log violations and let them through. Boundlane always sets it to block.

Package registries

  • npm. Scoped packages such as @types/node are requested with an encoded slash in the path. The read-only level already allows it. npm audit sends a POST, which read-only blocks, so agent images turn audit off. Run npm audit outside the sandbox.
  • pip. Packages download from files.pythonhosted.org, not only pypi.org. The default lists both.

What it compiles to

See the compiled policy without starting anything:

boundlane policy compile
Compiled OpenShell policy, excerpt
version: 1
filesystem_policy:
  include_workdir: false
  read_only: [/bin, /usr, /lib, /etc, /app, /var/log, /proc, /dev/urandom]
  read_write: [/sandbox, /tmp, /dev/null]   # /sandbox is the working folder
landlock:
  compatibility: hard_requirement
process:
  run_as_user: sandbox
  run_as_group: sandbox
network_policies:
  pypi_org:
    name: pypi.org
    endpoints:
      - host: pypi.org
        port: 443
        protocol: rest
        enforcement: enforce
        access: read-only
    binaries:
      - path: <agent binary>   # real path, from the agent catalog

A few choices are worth knowing:

  • hard_requirement means the sandbox does not start if the kernel cannot enforce the filesystem rules. The upstream default would start it anyway and log a warning.
  • The working folder is listed by path instead of with include_workdir, so the check below can reason about it.
  • Each host gets its own rule, and the rule names the real path of the agent. Programs the agent starts, such as pip or npm, use the agent's rules.
  • The user setting applies on Docker and Podman. Under the MicroVM driver, the sandbox runs as the user the driver configures.

The check before start

Before a sandbox starts, Boundlane runs OpenShell's policy prover. It compares the compiled policy, including access that agent keys add, against a boundary. If any action is possible that the boundary does not allow, the prover names it and nothing starts.

boundlane policy check
Example output, failing
! Policy check      exceeds_boundary
  Checked developer-default (built in) + boundlane.yaml for Claude Code.
  Example  claude can POST to api.github.com:443 /repos/acme/infra/hooks

To fix it, narrow the allow lines for that host, or ask whoever owns the boundary to include it. The command exits with code 2 until the result is within_boundary.

ResultMeaningStarts?
within_boundaryNothing the policy allows is outside the boundary.Yes
exceeds_boundaryThe prover found an action outside it, and shows one.No
unsupportedThe policy has a rule type the prover does not model.No
inconclusiveThe prover could not decide.No
errorA file could not be read or parsed.No

On Free, the boundary is compiled from the same file. The check then catches access that keys and their profiles add on top of what you wrote. On Team, the security lead publishes the boundary, and project files cannot go past it.

After the sandbox is created, Boundlane runs the check a second time on the policy the sandbox actually holds. If that fails, the sandbox is deleted before the agent starts.

Outside this file

The prover returns unsupported for GraphQL, MCP, WebSocket, and JSON-RPC rules. Raw TCP and TLS passthrough cannot be checked at the request level. The policy file has no fields for them.

An agent cannot use GitHub's GraphQL API, an MCP server over the network, or a database connection inside the sandbox through this file. Outbound MCP on the sandbox's network path is still inspected. A rule for the MCP payload is not.

Pinning a host to an address range is not in the file. A listed host name that resolves to a private address can reach that address, so list internal hosts with care.