Domain Enforcement
Structural file and tool permission boundaries per agent
Adding Domain Rules
Domain enforcement provides structural, code-enforced file and tool permission boundaries per agent. These are not advisory prompts or instructions written into a system prompt — they are real constraints evaluated at the adapter layer that block tool calls before execution ever begins. An agent cannot read, write, or delete a file outside its allowed paths, and cannot invoke a tool that is not permitted for its role.
Add a domain field to agent.yaml to declare what the agent is allowed to touch:
domain:
rules:
- path: "src/api/**" # Glob pattern matched against the requested file path
read: true
write: true
delete: false
- path: "src/config/**"
read: true
write: false # Config is read-only for this agent
delete: false
- path: "**/*.env*"
read: false # Environment files completely blocked
write: false
delete: false
tool_allowlist: # Only these tools are available to this agent
- read
- write
- edit
- grep
- glob
tool_denylist: # Blocked even if the tool appears in the allowlist
- bash
bash_restrictions: # If bash IS allowed, these command patterns are blocked
blocked_tokens:
- tokens: ["rm", "recursive"]
aliases: { recursive: ["-r", "-R", "--recursive"] }
- tokens: ["git", "push"]
- tokens: ["git", "reset"]
blocked_patterns: ["curl.*-X DELETE"]
Rules are evaluated in specificity order (see Path Matching Algorithm below). Each rule grants or denies read, write, and delete independently. A path that matches no rule is denied by default.
Path Matching Algorithm
Rules are matched using glob patterns. When a file operation is requested, every rule whose pattern matches the target path is collected. The winner is determined by specificity — the number of literal path segments in the pattern (segments without wildcards).
apps/web/**has specificity 2 (apps,web)apps/web/components/**has specificity 3 (apps,web,components)
When two rules match the same path, the more specific rule wins. If two matching rules have equal specificity and one denies, the deny wins.
| Request | Matching Rules | Winner | Outcome |
|---|---|---|---|
Write apps/web/components/Button.tsx | apps/web/** (specificity 2, allows write), apps/web/components/** (specificity 3, denies write) | specificity 3 | Denied |
Write apps/web/page.tsx | apps/web/** (specificity 2, allows write) | specificity 2 | Allowed |
Important
Paths that match no rule are denied by default. Always add an explicit rule for every path the agent legitimately needs to access.
Tool Access Control
The tool_allowlist and tool_denylist fields control which tools an agent can invoke:
- If neither is defined, all tools are permitted.
- If
tool_allowlistis defined, only the listed tools are permitted. Any tool not in the list is blocked. - If
tool_denylistis defined, the listed tools are always blocked — even if they appear in the allowlist. The denylist takes precedence.
This means you can define a broad allowlist and use the denylist to carve out specific exceptions without rewriting the full list.
Bash Restrictions
When bash is included in the allowlist, the bash_restrictions field adds a layer of command-level filtering.
Token-Based Detection
blocked_tokens rules define sets of tokens that must not appear together in a single command. Detection is order-independent: the runtime expands aliases and checks for co-occurrence of the full token set anywhere in the command string.
For example, a rule with tokens: ["rm", "recursive"] and aliases: { recursive: ["-r", "-R", "--recursive"] } will block:
rm -rf /tmp/buildrm -r -f /tmp/buildrm --recursive --force /tmp/build
All three trigger the same rule because the alias expansion maps -r, -R, and --recursive to the recursive token. The match fires as soon as all tokens in the set are present, regardless of order or flags interleaved between them.
Pattern-Based Detection
blocked_patterns are evaluated as regular expressions against the full command string. These are useful for blocking constructs that cannot be expressed cleanly as token sets:
blocked_patterns: ["curl.*-X DELETE"] Patterns are checked after token expansion, as a fallback for command shapes that are difficult to enumerate with discrete tokens.
Safety Scope
Note
Bash restrictions are a heuristic safety net — they raise the cost of accidental or unintended dangerous commands. They are not a security sandbox. A determined agent with bash access can still construct commands that avoid matching. Use tool_denylist: [bash] to fully remove bash access when it is not needed.
Profile-Level Overrides
A profile can override an agent's domain rules for a specific assembly context using domain_override. This is useful when the same agent participates in both restricted operational contexts and broader exploratory profiles:
assembly:
perspectives:
- agent: architect
domain_override:
rules:
- path: "**"
read: true
write: true # Full access in this profile context domain_override replaces the agent's domain.rules entirely for that profile assembly. Tool allowlists and denylists from the base agent definition remain in effect unless also overridden.
Domain Inheritance
When an agent spawns child agents (in nested orchestration), children inherit the parent's domain as a ceiling. Permissions are ANDed — a child can only have permissions that the parent also has.
If the parent domain allows src/** → write: true and a child agent is configured with src/** → delete: true, the delete permission is silently denied at runtime because the parent does not grant delete on that path.
Key Rule
This ensures that a child agent cannot escalate its own privileges beyond what the spawning agent was allowed to do. The parent's domain acts as the upper bound; the child's domain can be equal to or more restrictive, never more permissive.
Troubleshooting
no matching rule for path "X"
The file path did not match any rule in the agent's domain configuration. Domain enforcement is deny-by-default — unmatched paths are blocked. Add an explicit rule covering the path:
rules:
- path: "src/generated/**"
read: true
write: true
delete: false tool "X" is in denylist
The tool is explicitly blocked via tool_denylist. Either remove it from the denylist, or use a different tool that achieves the same goal. If bash is the blocked tool, consider whether read, grep, or glob can replace the specific command needed.
tool "X" is not in allowlist
A tool_allowlist is defined for this agent and the requested tool is not included. Add the tool to the allowlist:
tool_allowlist:
- read
- grep
- glob
- bash # Add the missing tool here bash command matches blocked token set: [X, Y]
The command contains a combination of tokens (after alias expansion) that matches a blocked_tokens rule. Review the command to determine whether it is genuinely needed. If it is, and the restriction is overly broad, adjust the bash_restrictions configuration in the agent's domain definition or use a more targeted blocked_patterns entry instead.