Zum Hauptinhalt springen

API — CASL-Permissions

Mehr Hintergrund: Berechtigungen-CASL Konzept.

CASL-Tuple

Jede API-Aktion wird gegen ein CASL-Tuple geprüft:

[action, subject, conditions?]

Beispiele:

  • ["view", "Customer"] — Kunden ansehen
  • ["update", "Customer", { "createdBy": "$user.id" }] — nur eigene Kunden ändern
  • ["do", "ApproveAbsence"] — Abwesenheit genehmigen

Standard-Actions

ActionWann
viewGET
createPOST
updatePATCH/PUT
deleteDELETE
do:CustomActionPOST auf Sub-Endpoint

403-Errors

{
"error": {
"code": "FORBIDDEN",
"message": "Action 'create' on subject 'Customer' not allowed",
"details": {
"missingAbility": [{
"action": "create",
"subject": "Customer"
}],
"userId": "...",
"userRoles": ["Innendienst"]
}
}
}

→ Lösung: Admin gibt User die fehlende Ability via Custom-Rolle.

FE_-Subjects vs. API-Subjects

Pro Modul zwei Subjects:

  • Customer — Daten-Zugriff (API)
  • FE_Customer — Seiten-Sichtbarkeit (Frontend)

API-Calls prüfen das API-Subject. FE_-Subjects sind nur für UI-Routing.

Conditions (feinere Kontrolle)

{
"action": "view",
"subject": "Workorder",
"conditions": {
"employeeId": "$user.id"
}
}

→ User darf nur Aufträge sehen, bei denen employeeId seine User-ID ist.

Operatoren in Conditions (MongoDB-ähnlich):

  • $eq, $ne, $gt, $lt, $gte, $lte
  • $in, $nin
  • $or, $and
  • $user.id, $user.tenantId, $user.roleNames

Custom-Actions (do:)

Für Aktionen jenseits CRUD:

ActionEndpointWofür
do:ApproveAbsencePOST /absences/:id/approveUrlaub genehmigen
do:RejectAbsencePOST /absences/:id/rejectUrlaub ablehnen
do:HandoverSalesDocumentPOST /sales-documents/:id/handoverLifecycle-Übergang
do:BulkImportAbsencesPOST /absences/bulk-importBulk-Import
do:DownloadAccountingGET /accountings/:id/downloadExport

Token-Abilities Cache

JWT-Token enthält zum Login-Zeitpunkt die Abilities. Bei Rollen-Änderung:

  • User muss neu einloggen oder Token-Refresh machen
  • Bis dahin gelten die alten Abilities (max. 1h Token-Gültigkeit)

API-Beispiel mit Conditions

GET /api/workorders
Authorization: Bearer <token mit ["view","Workorder",{"employeeId":"$user.id"}]>

# Backend filter automatisch: WHERE employeeId = <user.id>

User sieht nur seine Aufträge — die Condition wird Backend-seitig durchgesetzt.

Hinweis für Frontend-Entwickler

Ability-Check vor API-Call:

import { useAbility } from "@casl/react";

const ability = useAbility(AbilityContext);
if (ability.can("create", "Workorder")) {
// Button zeigen
}

Spart unnötige 403-Errors. Trotzdem: Backend prüft immer unabhängig (defense in depth).

Audit pro 403

Auch fehlgeschlagene Calls werden im Audit-Log mit 403-Status protokolliert. Bei häufigen 403 vom gleichen User: möglicher Privilegien-Eskalations-Versuch.

Verwandte Doku