Action Restrictions and Permissions › Designing a Permission System

Michael BrenndoerferAugust 14, 20252 min read
AI Agent HandbookAll chapters
Part 13 of 15Safety and Governance - Keeping the Agent Aligned
Chapter 37Action Restrictions and Permissions › Designing a Permission System
Reading section 6 of 11 · Designing a Permission System · 2 minSection 6 of 11 · 2 min

Book contents

Section 6 of 11 · 2 min read

Action Restrictions and Permissions › Designing a Permission SystemOne section · Sections in this chapter6 / 11 ↓

As your agent grows more capable, you'll want a more structured approach to permissions. Instead of hardcoding restrictions in each tool, you can create a permission system that manages what the agent can do.

Here's a simple permission system:

In[9]:
Code
## Using Claude Sonnet 4.5 with a structured permission system
from enum import Enum
from typing import Set, Dict, Any

class Permission(Enum):
    READ_FILES = "read_files"
    WRITE_FILES = "write_files"
    SEND_EMAIL = "send_email"
    MAKE_API_CALLS = "make_api_calls"
    DELETE_DATA = "delete_data"

class PermissionManager:
    def __init__(self, granted_permissions: Set[Permission]):
        self.granted_permissions = granted_permissions
        self.permission_log = []
    
    def check_permission(self, permission: Permission, action_details: str) -> bool:
        """Check if a permission is granted and log the check"""
        has_permission = permission in self.granted_permissions
        
        self.permission_log.append({
            'permission': permission.value,
            'action': action_details,
            'granted': has_permission
        })
        
        return has_permission
    
    def require_permission(self, permission: Permission, action_details: str):
        """Raise an error if permission is not granted"""
        if not self.check_permission(permission, action_details):
            raise PermissionError(
                f"Action requires {permission.value} permission: {action_details}"
            )

class PermissionedAgent:
    def __init__(self, permissions: Set[Permission]):
        self.permissions = PermissionManager(permissions)
        self.client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
    
    def read_file(self, filename: str) -> str:
        """Read a file if permission is granted"""
        self.permissions.require_permission(
            Permission.READ_FILES,
            f"Reading file: {filename}"
        )
        
        # Permission granted, proceed with reading
        with open(filename, 'r') as f:
            return f.read()
    
    def send_email(self, to_address: str, subject: str, body: str) -> str:
        """Send an email if permission is granted"""
        self.permissions.require_permission(
            Permission.SEND_EMAIL,
            f"Sending email to: {to_address}"
        )
        
        # Permission granted, proceed with sending
        return send_email_restricted(to_address, subject, body)
    
    def get_permission_log(self) -> list:
        """Get a log of all permission checks"""
        return self.permissions.permission_log

Now you can create agents with different permission levels:

In[10]:
Code
## Create a read-only agent
read_only_agent = PermissionedAgent({
    Permission.READ_FILES,
    Permission.MAKE_API_CALLS
})

## Create a full-access agent
full_agent = PermissionedAgent({
    Permission.READ_FILES,
    Permission.WRITE_FILES,
    Permission.SEND_EMAIL,
    Permission.MAKE_API_CALLS
})

## Try to send an email with the read-only agent
try:
    read_only_agent.send_email('alice@example.com', 'Test', 'Hello')
except PermissionError as e:
    print(f"Permission denied: {e}")
    # Output: Permission denied: Action requires send_email permission: 
    #         Sending email to: alice@example.com
Out[10]:
Console
Permission denied: Action requires send_email permission: Sending email to: alice@example.com

This system gives you several benefits:

Centralized control: All permission logic is in one place, making it easy to audit and modify.

Clear permissions: You can see at a glance what each agent is allowed to do.

Audit trail: The permission log shows every action the agent attempted and whether it was allowed.

Flexible configuration: You can easily create agents with different permission levels for different use cases.