Permissions: rules for file writes
Permissions are rules, passed as FilesystemPermission objects, that allow or deny the built-in file tools by operation and path; the first rule that matches decides.
Last updated: 29 Sep, 2026 · Deep Agents 0.7
The video lists permissions among create_deep_agent's parameters; this lesson follows the docs. The trip planner should write only its own notes. A permission rule makes that a fact instead of a request in the prompt.
The permissions syntax
from deepagents import FilesystemPermission
permissions = [
FilesystemPermission(operations=["write"], paths=["/trip/**"], mode="allow"),
FilesystemPermission(operations=["write"], paths=["/**"], mode="deny"), # everything else
]Rules are checked from top to bottom, and the first one that matches wins. A path that no rule matches is allowed. mode can also be "interrupt", which pauses for approval as in the human-in-the-loop lesson.
An agent that may write only under /trip/
A new file, notes.py, with no tools of its own: the built-in file tools are enough.
from deepagents import create_deep_agent
from langchain.chat_models import init_chat_model
model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0, max_retries=6)from deepagents import FilesystemPermission
agent = create_deep_agent(
model=model,
permissions=[
FilesystemPermission(operations=["write"], paths=["/trip/**"], mode="allow"),
FilesystemPermission(operations=["write"], paths=["/**"], mode="deny"),
],
system_prompt="You keep trip notes in files. Reply in one short sentence.",
)Writing inside and outside /trip/
for path in ["/trip/notes.md", "/settings/budget.md"]:
result = agent.invoke({"messages": [{"role": "user", "content": f"Write 'Budget: 100,000 rupees' to {path}."}]})
tool_results = [m.text for m in result["messages"] if m.type == "tool"]
print(path, "->", tool_results, "| files:", list(result["files"]))/trip/notes.md -> ['Updated file /trip/notes.md'] | files: ['/trip/notes.md'] /settings/budget.md -> ['Error: permission denied for write on /settings/budget.md', 'No files found', 'No files found'] | files: []
What the two writes show
- /trip/notes.md matched the allow rule. The write succeeded and the file is in
result["files"]. - /settings/budget.md skipped the first rule and matched the deny rule. The tool returned "permission denied"; the agent then looked for files, found none, and wrote nothing.
- The model did try: permissions are checked when the tool runs, so they hold even when the prompt is ignored.
Permissions vs approval vs the prompt
| System prompt rule | Permission | interrupt_on | |
|---|---|---|---|
| Enforced by | The model | The file tools | A person |
| Can be ignored | Yes | No | No |
| Applies to | Anything | Built-in file tools | Any tool |
Where permissions fit
- Keeping an agent inside a workspace folder.
- Protecting files like
.envor memory files from edits. - Giving a subagent narrower access than the main agent, with its own
permissionskey.
/** above the allow on /trip/** denies every write, because the first match wins.Related
- Previous: Edit decisions: changing a tool call before it runs
- Next: Fault tolerance: call limits and tool retries
- Reference: Deep Agents permissions
- Swap the two rules and run both writes again.
- Add a rule that denies
readon/secrets/**and ask the agent to read a file there. - Change the deny rule's mode to
"interrupt", add a checkpointer, and resume the paused write.
You understood something today that you didn't yesterday.