Zum Inhalt springen

Zugriff & Capabilities

Jeder Lesezugriff über /osl/query wird durch ein Capability-+-Permission-Modell begrenzt: wer fragt (eine Delegations-Kette aus Subjects), was jede Policy ihnen über den semantischen Graphen gewährt und wie diese Grants komponieren. Es ist fail-closed per Konstruktion — der Default ist deny, und alles Unaufgelöste wird verworfen, niemals geraten.

Ein Subject ist ein Principal in einer Delegationskette. Es hat einen von drei deskriptiven Typen:

Typ Ist
human Ein Benutzer (Username / E-Mail)
agent Ein AI-Agent (mit einem Vendor-Tag: Claude, ChatGPT, Gemini, …, oder custom)
machine Ein Workload / Service-Account

Zugriff wird über eine Kette von Principals ausgewertet, Root → Leaf. Das handelnde Subject ist das letzte Glied. Die Komposition hat zwei Ebenen:

Innerhalb eines Principals

Alle Policies, die diesen Principal binden, kombinieren sich: Grants vereinigen sich (Union), die stärkste Obligation gewinnt (deny > mask > redact), ein expliziter Deny überschreibt, und Bedingungen (IP-Range, Zeitfenster) gaten nur ALLOW — ein Deny ist unbedingt.

Über die Kette hinweg

Die Glieder kombinieren sich durch MEET (Schnittmenge): eine Entity oder Spalte ist nur dann gewährt, wenn jedes Glied sie gewährt. Der Tier-Cap ist das Minimum (am restriktivsten) und die geforderte Redaktion ist die Union dessen, was jedes Glied verlangt. Ein leeres Glied oder eines ohne verfasste Policy kollabiert das Meet zu deny.

Link 0 (manager): { client, email: cleartext }
Link 1 (employee): { client, email: mask }
────────────────────────────────────────────── MEET
Effective: { client, email: mask } ← the column survives, obligated to mask

Der semantische Scope einer Policy ist eine Menge von Bindings, jedes mit einer Domain-Map-nodeId als Schlüssel (z. B. entity:Customer, metric:aum). Ein Binding deklariert:

Feld Bedeutung
attributeGrants[] Grant pro Attribut: cleartext, mask oder deny
filters[] (+ filtersBool) Zeilen-Prädikate, die scopen, welche Zeilen sichtbar sind
grantedMetrics[] Eigenständige Metrik-Grants
facetGrants[] Content-Grant pro Facette (siehe Redaktionsversionen)

Grants sind positiv: Eine Spalte, die nicht gewährt ist, wird redigiert, niemals als NULL zurückgegeben oder stillschweigend aus dem Schema entfernt. deny entfernt eine Spalte vollständig aus der Projektion; ein policy-globaler deny überschreibt den Grant jedes anderen Bindings.

Content-Facetten werden durch benannte Redaktionsversionen gesteuert — eine Entkopplung eines menschenlesbaren Namens von einer physischen, byte-stabilen Identität:

  • Eine RedactionVersion hat einen Namen (das Konsolen-Handle, z. B. "PII básica") und eine Menge von Tags (die Content-Klassen, die sie redigiert, z. B. {email, phone}).
  • Die Tags sind die physische Identität (byte-unverändert, als Tabellenschlüssel genutzt); der Name ist nur fürs Authoring.
  • Die implizite original-Version (keine Tags) ist die Basistabelle.
  • Ein facetGrant bindet einen geforderten Versionsnamen pro Facette. Die Auswahl ist exact-or-deny: Die Engine bedient die gespeicherte Version, deren Tags exakt übereinstimmen, oder verweigert die Facette — sie fällt niemals auf eine stärker oder schwächer redigierte Version zurück.
  • Über eine Kette hinweg komponieren die geforderten Versionen durch Union der Tag-Mengen (mehr Redaktion ist immer sicher).

Die Durchsetzung ist serverseitig, in der Zelle. Die Ergebnisse:

Situation Zurückgegebener Wert Im Ergebnis?
Als cleartext gewährt Original ja
mask-Obligation *** ja
redact-Obligation ⟦redacted⟧ ja (überlebt für ORDER BY/GROUP BY)
deny / nicht gewährt entfernt aus der Projektion

Das ⟦redacted⟧-Sentinel bedeutet, dass die Spalte überlebt mit einem gesteuerten Wert (sodass die nachgelagerte Form stabil ist), statt zu NULL zu werden oder zu verschwinden — genau das macht cross-modale Joins fail-closed und das Modell komponierbar.

Die Kette ist kein vertrauter Header — sie ist ein signiertes Token. Die Zelle prägt und verifiziert ein HS256-JWT, dessen Payload die Kette selbst enthält, sodass ein Aufrufer sie nicht kürzen oder fälschen kann, ohne die Signatur zu brechen (eine fehlende/ungültige Kette → deny). Siehe Authentifizierung.

Zwei Dry-Run-Operationen berechnen die echte Komposition, ohne Daten zu bedienen (die Enterprise-Konsole macht sie zugänglich; die APIs liegen in der Zelle):

  • :simulate — eine Policy gegen eine Query als einzelnes Subject vorschauen.
  • :simulate-chain — das vollständige verfasste Policy-Set des Tenants über eine root → leaf-Kette kompilieren (das MEET) und den komponierten Scope plus eine per-Glied-Beitrags-Aufschlüsselung zurückgeben. Ein Glied ohne verfasste Policy wird markiert; das Meet leert sich zu einem fail-closed empty_meet.