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.

Claude Code temporary access cleanup receipt

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.