Claude Code needed staging access to diagnose a deployment failure. The operator approved a temporary role, a short-lived token, and an authenticated MCP session.
The agent found the bad configuration, opened a patch, and passed the tests. The review packet looked tidy. Twenty minutes later, the same token could still restart staging services.
The coding task had finished. Its authority had not.
Temporary access often receives more care at the start of a run than at the end. Teams record who approved it and when it should expire, then treat cleanup as an administrative detail. That is dangerous when a run fails halfway through, a worker crashes, or an MCP session outlives the process that opened it.
Bind temporary authority to the run
Do not lend Claude Code a human credential or add a broad role to a shared service account. Create authority that belongs to one run and one task.
run_identity:
run_id: cc-run-4821
task: repair-staging-deployment
principal: agent-cc-run-4821
allowed_effects:
- config.read
- deployment.restart:staging
denied_effects:
- deployment.restart:production
- iam.write
expires_at: 2026-08-27T11:15:00Z
cleanup_owner: platform-oncall
The run_id needs to survive every handoff. Put it in the cloud session tags, token metadata, MCP connection record, and audit events. If the provider cannot show which run owns a grant, the cleanup worker has to guess. Guessing is how useful temporary access becomes permanent background authority.
Expiry helps, but it is the backstop rather than the normal cleanup path. A token that expires in an hour remains usable for the rest of that hour. End the authority when the task ends.
Keep an authority inventory
The agent cannot revoke what the control plane did not record. Build an inventory when access is created, not after the patch is ready.
temporary_authority:
- kind: cloud_role_session
id: aws-session-a91
revoke_via: identity-broker
- kind: api_token
id: deploy-token-728
revoke_via: token-service
- kind: mcp_session
id: mcp-staging-114
revoke_via: mcp-gateway
- kind: queued_approval
id: approval-9007
revoke_via: policy-engine
Include delegated authority. An agent may create a child session, queue a deployment, mint a narrower token, or ask another service to continue work. Revoking the parent process does not prove that those descendants stopped.
This is the same reason stopping Claude Code does not cancel queued MCP work. Process state and authority state are different things.
Make cleanup a gate, not a courtesy
A run should enter cleanup_pending before it can become complete. The cleanup controller, not the model, should perform and verify the revocations.
PATCH READY
|
v
CLEANUP PENDING
| inventory grants and descendants
| revoke sessions, tokens, approvals
| test that denied actions now fail
v
HANDOFF READY
Run cleanup on every terminal path:
- successful handoff
- operator cancellation
- timeout
- policy denial
- worker crash recovery
- abandoned approval
The crash path matters most. An agent cannot clean up after itself if its process has disappeared. A separate controller needs a durable record of active run identities and a sweeper for runs without a live owner.
Do not let cleanup failure disappear behind a successful patch. If token revocation returns an error, the run is not complete. Assign an owner, preserve the evidence, and escalate according to the remaining effect. Read-only staging access and production deployment authority should not share the same response window.
Verify denial after revocation
A 200 OK from the revocation endpoint proves that the provider accepted a request. It does not prove that every cache, session, proxy, and delegated credential stopped working.
After revocation, attempt a harmless action that the run could previously perform:
revocation_probe:
principal: agent-cc-run-4821
action: deployment.status:staging
expected: denied
observed: denied
checked_at: 2026-08-27T10:58:12Z
Use a non-destructive probe. The point is to test the boundary without causing another production effect. If an API supports introspection, check both the credential status and a real authorization decision. A stale gateway cache can make those disagree.
For an MCP session, close the session, invalidate its bearer material, reject queued calls, and check for child operations. For a cloud role, end the broker session and inspect provider audit logs for later use. For a queued approval, mark it consumed or revoked so another worker cannot redeem yesterday’s decision.
Put a cleanup receipt in the review packet
The handoff needs one artifact that connects the run to every temporary grant and its final state.
authority_cleanup_receipt:
run_id: cc-run-4821
principal: agent-cc-run-4821
terminal_reason: task_completed
grants_discovered: 4
grants_revoked: 4
delegated_grants_discovered: 0
queued_effects_cancelled: 0
denial_probes:
passed: 3
failed: 0
last_authorized_event: 2026-08-27T10:54:03Z
first_denied_probe: 2026-08-27T10:58:12Z
unresolved_authority: []
cleanup_status: verified
handoff_status: ready
Count the grants. Name unresolved authority. Record the last observed authorized event and the first denied probe. Cleanup attempted is not enough for a reviewer deciding whether the run can close.
Sign the receipt or store it in an append-only control log. Bind it to the same run identity, policy version, commit, and review packet as the code evidence. Otherwise, a clean receipt from one run can be attached to another.
If unresolved_authority contains anything, set handoff_status to blocked. That is the useful part of the artifact. It turns lingering access from a buried warning into a release decision.
Test the exit paths
Most permission tests check whether an agent can obtain access. Add eval fixtures for losing it:
fixtures:
- name: successful_run_revokes_all_grants
expected: handoff_ready
- name: worker_crashes_after_role_issue
expected: controller_revokes_role
- name: mcp_session_has_queued_child_call
expected: child_cancelled_before_handoff
- name: gateway_cache_accepts_revoked_token
expected: cleanup_blocked
- name: approval_waits_after_operator_cancel
expected: approval_revoked
- name: delegated_token_missing_from_inventory
expected: reconciliation_failed
The eval should inspect provider state and audit events rather than trusting the agent’s summary. Claude Code can report that it removed a token. Only the control plane can prove that the token no longer works.
My completion rule is blunt: a Claude Code run is not finished until its temporary authority has been inventoried, revoked, tested, and attached to the review packet. A green test suite closes the code loop. The cleanup receipt closes the authority loop.
Claude Code: Building Production Agents That Actually Scale covers permission boundaries, MCP control, rollback, evals, observability, cost loops, and review packets for production coding agents.