Skip to main content

Tool Permissions & Access Control

Role-based access control system for tools with permission management, inheritance, and dynamic evaluation.

Features

  • Role-Based Access Control: Define roles with specific permissions
  • Permission Inheritance: Roles can inherit from other roles
  • Dynamic Evaluation: Context-aware permission checking
  • Tool Authorization: Control access to specific tools
  • Audit Logging: Track permission changes and usage
  • Flexible Conditions: Time-based and context-based permissions

Quick Start

from recoagent.tools import PermissionManager, Role, Permission, PermissionLevel, ResourceType

# Initialize permission manager
pm = PermissionManager()

# Create roles
admin_role = Role(
name="admin",
description="Administrator with full access",
permissions=[
Permission("*", ResourceType.TOOL, PermissionLevel.ADMIN)
]
)

user_role = Role(
name="user",
description="Standard user",
permissions=[
Permission("search_tools", ResourceType.TOOL, PermissionLevel.EXECUTE),
Permission("basic_workflows", ResourceType.WORKFLOW, PermissionLevel.EXECUTE)
]
)

# Add roles
pm.add_role(admin_role)
pm.add_role(user_role)

# Add users
pm.add_user("user123", "John Doe", roles=["user"])
pm.add_user("admin456", "Jane Admin", roles=["admin"])

# Check permissions
can_search = pm.check_permission("user123", "search_tools", PermissionLevel.EXECUTE)
print(f"Can search: {can_search}") # True

can_admin = pm.check_permission("user123", "admin_tools", PermissionLevel.ADMIN)
print(f"Can admin: {can_admin}") # False

Permission Levels

Basic Levels

from recoagent.tools import PermissionLevel

# Read-only access
Permission("view_tools", ResourceType.TOOL, PermissionLevel.READ)

# Write access
Permission("edit_tools", ResourceType.TOOL, PermissionLevel.WRITE)

# Execute access
Permission("run_tools", ResourceType.TOOL, PermissionLevel.EXECUTE)

# Administrative access
Permission("manage_tools", ResourceType.TOOL, PermissionLevel.ADMIN)

Permission Hierarchy

# Permission levels are hierarchical
# ADMIN > EXECUTE > WRITE > READ

# Admin can do everything
admin_permission = Permission("*", ResourceType.TOOL, PermissionLevel.ADMIN)

# Execute can run tools
execute_permission = Permission("search_tools", ResourceType.TOOL, PermissionLevel.EXECUTE)

# Write can modify tools
write_permission = Permission("edit_tools", ResourceType.TOOL, PermissionLevel.WRITE)

# Read can view tools
read_permission = Permission("view_tools", ResourceType.TOOL, PermissionLevel.READ)

Role Management

Creating Roles

# Basic role
basic_role = Role(
name="basic_user",
description="Basic user role",
permissions=[
Permission("search_tools", ResourceType.TOOL, PermissionLevel.EXECUTE),
Permission("view_workflows", ResourceType.WORKFLOW, PermissionLevel.READ)
]
)

# Role with inheritance
advanced_role = Role(
name="advanced_user",
description="Advanced user role",
inherits_from=["basic_user"], # Inherit from basic_user
permissions=[
Permission("edit_tools", ResourceType.TOOL, PermissionLevel.WRITE),
Permission("create_workflows", ResourceType.WORKFLOW, PermissionLevel.EXECUTE)
]
)

# Admin role
admin_role = Role(
name="admin",
description="Administrator role",
permissions=[
Permission("*", ResourceType.TOOL, PermissionLevel.ADMIN),
Permission("*", ResourceType.WORKFLOW, PermissionLevel.ADMIN),
Permission("*", ResourceType.DATA, PermissionLevel.ADMIN)
]
)

Role Inheritance

# Create role hierarchy
pm.add_role(Role(
name="base_user",
permissions=[
Permission("view_tools", ResourceType.TOOL, PermissionLevel.READ)
]
))

pm.add_role(Role(
name="power_user",
inherits_from=["base_user"], # Inherit base permissions
permissions=[
Permission("run_tools", ResourceType.TOOL, PermissionLevel.EXECUTE)
]
))

pm.add_role(Role(
name="developer",
inherits_from=["power_user"], # Inherit power user permissions
permissions=[
Permission("edit_tools", ResourceType.TOOL, PermissionLevel.WRITE)
]
))

