MATIH Platform is in active MVP development. Documentation reflects current implementation status.
14. Context Graph & Ontology
Security & RBAC
Tool Permissions

Tool Permissions

The ToolPermissionService provides fine-grained access control for MCP (Model Context Protocol) tools within the Context Graph. It maps tools to roles and tenants, enforces permission checks before tool execution, logs all permission decisions for audit, and supports tenant-specific overrides.


Overview

When an agent attempts to use a tool (such as executing SQL, accessing a data source, or calling an external API), the tool permission service checks whether the current user/agent has the required permissions based on their role, tenant, and individual access grants.

Source: data-plane/ai-service/src/context_graph/services/tool_permission_service.py


Permission Levels

LevelDescription
PUBLICAccessible by all authenticated users
TENANTAccessible by specific tenants only
ROLEAccessible by users with specific roles
USERAccessible by specific individual users
ADMINRequires admin privileges
DENIEDExplicitly denied

Permission Decisions

DecisionDescription
ALLOWEDUser has the required permission
DENIED_NO_PERMISSIONNo matching permission rule found
DENIED_TENANT_BLOCKEDTool is blocked for this tenant
DENIED_ROLE_REQUIREDUser does not have the required role
DENIED_USER_BLOCKEDUser is explicitly blocked

Permission Check Flow

  1. Check the permission cache for a cached decision
  2. Look up the tool permission rules in the graph store
  3. Evaluate rules in priority order: DENIED > USER > ROLE > TENANT > PUBLIC
  4. Cache the decision for the configured TTL (default: 300 seconds)
  5. Log the decision for audit

API Usage

from context_graph.services.tool_permission_service import (
    ToolPermissionService,
    ToolPermissionLevel,
)
 
service = ToolPermissionService()
 
decision = await service.check_permission(
    tool_name="sql_executor",
    auth_context=auth_context,
    tenant_id="acme",
)
 
if decision == PermissionDecision.ALLOWED:
    # Execute the tool
    result = await tool.execute(params)
else:
    raise PermissionDeniedError(f"Tool access denied: {decision}")

Caching

Permission decisions are cached in memory with a configurable TTL to avoid repeated graph store lookups:

ParameterDefaultDescription
Cache size10,000 entriesMaximum cached permission decisions
TTL300 secondsTime-to-live for cached decisions

Audit Logging

All permission decisions are logged with structured fields:

{
  "event": "tool_permission_check",
  "tool": "sql_executor",
  "tenant_id": "acme",
  "user_id": "user-123",
  "decision": "allowed",
  "permission_level": "role",
  "duration_ms": 2.3
}

Integration

ComponentIntegration
MCP GatewayCalls permission check before tool dispatch
RBAC CheckerProvides role resolution for permission evaluation
Context Graph StoreStores tool permission rules as graph entities
Auth ContextProvides user identity and role information