Action Restrictions and Permissions › Combining Restrictions, Confirmations, and Permissions
Michael BrenndoerferAugust 14, 20252 min read
AI Agent HandbookAll chapters Part 13 of 15Safety and Governance - Keeping the Agent Aligned
Action Restrictions and Permissions › Combining Restrictions, Confirmations, and PermissionsOne section · Sections in this chapter7 / 11 ↓
Sections in this chapter11
The most robust approach combines all three techniques:
- Permissions define what the agent is allowed to do in principle
- Restrictions limit the scope of allowed actions (which files, which recipients, etc.)
- Confirmations require user approval for high-stakes actions
Here's how they work together:
In[11]:
Code## Using Claude Sonnet 4.5 for comprehensive action safety
class SafeAgent:
def __init__(self, permissions: Set[Permission]):
self.permissions = PermissionManager(permissions)
self.client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
self.pending_confirmations = {}
def send_email(self, to_address: str, subject: str, body: str) -> str:
"""Send an email with permission check, restriction, and confirmation"""
# Step 1: Check permission
self.permissions.require_permission(
Permission.SEND_EMAIL,
f"Sending email to: {to_address}"
)
# Step 2: Check restrictions
if to_address not in ALLOWED_RECIPIENTS:
domain = to_address.split('@')[1] if '@' in to_address else ''
if domain not in ALLOWED_DOMAINS:
return f"Error: Cannot send email to {to_address}. Not in allowed recipients."
# Step 3: Request confirmation
confirmation_id = f"email_{len(self.pending_confirmations)}"
self.pending_confirmations[confirmation_id] = {
'action': 'send_email',
'params': {
'to_address': to_address,
'subject': subject,
'body': body
}
}
return f"""Ready to send email:
To: {to_address}
Subject: {subject}
Body: {body}
Confirm with: agent.confirm('{confirmation_id}')
Cancel with: agent.cancel('{confirmation_id}')"""
def confirm(self, confirmation_id: str) -> str:
"""Execute a pending action after confirmation"""
if confirmation_id not in self.pending_confirmations:
return "No pending action with that ID."
action_data = self.pending_confirmations[confirmation_id]
if action_data['action'] == 'send_email':
params = action_data['params']
result = send_email_restricted(
params['to_address'],
params['subject'],
params['body']
)
del self.pending_confirmations[confirmation_id]
return f"Confirmed. {result}"
def cancel(self, confirmation_id: str) -> str:
"""Cancel a pending action"""
if confirmation_id not in self.pending_confirmations:
return "No pending action with that ID."
del self.pending_confirmations[confirmation_id]
return "Action cancelled."This gives you defense in depth. If one layer fails, the others provide backup protection:
- If the agent somehow bypasses the permission check, the restriction will still block unauthorized recipients
- If the restriction is misconfigured, the confirmation gives the user a chance to catch the error
- If the user accidentally confirms, the permission log provides an audit trail