Cada lectura a través de /osl/query està limitada
per un model de capacitat + permís: qui pregunta (una cadena de delegació de
subjectes), què li concedeix cada política sobre el graf semàntic, i com
componen aquests grants. És fail-closed per construcció — el defecte és
denegar, i qualsevol cosa no resolta es descarta, mai s’endevina.
L’accés s’avalua sobre una cadena de principals, root → leaf. El subjecte
actuant és l’última baula. La composició té dos nivells:
Dins d'un principal
Totes les polítiques que lliguen aquest principal es combinen: els grants
fan unió, l’obligació més forta guanya (deny > mask > redact), un
deny explícit preval, i les condicions (rang d’IP, finestra temporal) només
condicionen l’ALLOW — un deny és incondicional.
A través de la cadena
Les baules es combinen per MEET (intersecció): una entitat o columna es
concedeix només si cada baula la concedeix. El sostre de tier és el mínim
(més restrictiu) i la redacció requerida és la unió del que cada baula requereix.
Una baula buida o sense autoria col·lapsa el meet a deny.
L’scope semàntic d’una política és un conjunt de bindings, cadascun indexat
per un nodeId del domain-map (p. ex.
entity:Customer, metric:aum). Un binding declara:
Camp
Significat
attributeGrants[]
Grant per atribut: cleartext, mask, o deny
filters[] (+ filtersBool)
Predicats de fila que determinen quines files són visibles
Els grants són positius: una columna que no està concedida es redacta, mai es
retorna com a NULL ni es descarta silenciosament de l’schema. deny treu una
columna de la projecció completament; un deny global de la política preval sobre
el grant de qualsevol altre binding.
Les facetes de contingut es governen per versions de redacció amb nom — un
desacoblament d’un nom de cara a l’usuari respecte d’una identitat física i estable
a nivell de byte:
Una RedactionVersion té un nom (el handle de la consola, p. ex.
"PII básica") i un conjunt de tags (les classes de contingut que redacta,
p. ex. {email, phone}).
Els tags són la identitat física (byte-inalterada, usada com a clau de la
taula); el nom és només per a l’autoria.
La versió implícita original (sense tags) és la taula base.
Un facetGrant lliga un nom de versió requerit per faceta. La selecció és
exact-or-deny: el motor serveix la versió emmagatzemada els tags de la qual
coincideixen exactament, o denega la faceta — mai recorre a una versió més o menys
redactada.
A través d’una cadena, les versions requerides es componen per unió de conjunts
de tags (més redacció sempre és segur).
L’aplicació és server-side, a la cel·la. Els resultats:
Situació
Valor retornat
Al resultat?
Concedit cleartext
original
sí
Obligació mask
***
sí
Obligació redact
⟦redacted⟧
sí (sobreviu per a ORDER BY/GROUP BY)
deny / no concedit
—
descartat de la projecció
El sentinella⟦redacted⟧ significa que la columna sobreviu amb un valor
governat (així la forma downstream és estable), en comptes de convertir-se en NULL
o desaparèixer — que és el que fa que els joins cross-modal siguin fail-closed i el
model composable.
La cadena no és una capçalera de confiança — és un token signat. La cel·la
encunya i verifica un JWT HS256 el payload del qual conté la cadena mateixa, així un
cridador no la pot escurçar ni falsejar sense trencar la signatura (una cadena
absent/invàlida → deny). Vegeu Autenticació.
Dues operacions dry-run computen la composició real sense servir dades (la consola
Enterprise les exposa; les APIs són a la cel·la):
:simulate — previsualitza una política contra una query com un sol subjecte.
:simulate-chain — compila el conjunt complet de polítiques autoritzades del
tenant sobre una cadena root → leaf (el MEET), retornant l’scope compost més
un desglossament de contribució per baula. Una baula sense autoria es marca; el
meet es buida a un empty_meet fail-closed.