使用 declarative permission rules 控制 agent 可以 read 或 write 哪些 files 和 directories。将 rules list 传给 permissions= 后,agent 的 built-in filesystem tools 会遵守这些规则。
Permissions 需要 deepagents>=0.5.2。
Permissions 只适用于 built-in filesystem tools(ls、read_file、glob、grep、write_file、edit_file)。访问 filesystem 的 custom tools 和 MCP tools 不在覆盖范围内。Permissions 也不适用于 sandbox backends,后者通过 execute tool 支持任意 command execution。
当你需要对 built-in filesystem tools 设置 path-based allow/deny rules 时,请使用 permissions。当你需要 custom validation logic(rate limiting、audit logging、content inspection),或需要控制 custom tools 时,请使用 backend policy hooks。
Basic usage
将 FilesystemPermission rules list 传给 create_deep_agent。Rules 按 declaration order 求值。第一条匹配的 rule 生效。如果没有 rule 匹配,则允许 operation。
from deepagents import FilesystemPermission, create_deep_agent
# Read-only agent: deny all writes
agent = create_deep_agent(
model=model,
backend=backend,
permissions=[
FilesystemPermission(
operations=["write"],
paths=["/**"],
mode="deny",
),
],
)
Rule structure
每个 FilesystemPermission 都有三个 fields:
| Field | Type | Description |
|---|
operations | list["read" | "write"] | 该 rule 适用的 operations。"read" 覆盖 ls、read_file、glob、grep。"write" 覆盖 write_file、edit_file。 |
paths | list[str] | 用于匹配 file paths 的 glob patterns(例如 ["/workspace/**"])。支持 ** recursive matching 和 {a,b} alternation。 |
mode | "allow" | "deny" | "interrupt" | 匹配 operations 时是允许、拒绝,还是暂停等待 human approval。默认值为 "allow"。请参阅 Pause for human approval。 |
Rules 使用 first-match-wins evaluation:第一条 operations 和 paths 与当前 call 匹配的 rule 会决定结果。如果没有 rule 匹配,则 call 会被 allowed(permissive default)。
Pause for human approval
"interrupt" mode 需要 deepagents>=0.6.8。
设置 mode="interrupt",即可在匹配 operation 时暂停等待 human approval,而不是直接允许或拒绝。当 agent 在匹配 interrupt-mode rule 的 path 上调用 built-in write tool(write_file、edit_file)时,create_deep_agent 会发出 human-in-the-loop interrupt,而不是运行 tool,reviewer 可以 approve、edit 或 reject 该 call。
from deepagents import FilesystemPermission, create_deep_agent
from langgraph.checkpoint.memory import InMemorySaver
agent = create_deep_agent(
model=model,
permissions=[
# Pause for approval before writing anything under /secrets.
FilesystemPermission(
operations=["write"],
paths=["/secrets/**"],
mode="interrupt",
),
],
# Interrupt mode requires a checkpointer to pause and resume.
checkpointer=InMemorySaver(),
)
Interrupt-mode rules 会自动连接到 agent 的 human-in-the-loop middleware,并与你传入的任何 interrupt_on 合并,因此你可以用与 tool-call interrupts 相同的方式处理和 resume。Resume flow 请参阅 Human-in-the-loop。
使用 literal leading segment 锚定 interrupt patterns(例如 /secrets/** 或 /projects/*/secrets/**)。Bulk tools(ls、glob、grep)会在其 search subtree 可能与 rule 的 anchored prefix 重叠时触发 interrupt,因此像 /**/secrets 这样完全 unanchored 的 pattern 会保守地过度触发。
Examples
Isolate to a workspace directory
只允许在 /workspace/ 下 read 和 write,并拒绝其他所有内容:
agent = create_deep_agent(
model=model,
backend=backend,
permissions=[
FilesystemPermission(
operations=["read", "write"],
paths=["/workspace/**"],
mode="allow",
),
FilesystemPermission(
operations=["read", "write"],
paths=["/**"],
mode="deny",
),
],
)
Protect specific files
agent = create_deep_agent(
model=model,
backend=backend,
permissions=[
FilesystemPermission(
operations=["read", "write"],
paths=["/workspace/.env", "/workspace/examples/**"],
mode="deny",
),
FilesystemPermission(
operations=["read", "write"],
paths=["/workspace/**"],
mode="allow",
),
FilesystemPermission(
operations=["read", "write"],
paths=["/**"],
mode="deny",
),
],
)
Read-only memory
允许 agent read memory files,但阻止其修改这些 files。这适用于 organization-wide policies 或只应由 application code 更新的 shared knowledge bases。更多 context 请参阅 read-only vs writable memory。
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
agent = create_deep_agent(
model=model,
backend=CompositeBackend(
default=StateBackend(),
routes={
"/memories/": StoreBackend(
namespace=lambda rt: (rt.server_info.user.identity,),
),
"/policies/": StoreBackend(
namespace=lambda rt: (rt.context.org_id,),
),
},
),
permissions=[
FilesystemPermission(
operations=["write"],
paths=["/memories/**", "/policies/**"],
mode="deny",
),
],
)
Deny all access
阻止所有 reads 和 writes。这是一个 restrictive baseline,你可以在其上叠加更具体的 allow rules:
agent = create_deep_agent(
model=model,
backend=backend,
permissions=[
FilesystemPermission(
operations=["read", "write"],
paths=["/**"],
mode="deny",
),
],
)
Rule ordering
由于 first-match-wins,rule order 很重要。请将更 specific 的 rules 放在更 broad 的 rules 前:
# Correct: deny .env, allow workspace, deny everything else
correct_permissions = [
FilesystemPermission(
operations=["read", "write"],
paths=["/workspace/.env"],
mode="deny",
),
FilesystemPermission(
operations=["read", "write"],
paths=["/workspace/**"],
mode="allow",
),
FilesystemPermission(
operations=["read", "write"],
paths=["/**"],
mode="deny",
),
]
# Bug: /workspace/** matches .env first, so the deny never triggers
incorrect_permissions = [
FilesystemPermission(
operations=["read", "write"],
paths=["/workspace/**"],
mode="allow",
),
FilesystemPermission(
operations=["read", "write"],
paths=["/workspace/.env"],
mode="deny", # never reached
),
FilesystemPermission(
operations=["read", "write"],
paths=["/**"],
mode="deny",
),
]
Subagent permissions
Subagents 默认继承 parent agent 的 permissions。若要为 subagent 提供不同 permissions,请在其 spec 中设置 permissions field。这会完全 replace parent 的 rules。
agent = create_deep_agent(
model=model,
backend=backend,
permissions=[
FilesystemPermission(
operations=["read", "write"],
paths=["/workspace/**"],
mode="allow",
),
FilesystemPermission(
operations=["read", "write"],
paths=["/**"],
mode="deny",
),
],
subagents=[
{
"name": "auditor",
"description": "Read-only code reviewer",
"system_prompt": "Review the code for issues.",
"permissions": [
FilesystemPermission(
operations=["write"],
paths=["/**"],
mode="deny",
),
FilesystemPermission(
operations=["read"],
paths=["/workspace/**"],
mode="allow",
),
FilesystemPermission(
operations=["read"],
paths=["/**"],
mode="deny",
),
],
}
],
)
Composite backends
使用带 sandbox default 的 CompositeBackend 时,每个 permission path 都必须限定在已知 route prefix 下。Sandboxes 支持任意 command execution,因此仅靠 path-based restrictions 无法阻止通过 shell commands 访问 filesystem。将 permissions 限定到 route-specific backends 可以避免这一冲突。
from deepagents.backends import CompositeBackend
composite = CompositeBackend(
default=sandbox,
routes={"/memories/": memories_backend},
)
# Works: permissions are scoped to the /memories/ route
agent = create_deep_agent(
model=model,
backend=composite,
permissions=[
FilesystemPermission(
operations=["write"],
paths=["/memories/**"],
mode="deny",
),
],
)
包含任何 route 外 paths 的 permissions 会抛出 NotImplementedError:
# Raises NotImplementedError: /workspace/** hits the sandbox default
try:
create_deep_agent(
model=model,
backend=composite,
permissions=[
FilesystemPermission(
operations=["write"],
paths=["/workspace/**"],
mode="deny",
),
],
)
except NotImplementedError:
pass
# Also raises: /** covers both routes and the default
try:
create_deep_agent(
model=model,
backend=composite,
permissions=[
FilesystemPermission(
operations=["read"],
paths=["/**"],
mode="deny",
),
],
)
except NotImplementedError:
pass