User Management

Adding Users

# Add user with roles
pm.add_user(
user_id="user123",
username="John Doe",
roles=["basic_user", "power_user"],
metadata={"department": "engineering", "level": "senior"}
)

# Add user with specific permissions
pm.add_user(
user_id="special_user",
username="Special User",
roles=["basic_user"],
permissions=[
Permission("special_tool", ResourceType.TOOL, PermissionLevel.EXECUTE)
]
)

Assigning Roles

# Assign role to user
pm.assign_role("user123", "power_user")

# Check if user has role
user_info = pm.get_user_info("user123")
print(f"User roles: {user_info['roles']}")

# Revoke role
pm.revoke_role("user123", "power_user")

User Permissions

# Get all permissions for user
permissions = pm.get_user_permissions("user123")

for permission in permissions:
print(f"Resource: {permission.resource}")
print(f"Level: {permission.permission_level}")
print(f"Type: {permission.resource_type}")
print(f"Conditions: {permission.conditions}")

Permission Checking

Basic Permission Checks

# Check if user can execute tool
can_execute = pm.check_permission(
user_id="user123",
resource="search_tools",
permission_level=PermissionLevel.EXECUTE
)

# Check if user can admin tool
can_admin = pm.check_permission(
user_id="user123",
resource="admin_tools",
permission_level=PermissionLevel.ADMIN
)

Context-Aware Permissions

# Check permission with context
can_access = pm.check_permission(
user_id="user123",
resource="sensitive_tool",
permission_level=PermissionLevel.EXECUTE,
context={
"time_of_day": "business_hours",
"location": "office",
"department": "engineering"
}
)

Conditional Permissions

# Permission with conditions
conditional_permission = Permission(
resource="sensitive_tool",
resource_type=ResourceType.TOOL,
permission_level=PermissionLevel.EXECUTE,
conditions={
"time_of_day": "business_hours",
"location": "office"
}
)

# Check with context
context = {
"time_of_day": "business_hours",
"location": "office"
}

can_access = pm.check_permission(
user_id="user123",
resource="sensitive_tool",
permission_level=PermissionLevel.EXECUTE,
context=context
)

Tool Integration

Permission Decorators

from recoagent.tools import ToolPermissionDecorator

# Create permission decorator
permission_decorator = ToolPermissionDecorator(pm)

# Decorate tool function
@permission_decorator.require_permission(
resource="search_tool",
permission_level=PermissionLevel.EXECUTE
)
def search_tool(query, user_id=None, **kwargs):
# Tool implementation
return search_results

# Use tool
result = search_tool("test query", user_id="user123")

Tool Authorization

# Check tool access before execution
def execute_tool(tool_name, user_id, **kwargs):
# Check permission
if not pm.check_permission(user_id, tool_name, PermissionLevel.EXECUTE):
return {"error": "Permission denied"}

# Execute tool
return tool_function(**kwargs)

Dynamic Permissions

# Grant temporary permission
pm.grant_permission(
user_id="user123",
resource="temporary_tool",
resource_type=ResourceType.TOOL,
permission_level=PermissionLevel.EXECUTE,
expires_at=datetime.now() + timedelta(hours=1)
)

# Check temporary permission
can_access = pm.check_permission(
user_id="user123",
resource="temporary_tool",
permission_level=PermissionLevel.EXECUTE
)

Advanced Features

Time-Based Permissions

# Permission with expiration
expiring_permission = Permission(
resource="temporary_tool",
resource_type=ResourceType.TOOL,
permission_level=PermissionLevel.EXECUTE,
expires_at=datetime.now() + timedelta(days=7)
)

# Check if permission is still valid
if expiring_permission.expires_at > datetime.now():
print("Permission is valid")
else:
print("Permission has expired")

Resource-Specific Permissions

# Wildcard permissions
wildcard_permission = Permission(
resource="*", # All resources
resource_type=ResourceType.TOOL,
permission_level=PermissionLevel.ADMIN
)

# Specific resource permissions
specific_permission = Permission(
resource="search_tools", # Specific resource
resource_type=ResourceType.TOOL,
permission_level=PermissionLevel.EXECUTE
)

Permission Revocation

