Es war 23:47 Uhr an einem Mittwochabend, als unser On-Call-Pager erneut vibrierte. Ein 401 Unauthorized Error durchzog unsere Produktionsumgebung – jedoch nicht durch einen böswilligen Angriff, sondern durch einen internen Konfigurationsfehler: Ein Entwickler hatte versehentlich einen API-Schlüssel mit Admin-Rechten in einem öffentlichen Repository geteilt. Innerhalb von 12 Minuten wurden über 50.000 API-Anfragen an unser LLM-System gestellt, bevor wir den Schlüssel widerrufen konnten. Diese Situation verdeutlicht, warum RBAC-Berechtigungssteuerung (Role-Based Access Control) und Audit-Logs keine optionalen Features sind, sondern existenzielle Notwendigkeiten für jede Enterprise-AI-API-Infrastruktur.
Warum RBAC für AI APIs unverzichtbar ist
Großsprachige Modelle (LLMs) verarbeiten sensible Geschäftsdaten – von Kundenkommunikation bis hin zu strategischen Dokumenten. Ohne granulare Zugriffskontrolle riskieren Unternehmen:
- Datenlecks durch fehlerhafte oder böswillige Nutzung
- Cost Explosion durch unkontrollierte API-Nutzung
- Compliance-Verstöße (DSGVO, SOC 2, ISO 27001)
- Betriebsunterbrechungen durch fehlerhafte Konfigurationen
Architekturübersicht: RBAC-System für AI APIs
Ein robustes RBAC-System für AI-APIs besteht aus vier Kernkomponenten:
┌─────────────────────────────────────────────────────────────┐
│ RBAC-ARCHITEKTUR │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ User │───▶│ Role │───▶│Permission│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ Policy Engine (OPA) │ │
│ └──────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────────────────────────────┐ │
│ │ Audit Logger │ │
│ └──────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Python-Implementierung: Rollen und Berechtigungen
from enum import Enum
from dataclasses import dataclass
from typing import List, Optional
from datetime import datetime
import hashlib
import hmac
class Permission(Enum):
"""AI-API Berechtigungen"""
CHAT_COMPLETION_READ = "chat.completion:read"
CHAT_COMPLETION_WRITE = "chat.completion:write"
EMBEDDING_CREATE = "embedding:create"
MODEL_LIST = "model:list"
ADMIN_USERS = "admin:users"
ADMIN_KEYS = "admin:keys"
AUDIT_READ = "audit:read"
class Role(Enum):
"""Vordefinierte Rollen"""
DEVELOPER = "developer"
DATA_SCIENTIST = "data_scientist"
PRODUCT_MANAGER = "product_manager"
ADMIN = "admin"
AUDITOR = "auditor"
ROLE_PERMISSIONS = {
Role.DEVELOPER: [
Permission.CHAT_COMPLETION_READ,
Permission.CHAT_COMPLETION_WRITE,
Permission.EMBEDDING_CREATE,
],
Role.DATA_SCIENTIST: [
Permission.CHAT_COMPLETION_READ,
Permission.EMBEDDING_CREATE,
Permission.MODEL_LIST,
],
Role.PRODUCT_MANAGER: [
Permission.CHAT_COMPLETION_READ,
Permission.MODEL_LIST,
],
Role.ADMIN: list(Permission),
Role.AUDITOR: [
Permission.AUDIT_READ,
Permission.MODEL_LIST,
],
}
@dataclass
class APIKey:
key_id: str
key_hash: str
user_id: str
role: Role
permissions: List[Permission]
rate_limit: int # Anfragen pro Minute
created_at: datetime
expires_at: Optional[datetime] = None
is_active: bool = True
last_used: Optional[datetime] = None
request_count: int = 0
class RBACEngine:
def __init__(self):
self.api_keys: dict[str, APIKey] = {}
def create_api_key(
self,
user_id: str,
role: Role,
rate_limit: int = 100
) -> tuple[str, APIKey]:
"""Erstellt einen neuen API-Schlüssel mit RBAC-Permissions"""
raw_key = f"sk_holysheep_{hashlib secrets.token_urlsafe(32)}"
key_id = hashlib.sha256(raw_key.encode()).hexdigest()[:16]
api_key = APIKey(
key_id=key_id,
key_hash=self._hash_key(raw_key),
user_id=user_id,
role=role,
permissions=ROLE_PERMISSIONS[role],
rate_limit=rate_limit,
created_at=datetime.utcnow(),
expires_at=datetime.utcnow() + timedelta(days=90)
)
self.api_keys[key_id] = api_key
return raw_key, api_key
def validate_request(
self,
key_id: str,
permission: Permission
) -> tuple[bool, Optional[str]]:
"""Validiert API-Request gegen RBAC-Policy"""
if key_id not in self.api_keys:
return False, "401: Invalid API key"
api_key = self.api_keys[key_id]
if not api_key.is_active:
return False, "403: API key deactivated"
if api_key.expires_at and datetime.utcnow() > api_key.expires_at:
return False, "403: API key expired"
if permission not in api_key.permissions:
return False, f"403: Permission denied - {permission.value}"
# Rate-Limit Prüfung
if self._check_rate_limit(api_key):
return False, "429: Rate limit exceeded"
# Usage aktualisieren
api_key.last_used = datetime.utcnow()
api_key.request_count += 1
return True, None
def _hash_key(self, raw_key: str) -> str:
return hmac.new(
os.environ["KEY_SECRET"].encode(),
raw_key.encode(),
hashlib.sha256
).hexdigest()
def _check_rate_limit(self, api_key: APIKey) -> bool:
# Implementierung mit Redis oder In-Memory-Cache
return False # Vereinfacht