Claude Code permissions need expiry dates
Claude Code permissions tend to expand for reasonable reasons.
A task starts inside one module. The agent asks to inspect a neighbouring package. That makes sense. Then it wants to run a broader command. Also reasonable. Then it asks for an MCP tool because the ticket, docs, or deployment notes live outside the repo. By the end of the run, the permission set may be much wider than the original problem.
The risk is not that one request was foolish. The risk is that temporary access quietly becomes normal.
For production-adjacent work, I want a simple rule: every permission granted to Claude Code should have an expiry date. Usually that expiry date is the end of the task.
A permission is not a preference
It is tempting to treat permissions like a comfort setting. This repo is familiar, this command usually works, that MCP server is handy, so the agent gets a slightly wider lane next time.
That is how permission drift starts.
A permission is not a preference. It is a claim about what the agent needs to complete a specific task safely. If the task changes, the claim should be checked again. If the work finishes, the permission should close.
That sounds heavy until you compare it with the alternative. A team gives Claude Code broad read access because it helped on the last migration. Two weeks later, someone uses the same setup for a billing bug, and the agent can now inspect parts of the system that are irrelevant to the fix. Nothing dramatic has happened yet, but the blast radius has grown without a decision.
I wrote earlier about Claude Code MCP tools needing a blast radius. Expiry is the companion habit. Blast radius says how far the tool can reach. Expiry says how long that reach is allowed to exist.
Make the grant small enough to review
A useful permission grant should fit in a short note. If it takes a page to explain, the task is probably too wide for the current level of autonomy.
For example:
Task: fix duplicate invoice rows in the export job.
Grant: read and edit billing/export/** and tests/billing/export/**.
Commands: targeted export tests and lint for the billing package.
MCP: read-only ticket lookup for PAY-2184 only.
Stop before: migrations, payment provider adapters, deploy config,
production data, or write-capable external tools.
Expires: when the patch and review packet are produced.
The important line is the last one.
Without expiry, the team has to remember to narrow access later. Under delivery pressure, people rarely do. With expiry, the default is safer: the next run starts from a smaller contract unless a human grants more.
This is the same operational instinct I learned in financial-services engineering. Controls that depend on everyone remembering the careful thing at the end of a busy day are weak controls. The safer pattern is to make the careful thing the default.
Permission requests should explain the risk, not only the need
Claude Code can be good at explaining why it wants more context. That is useful, but it is only half of the request.
When a run asks for wider access, the human needs two things:
Need: what the agent cannot prove without this access.
Risk: what could go wrong if this access is wider than needed.
A request like “I need to inspect the deployment config” is not enough near production systems. Better:
Need: I need to confirm whether the export job runs with EU-only flags.
Risk: deployment config may include unrelated service settings. I will read only
config/export-job.yml and stop if the answer is not there.
Expiry: this read grant ends after I record the flag behaviour in the review packet.
That gives the reviewer something concrete to approve or reject. It also trains the team to notice when the agent is reaching for convenience rather than evidence.
A good workflow does not shame every request for more access. Sometimes the agent really does need more context. The point is to avoid lazy widening. If the permission is worth granting, it is worth naming.
The review packet should show what expired
A clean diff does not prove that permissions were handled well.
The review packet should include a small permission section:
Permissions granted:
- billing/export/** read and edit
- tests/billing/export/** read and edit
- targeted billing export tests
- read-only PAY-2184 ticket lookup
Permission pressure:
- requested deployment config read
- human narrowed it to config/export-job.yml
Expired at:
- patch produced
- tests run
- review packet generated
This is not audit theatre. It is how the reviewer checks whether the run stayed inside the deal.
It also creates useful evidence over time. If Claude Code keeps asking for the same broad tool on a certain kind of task, maybe the team needs a narrower MCP server. If it keeps asking to inspect deploy config for ordinary bug fixes, maybe the prompt is too vague. If permissions never expire cleanly, the adoption model is too loose.
That evidence is more valuable than another demo where the agent finishes a task quickly.
Expiry changes the team conversation
Without expiry, the permission conversation is often emotional:
Do we trust Claude Code with this?
That question is too broad. It pushes people into camps: believers, sceptics, blockers, enthusiasts.
Expiry makes the question smaller:
Do we grant this access for this task, with this stop rule, until this evidence exists?
That is a better engineering question. It allows a team to be ambitious and careful at the same time.
You can widen autonomy later. In fact, you should widen it where the evidence supports it. But the widening should be earned through repeated controlled runs, not inherited from yesterday’s emergency.
A simple starting rule
If your team is using Claude Code on anything close to production, add this line to the task contract:
All extra permissions expire when the run ends unless a human renews them for a named follow-up task.
Then ask for the permission section in the review packet. The first few times may feel slightly slow. That is fine. The goal is not to wrap Claude Code in process until it stops being useful. The goal is to keep useful work from turning into invisible access creep.
The free Claude Code production checklist includes permission scope, MCP blast radius, review packets, evals, observability, and rollback prompts.
For the full operating model, I wrote the Claude Code book for engineers and teams moving from impressive demos to controlled production use. The landing page routes readers to the Amazon Kindle edition as the primary purchase option.
Start with the free production checklist, then get the Claude Code book for the practical operating model: permissions, MCP, evals, observability, review gates, and rollback.