Fine-Grained Authorization (FGA)
Auris FGA ist eine Zanzibar-artige beziehungsbasierte Autorisierungs-Engine (ReBAC) für Objekt-Level-Zugriffskontrolle. Während RBAC die Frage beantwortet “Hat dieser Benutzer die Berechtigung view:invoices global?”, beantwortet FGA “Hat dieser Benutzer die viewer-Relation speziell auf Dokument #123?”.
FGA ist das richtige Werkzeug, wenn Autorisierung von Beziehungen zwischen spezifischen Objekten abhängt — nicht nur von Benutzerrollen.
Häufige Anwendungsfälle:
- Ein Dokumenten-Sharing-System, bei dem jedes Dokument individuelle Eigentümer, Editoren und Betrachter hat
- Ein Multi-Tenant-SaaS, bei dem der Zugriff auf ein Projekt von der Organisationsmitgliedschaft abhängt
- Ein Dateisystem, bei dem Ordnerberechtigungen von seinen Inhalten geerbt werden
- Ein B2B-Portal, bei dem Kundenkontakte nur die Daten ihrer eigenen Organisation sehen können
FGA ersetzt Ory Keto als Auris ReBAC-Schicht. Setze FGA_ENGINE_ENABLED=true in der API-Umgebung, um FGA zu aktivieren. Wenn false, fällt das System auf Keto zurück (veraltet).
Kernkonzepte
Objekte
Ein Objekt ist eine Entität in deinem System, identifiziert durch Typ und ID, geschrieben als typ:id. Beispiele:
document:inv-2024-001folder:invoices-q4project:website-redesignorganization:acme-corp
Relationen
Eine Relation beschreibt, wie ein Subjekt mit einem Objekt verbunden ist. Relationen werden im Autorisierungsmodell definiert. Beispiele: owner, editor, viewer, member, admin.
Subjekte
Ein Subjekt ist die zu autorisierende Entität. Subjekte werden auch als typ:id geschrieben. Der häufigste Subjekt-Typ ist user. Subjekte können auch Mengen sein — organization:acme-corp#member bedeutet “jeder, der Mitglied der acme-corp-Organisation ist”.
Tuples
Ein Beziehungs-Tuple ist eine gespeicherte Tatsache: (objektTyp, objektId, relation, subjektTyp, subjektId). Beispielsweise: “user:alice ist ein viewer von document:report-2024” wird gespeichert als:
{
"objectType": "document",
"objectId": "report-2024",
"relation": "viewer",
"subjectType": "user",
"subjectId": "alice"
}Autorisierungsmodelle
Das Autorisierungsmodell ist ein in einer OpenFGA-kompatiblen DSL geschriebenes Schema. Es definiert, welche Typen existieren und welche Relationen jeder Typ unterstützt.
DSL-Syntax
type user
type organization
relations
define admin: [user]
define member: [user] or admin
type project
relations
define org: [organization]
define admin: [user] or admin from org
define editor: [user] or admin
define viewer: [user] or editor
type document
relations
define project: [project]
define owner: [user]
define editor: [user] or owner or editor from project
define viewer: [user] or editor or viewer from project or member from org of projectDieses Modell definiert:
- Jeder Benutzer kann
memberoderadmineiner Organisation sein - Ein Projekt gehört zu einer Organisation; Projekt-Admins erben von Org-Admins
- Ein Dokument gehört zu einem Projekt; sein viewer-Set enthält direkte Viewer, Editoren, Projekt-Viewer und Org-Mitglieder
Rewrite-Typen
Auris FGA unterstützt 6 Rewrite-Typen zur Berechnung der Relationsmitgliedschaft:
| Typ | Beschreibung | DSL-Syntax |
|---|---|---|
this | Direktes Tuple-Lookup | [user] |
computedUserset | Mitglieder einer anderen Relation am selben Objekt | or owner |
tupleToUserset | Einer Relation zu einem anderen Objekt folgen, dann dessen Relation abrufen | viewer from project |
union | Benutzer in einem der Operanden | [user] or owner |
intersection | Benutzer in allen Operanden | [user] and verified |
exclusion | Benutzer im linken Operanden, aber nicht im rechten | [user] but not blocked |
Modell erstellen und aktivieren
/api/fga/modelsRequires: manage:fga_modelsErstellt eine neue Autorisierungsmodell-Version. Body: { name: string, dsl: string }. Auris analysiert und validiert die DSL vor dem Speichern.
/api/fga/models/:id/activateRequires: manage:fga_modelsAktiviert eine Modell-Version. Nur ein Modell kann gleichzeitig aktiv sein. Das Aktivieren eines neuen Modells macht bestehende Tuples nicht ungültig.
Tuples schreiben
Tuples sind die Laufzeitdaten — die tatsächlichen Beziehungen zwischen Objekten und Subjekten in deiner Anwendung.
/api/fga/tuplesRequires: manage:fga_tuplesSchreibt ein oder mehrere Beziehungs-Tuples. Body: { writes: TupleInput[] }. Jedes Tuple: { objectType, objectId, relation, subjectType, subjectId, subjectRelation? }.
/api/fga/tuplesRequires: manage:fga_tuplesLöscht ein oder mehrere Beziehungs-Tuples. Body: { deletes: TupleInput[] }.
/api/fga/tuples/bulkRequires: manage:fga_tuplesSchreibt und löscht Tuples in einer einzigen atomaren Anfrage. Body: { writes: TupleInput[], deletes: TupleInput[] }. Maximal 100 Operationen pro Anfrage.
// Dokument mit einem Benutzer teilen (Tuple schreiben)
await fetch('/api/fga/tuples', {
method: 'POST',
headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
writes: [
{
objectType: 'document',
objectId: 'report-2024',
relation: 'viewer',
subjectType: 'user',
subjectId: 'bob',
},
],
}),
})
// Zugriff widerrufen (Tuple löschen)
await fetch('/api/fga/tuples', {
method: 'DELETE',
headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
deletes: [
{
objectType: 'document',
objectId: 'report-2024',
relation: 'viewer',
subjectType: 'user',
subjectId: 'bob',
},
],
}),
})Autorisierung prüfen
Check
Der check-Endpunkt beantwortet “Hat Subjekt X die Relation R auf Objekt Y?”
/api/fga/checkBewertet, ob ein Subjekt eine Relation auf einem Objekt hat. Gibt { allowed: boolean } zurück. Keine Authentifizierung erforderlich — verwendet die Identität des Aufrufers aus dem Access Token, sofern kein explizites Subjekt angegeben.
Expand
Der expand-Endpunkt gibt den vollständigen Satz von Subjekten zurück, die eine bestimmte Relation auf einem Objekt haben — nützlich für Debugging und das Erstellen von Sharing-Panels für Benutzer.
/api/fga/expandRequires: view:fga_tuplesExpandiert eine Relation, um alle Subjekte (mit Auflösungspfad) anzuzeigen. Body: { objectType, objectId, relation }.
Objekte auflisten
Der list-objects-Endpunkt gibt alle Objekte eines bestimmten Typs zurück, auf denen ein Subjekt eine bestimmte Relation hat — nützlich für das Filtern von Abfrageergebnissen.
/api/fga/list-objectsRequires: view:fga_tuplesListet alle Objekte auf, bei denen das Subjekt die gegebene Relation hat. Body: { objectType, relation, subjectType, subjectId, cursor?, limit? }.
SDK-Verwendung
React
import { useFga } from '@auris/react'
function DocumentPage({ documentId }) {
const { check, listObjects, isLoading } = useFga()
const [canEdit, setCanEdit] = useState(false)
useEffect(() => {
check({
object: `document:${documentId}`,
relation: 'editor',
}).then((result) => setCanEdit(result.allowed))
}, [documentId])
return (
<div>
<h1>Dokument</h1>
{canEdit ? (
<button>Dokument bearbeiten</button>
) : (
<span>Nur-Lesen</span>
)}
</div>
)
}
// Sharing-Panel — Zugriffsberechtigte anzeigen
function SharingPanel({ documentId }) {
const { expand } = useFga()
const [viewers, setViewers] = useState([])
useEffect(() => {
expand({
objectType: 'document',
objectId: documentId,
relation: 'viewer',
}).then((result) => setViewers(result.subjects))
}, [documentId])
return (
<ul>
{viewers.map((viewer) => (
<li key={viewer.subjectId}>{viewer.subjectId}</li>
))}
</ul>
)
}Gängige Muster
Google Drive-Modell
Eine Hierarchie, bei der Ordnerberechtigungen auf Dokumente übertragen werden:
type user
type folder
relations
define owner: [user]
define editor: [user] or owner
define viewer: [user] or editor
define parent: [folder]
define editor_via_parent: editor from parent
define viewer_via_parent: viewer from parent
type document
relations
define owner: [user]
define parent_folder: [folder]
define editor: [user] or owner or editor_via_parent from parent_folder
define viewer: [user] or editor or viewer_via_parent from parent_folderSaaS Multi-Tenant-Modell
Organisationsmitgliedschaft steuert den Zugriff auf Projekte und Ressourcen:
type user
type organization
relations
define admin: [user]
define member: [user] or admin
type project
relations
define organization: [organization]
define admin: [user] or admin from organization
define member: [user] or member from organization or admin
type resource
relations
define project: [project]
define owner: [user]
define editor: [user] or owner or admin from project
define viewer: [user] or editor or member from projectDebugging mit dem FGA-Debugger in der Console
Die Auris Console enthält einen FGA-Debugger unter Console → Authorization → Debugger mit drei Tools:
- Check: Beliebige Objekt/Relation/Subjekt-Kombination testen und den Auflösungsbaum sehen
- Expand: Den vollständigen Subjekt-Satz für jede Relation visualisieren
- List Objects: Alle Objekte finden, auf die ein Benutzer Zugriff hat
Der Auflösungsbaum zeigt genau, welche Tuples und Modell-Rewrites zum Ergebnis allowed: true oder allowed: false geführt haben — unverzichtbar für die Diagnose unerwarteter Autorisierungsergebnisse.
Modell-Vorlagen
Die Console bietet drei Modell-Vorlagen für einen schnellen Einstieg:
- Basic: Einfaches Benutzer/Ressource-Modell mit owner, editor, viewer
- SaaS: Organisation → Projekt → Ressource-Hierarchie mit Team-Mitgliedschaft
- Drive: Verschachtelte Ordner/Dokument-Hierarchie mit vererbten Berechtigungen
Verwandte Anleitungen
- Rollen & Berechtigungen (RBAC) — Rollenbasierte Autorisierung für Anwendungsberechtigungen
- Benutzerdefinierte JWT-Claims — FGA-abgeleitete Daten in Access Tokens einbetten
- M2M Client Credentials — Serverseitige FGA-Prüfungen aus Backend-Diensten