# Revoke specific permission
pm.revoke_permission(
user_id="user123",
resource="sensitive_tool",
permission_level=PermissionLevel.EXECUTE
)

# Revoke all permissions for user
pm.revoke_role("user123", "power_user")

Integration Examples

With FastAPI

from fastapi import FastAPI, Depends, HTTPException
from recoagent.tools import PermissionManager

app = FastAPI()
pm = PermissionManager()

def get_current_user():
# Get user from authentication
return "user123"

def check_permission(resource: str, level: PermissionLevel):
def permission_checker(user_id: str = Depends(get_current_user)):
if not pm.check_permission(user_id, resource, level):
raise HTTPException(status_code=403, detail="Permission denied")
return user_id
return permission_checker

@app.post("/tools/search")
async def search_tools(
query: str,
user_id: str = Depends(check_permission("search_tools", PermissionLevel.EXECUTE))
):
# Tool implementation
return {"results": "search_results"}

With Workflows

from packages.observability import trace_workflow

@trace_workflow(name="permission_controlled_workflow")
async def controlled_workflow(user_id: str, tool_name: str):
# Check permission
if not pm.check_permission(user_id, tool_name, PermissionLevel.EXECUTE):
return {"error": "Permission denied"}

# Execute workflow
result = await execute_tool(tool_name)
return result

With Tools

# Tool with permission check
def secure_tool(operation, user_id, **kwargs):
# Check permission
if not pm.check_permission(user_id, f"{operation}_tool", PermissionLevel.EXECUTE):
return {"error": "Permission denied"}

# Execute operation
return perform_operation(operation, **kwargs)

Monitoring and Auditing

Permission Statistics

# Get permission statistics
stats = pm.get_permission_stats()
print(f"Total Users: {stats['total_users']}")
print(f"Total Roles: {stats['total_roles']}")
print(f"Total Permissions: {stats['total_permissions']}")

# Get user statistics
user_stats = pm.get_user_stats("user123")
print(f"User Roles: {user_stats['roles']}")
print(f"User Permissions: {user_stats['permissions']}")

Audit Logging

# Track permission changes
pm.add_audit_log(
user_id="admin123",
action="grant_permission",
resource="sensitive_tool",
target_user="user123",
timestamp=datetime.now()
)

# Get audit logs
audit_logs = pm.get_audit_logs(user_id="user123")
for log in audit_logs:
print(f"{log['timestamp']}: {log['action']} on {log['resource']}")

Best Practices

  1. Principle of Least Privilege: Grant minimum required permissions
  2. Role Hierarchy: Use role inheritance for complex permissions
  3. Regular Audits: Review permissions regularly
  4. Time-Based Access: Use expiration for temporary permissions
  5. Context Awareness: Consider context in permission checks
  6. Documentation: Document permission policies
  7. Testing: Test permission scenarios thoroughly

Troubleshooting

Common Issues

  1. Permission Denied: Check user roles and permissions
  2. Role Inheritance: Verify role hierarchy
  3. Context Issues: Check permission conditions
  4. Expiration: Verify permission expiration times

Debug Mode

# Enable debug logging
import logging
logging.getLogger('recoagent.tools.permissions').setLevel(logging.DEBUG)

Permission Testing

# Test permission scenarios
def test_permissions():
# Test basic permission
assert pm.check_permission("user123", "search_tools", PermissionLevel.EXECUTE)

# Test denied permission
assert not pm.check_permission("user123", "admin_tools", PermissionLevel.ADMIN)

# Test context-based permission
context = {"time_of_day": "business_hours"}
assert pm.check_permission("user123", "sensitive_tool", PermissionLevel.EXECUTE, context)

print("All permission tests passed!")

API Reference

PermissionManager

MethodDescription
add_role(role)Add role to manager
add_user(user_id, username, roles)Add user with roles
assign_role(user_id, role_name)Assign role to user
check_permission(user_id, resource, level, context)Check user permission
grant_permission(user_id, resource, level, expires_at)Grant permission
revoke_permission(user_id, resource, level)Revoke permission

PermissionLevel

ValueDescription
READRead-only access
WRITEWrite access
EXECUTEExecute access
ADMINAdministrative access

ResourceType

ValueDescription
TOOLTool resource
WORKFLOWWorkflow resource
DATAData resource
SYSTEMSystem resource