Ir al contenido

Acceso y capacidades

Cada lectura a través de /osl/query está limitada por un modelo de capacidad + permiso: quién pregunta (una cadena de delegación de sujetos), qué le concede cada política sobre el grafo semántico, y cómo componen esos grants. Es fail-closed por construcción — el default es denegar, y cualquier cosa sin resolver se descarta, nunca se adivina.

Un sujeto es un principal en una cadena de delegación. Tiene uno de tres tipos descriptivos:

Tipo Es
human Un usuario (nombre de usuario / email)
agent Un agente de IA (con una etiqueta de proveedor: Claude, ChatGPT, Gemini, …, o custom)
machine Una carga de trabajo / cuenta de servicio

La cadena de delegación, compuesta por MEET

Sección titulada «La cadena de delegación, compuesta por MEET»

El acceso se evalúa sobre una cadena de principals, raíz → hoja. El sujeto que actúa es el último eslabón. La composición tiene dos niveles:

Dentro de un principal

Todas las políticas que vinculan a ese principal se combinan: los grants se unen, gana la obligación más fuerte (deny > mask > redact), un deny explícito prevalece, y las condiciones (rango de IP, ventana de tiempo) solo condicionan el ALLOW — un deny es incondicional.

A lo largo de la cadena

Los eslabones se combinan por MEET (intersección): una entidad o columna se concede solo si cada eslabón la concede. El tope de tier es el mínimo (el más restrictivo) y la redacción requerida es la unión de lo que exige cada eslabón. Un eslabón vacío o sin autorizar colapsa el meet a deny.

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

El scope semántico de una política es un conjunto de bindings, cada uno indexado por un nodeId del domain-map (p. ej. entity:Customer, metric:aum). Un binding declara:

Campo Significado
attributeGrants[] Grant por atributo: cleartext, mask o deny
filters[] (+ filtersBool) Predicados de fila que acotan qué filas son visibles
grantedMetrics[] Grants de métrica autónomos
facetGrants[] Grant de contenido por faceta (ver versiones de redacción)

Los grants son positivos: una columna sin grant se redacta, nunca se devuelve como NULL ni se descarta silenciosamente del schema. deny elimina una columna de la proyección por completo; un deny global de política prevalece sobre el grant de cualquier otro binding.

Las facetas de contenido se gobiernan por versiones de redacción con nombre — un desacople entre un nombre de cara al humano y una identidad física y estable a nivel de bytes:

  • Una RedactionVersion tiene un nombre (el handle de la consola, p. ej. "PII básica") y un conjunto de tags (las clases de contenido que redacta, p. ej. {email, phone}).
  • Los tags son la identidad física (sin cambio de bytes, usados como clave de tabla); el nombre es solo para la autoría.
  • La versión implícita original (sin tags) es la tabla base.
  • Un facetGrant vincula un nombre de versión requerida por faceta. La selección es exacta-o-deny: el motor sirve la versión almacenada cuyos tags coinciden exactamente, o deniega la faceta — nunca recurre a una versión más o menos redactada.
  • A lo largo de una cadena, las versiones requeridas componen por unión de conjuntos de tags (más redacción siempre es seguro).

La aplicación es server-side, en la celda. Los resultados:

Situación Valor devuelto ¿En el resultado?
cleartext concedido original
obligación mask ***
obligación redact ⟦redacted⟧ sí (sobrevive para ORDER BY/GROUP BY)
deny / sin grant descartada de la proyección

El centinela ⟦redacted⟧ significa que la columna sobrevive con un valor gobernado (así la forma downstream es estable), en vez de convertirse en NULL o desaparecer — que es lo que hace fail-closed a los joins cross-modal y componible al modelo.

La cadena no es una cabecera confiada — es un token firmado. La celda acuña y verifica un JWT HS256 cuyo payload contiene la propia cadena, de modo que un llamante no puede acortarla ni falsificarla sin romper la firma (una cadena ausente/inválida → deny). Ver Autenticación.

Dos operaciones dry-run calculan la composición real sin servir datos (la consola Enterprise las expone; las APIs están en la celda):

  • :simulate — previsualiza una política contra una consulta como un solo sujeto.
  • :simulate-chain — compila el conjunto completo de políticas autorizadas del tenant sobre una cadena root → leaf (el MEET), devolviendo el scope compuesto más un desglose de contribución por eslabón. Un eslabón sin autorizar se marca; el meet se vacía a un empty_meet fail-closed.