Permissions, and the fail-open trap
Three properties. The third one runs against everything your instincts have been trained on, and that is what makes it examinable.
How a permission list is evaluated
- In declaration order. The order you write the rules is the order they are considered.
- First match wins. Evaluation stops at the first rule whose pattern matches, and everything below it is never consulted.
- If nothing matches, the operation is allowed.
Order shadows
First-match-wins plus declaration order means a broad rule placed early shadows everything below it. Consider a list that looks entirely reasonable:
1. allow /workspace/**
2. deny /workspace/secrets/**A write to /workspace/secrets/key.pem matches rule 1, evaluation stops, and the write is allowed. Rule 2 was never reached. It is decoration in a security-critical file, which is the worst kind of decoration there is.
Flip it and add the piece almost everyone leaves off:
1. deny /workspace/secrets/**
2. allow /workspace/**
3. deny /**Rule 3 is the fail-open fix in its natural habitat. Without it, anything outside /workspace matches nothing and is therefore permitted, including paths you never imagined the agent would reach.
Why competence is the failure mode
The wrong answer here is produced by experience, which is unusual and worth naming.
Someone who has never configured a policy engine has no strong intuition about evaluation semantics. Someone with a decade of security work has a very strong one, and it says: deny by default, specific beats general, deny overrides allow. Those are three sensible models. None of them is this model.
The more policy engines you have configured, the more confidently you will get this wrong, which is precisely the profile of the person sitting a certification exam. That is presumably why it is on it.
Where permissions stop
Permissions are static rules over paths. Two things they cannot do, both of which have their own lever elsewhere in this course.
They cannot express “it depends”. A decision that needs a human belongs in interrupt_on, from module 1, and the two compose: gate the irreversible operations, scope the rest with paths.
They cannot cover what you did not think of, and here the failure direction is the bad one. A gate you forgot to configure means a tool runs unsupervised. A permission you forgot to write means a path is open. Both fail toward capability.
And there is a third boundary that matters more in production than in the exam, because it decides what the list is actually protecting.
Read that alongside the module summary. A permission list scopes the file tools; it is not a filesystem boundary, and it is not a leash on the shell.
That is the module’s real summary. Deep Agents defaults toward capability at every layer: the shell policy runs on your host, the permission list allows what it does not mention, and execute ships registered. Each of those is defensible in isolation for a tool aimed at capable agents. Inheriting all three without reading them is how a demo becomes an incident.
Try it yourself
When nothing matches
A filesystem operation is attempted and none of the declared permission rules matches its path. What happens?
Show answer
Correct answer: D — The operation is allowed, because filesystem permissions fail open
Filesystem permissions fail open: no matching rule means allowed. Denial is what almost everyone picks, because every firewall, IAM policy and access control system they have ever configured denies by default, and that trained intuition is exactly backwards here. If you want deny-by-default you write the catch-all deny rule yourself, because nothing hands it to you.
The rule that never runs
This list was written by someone being careful. A write to /workspace/secrets/key.pem is attempted.
1. allow /workspace/**
2. deny /workspace/secrets/**Show answer
Correct answer: B — Allowed, because the broad allow matched first and evaluation stopped
First match wins on declaration order, so rule 1 matches and rule 2 is never reached. It is decoration. Options one and three both encode a specificity-beats-position model, which is how many real policy engines work and is exactly why this list looks safe to the person writing it. Here position is everything and the deny has to come first.
The three properties
Three facts that together fully determine behaviour. Get any one wrong and you get a different answer, which is what makes this a clean four-option question for an examiner.
State the three rules governing how filesystem permissions are evaluated in Deep Agents, and the practical consequence of all three together.
Reveal answer
One, rules evaluate in declaration order. Two, first match wins, so evaluation stops at the first matching rule and later rules are never consulted. Three, if nothing matches, the operation is allowed, so the system fails open. The consequence is that specific rules must be declared before general ones, and that an explicit catch-all deny at the end is the only way to get deny-by-default behaviour.
Fix the list
Which rewrite gives you deny-by-default with a readable workspace and a protected secrets path?
Candidate A Candidate B
allow /workspace/** deny /workspace/secrets/**
deny /workspace/secrets/** allow /workspace/**
deny /** deny /**Show answer
Correct answer: B — Candidate B, because the specific deny is declared before the broad allow
Candidate B is correct: specific deny first, then the broad allow, then the catch-all. Candidate A repeats the shadowing bug, and its final catch-all is what makes it feel safe, which is the trap. A catch-all at the end cannot rescue a rule that was already shadowed higher up, because evaluation never reaches the bottom of the list for a path that matched at the top.
Who gets this wrong
This question is unusual in that experience makes performance worse. Why?
Show answer
Correct answer: C — Because policy-engine experience trains a deny-by-default intuition that fails here
Someone who has never configured a policy engine has no strong intuition here. Someone with ten years of security work has a very strong one, and it says deny-by-default, specific-beats-general, deny-overrides-allow. Every one of those is a reasonable model and none of them is this model. The fourth option is worth ruling out explicitly: this is not a version change, so do not go looking for a release note to reconcile it against.
Write a safe list
Ten minutes, scratch file, no runtime needed. Order is the entire exercise.
- Write a list that allows reads across a project directory, forbids anything under a secrets path, and forbids everything else.
- Read your list top to bottom and, for each rule, ask whether anything above it already matched the same path.
- Delete the catch-all deny and write down in one sentence what becomes reachable.