Bound fields
A bound is the object that restricts a session. It takes away tools, write access, file paths, shell commands, network destinations, and nodes from what the session’s traits grant, and it never grants anything. This page lists every key the bound schema accepts. For how patterns match, how Barry enforces each rule, and how bounds merge, see Bounds.
You write the same object in several places:
identity.yaml,bound:: an inline bound that applies to every session the identity starts.identity.yaml,bounds:: a list of named bounds, each a one-name mapping whose fields sit besidedescriptionandoptional. The mapping key is the name, so the entry has nonamefield. See the builtin bounds in Barry’sidentity.yaml.bag.yaml, top-levelbounds:: a map from bound name to a definition with adescriptionand abound:object.bag.yaml, a trait’sbound:: an inline bound that the trait carries.- Named bounds: a bound with its
nameat the same level as its rules.barry bound listshows every named bound and what it restricts.
The schema is BoundSchema in
sdk/src/bounds/types.ts.
It rejects unknown keys at every level, so a misspelled key fails instead of
denying nothing. Every key is optional, and a bound with no rules restricts
nothing.
Overview
Section titled “Overview”Every key bound accepts, with its type. Each key has its own section under Fields.
name: stringdescription: stringnodes: object allow: list of strings deny: list of stringsnativeTools: map of harness ID to list of stringsdeniedTools: list of stringsdeniedAccess: list of stringsfiles: object deny: list of strings allowOnly: list of stringsbash: object deny: list of strings denyPrograms: list of stringsnetwork: object actions: list of strings domains: list of strings allowDomains: list of strings enforce: stringFields
Section titled “Fields”- Type:
string - Required: no
The bound’s name, at least one character. A named bound carries it, and
sessions, traits, and identities select the bound by it. Merging drops it,
so it never restricts anything. An entry under bounds: in
identity.yaml takes its name from the mapping key and rejects this field.
name: no-secretsdescription
Section titled “description”- Type:
string - Required: no
What the bound restricts, in a sentence. barry bound list prints it.
Merging drops it. An entry under bounds: in identity.yaml requires it,
and a bag.yaml bound definition takes it beside bound: instead.
description: "Denies writes, Bash, and recognized network writes"- Type:
object - Required: no
Which installations may run the work: this one, as local or by its
installation ID, and the workers it invited. Barry refuses a tool call on
a node that deny names, or on a node missing from allow when allow
is present. See
Distributed nodes.
nodes: allow: [local]nodes.allow
Section titled “nodes.allow”- Type:
list of strings - Required: no
The only nodes that may run the work. Each entry is a non-empty node ID. An empty list permits no node. Merging intersects this list with the other sources’ lists.
nodes: allow: [local]nodes.deny
Section titled “nodes.deny”- Type:
list of strings - Required: no
Nodes that may not run the work. Each entry is a non-empty node ID.
Merging unions this list with the other sources’ lists, and deny
wins over allow.
nodes: deny: [build-box]nativeTools
Section titled “nativeTools”- Type:
map of harness ID to list of strings - Required: no
The agent harness’s own tools to take back. Each key is a harness ID, and each list names tools as the harness names them. Barry rejects a name the harness does not offer. It applies only to native tools, never to the tools Barry serves. See enforcement coverage.
nativeTools: claude-code: [WebFetch, WebSearch]deniedTools
Section titled “deniedTools”- Type:
list of strings - Required: no
Tools to remove. Each entry is a namespace or a tool name, matched without
regard to case, and a match removes the tool from the session’s tool list.
Some names also take back a category of native tools, such as Bash for
the native shell.
deniedTools: [Bash, Write, Edit]deniedAccess
Section titled “deniedAccess”- Type:
list of strings - Required: no
Write access to remove. write removes every write tool. A namespace or a
tool name, matched exactly, removes the write tools it names. Read tools
stay. write also takes back the native shell and native file writes.
deniedAccess: [write]- Type:
object - Required: no
Path restrictions, checked on the path fields of Barry’s file tools.
A non-empty deny or any allowOnly removes Barry’s Bash, and either
key takes back the native shell, file reads, and file writes. See
patterns.
files: deny: ["*.env", "~/.ssh/**"]files.deny
Section titled “files.deny”- Type:
list of strings - Required: no
Path patterns to deny. Barry checks both the path as written and its absolute form, and refuses a path that matches any pattern. Merging unions the lists.
files: deny: ["*.env", "*.pem"]files.allowOnly
Section titled “files.allowOnly”- Type:
list of strings - Required: no
The only paths the session may reach. Barry refuses every path that
matches none of the patterns, and deny wins when a path matches
both. Each entry starts with /, ~/, a drive letter, or \\, or
equals ~; the schema rejects relative paths. An empty list permits
no path, and merging intersects the lists.
files: allowOnly: ["~/repos/vantage/**"]- Type:
object - Required: no
Shell command restrictions, checked on Barry’s Bash tool. A non-empty
list in either key takes back the native shell.
bash: denyPrograms: [git, gh]bash.deny
Section titled “bash.deny”- Type:
list of strings - Required: no
Deprecated. Barry refuses a command that contains any entry as a
substring, which misses git -C and matches legit. Use
denyPrograms instead.
bash: deny: ["rm -rf"]bash.denyPrograms
Section titled “bash.denyPrograms”- Type:
list of strings - Required: no
Programs to deny, as program or program:subcommand. Barry matches
every command in the line, through wrappers such as env, sudo,
and sh -c, and refuses a command it cannot parse.
bash: denyPrograms: [git, "gh:pr:create"]network
Section titled “network”- Type:
object - Required: no
Network restrictions. Any rule in it takes back the native shell and
native network tools. Barry rejects a network object that sets
allowDomains without enforce: sandbox.
network: actions: [write]network.actions
Section titled “network.actions”- Type:
list of strings - Required: no
- Values:
all,write,read,git:push,git:fetch,http:write,http:read,ssh:write,ssh:read,dns
Network operations to deny. A parent tag denies its children, so
write covers git:push, http:write, and ssh:write. The schema
rejects an unknown tag. See
network actions.
network: actions: ["git:push"]network.domains
Section titled “network.domains”- Type:
list of strings - Required: no
Destination hosts to deny. An entry matches the host and every
subdomain. Barry reads URLs from Bash commands and from WebFetch,
and misses URLs built at runtime.
network: domains: ["*.internal.example.com"]network.allowDomains
Section titled “network.allowDomains”- Type:
list of strings - Required: no
The only hosts the egress sandbox lets through. It requires
enforce: sandbox. Under the sandbox, an absent list means no egress
except to localhost, and a host in domains stays denied. Merging
intersects the lists.
network: enforce: sandbox allowDomains: [registry.npmjs.org]network.enforce
Section titled “network.enforce”- Type:
string - Required: no
- Values:
guard,sandbox
The enforcement level. An absent value means guard: Barry checks
tool calls and shell commands. sandbox adds the agent runtime’s
egress proxy, and a hosted session that cannot get the sandbox refuses
to start. sandbox wins when bounds merge. See
enforcement levels.
network: enforce: sandboxExamples
Section titled “Examples”Read-only
Section titled “Read-only”Barry’s builtin readonly bound: no shell, no write tools, and no
recognized network writes.
name: readonlydescription: "Denies supported write tools, Bash, and recognized network writes"deniedTools: [Bash, Write, Edit]deniedAccess: [write]network: actions: [write]Offline sandbox
Section titled “Offline sandbox”Denies every recognized network operation, and asks for the egress sandbox with an empty allowlist.
name: sandboxed-offlinedescription: "Requests proxy enforcement on supported harnesses"network: actions: [all] enforce: sandbox allowDomains: []One repository, no secrets
Section titled “One repository, no secrets”Confines file tools to one repository and denies its secret files, even inside it.
name: vantage-onlydescription: "File tools reach only the vantage repository, never its secrets"files: allowOnly: ["~/repos/vantage/**"] deny: ["*.env", ".env.*", "*.pem", "*.key"]