Skip to main content
Traducción. Autoritativo: fs-idn-0002-permission-registry-rbac.md.

Contexto

DEC-D5 fijó el modelo: cada endpoint declara exactamente un permiso {module}.{resource}.{action}; los permisos se agrupan en roles; los roles se asignan a usuarios y a máquinas. Esta feature es ese modelo. La decisión que lo hace confiable es que el registro se genera, no se mantiene. Las rutas declaran su permiso en código; el registro se construye desde esas declaraciones; CI falla si la base y el union generado discrepan. Una lista de permisos mantenida a mano se separa de lo que el código verifica en semanas, y una lista divergente es peor que ninguna: le dice al administrador algo falso sobre lo que acaba de otorgar. Que las máquinas lleven roles es la segunda decisión de carga. Una API key no es un caso especial con su propio lenguaje de scopes; es un sujeto con asignaciones de rol, verificado idénticamente. Eso es lo que permite que una pantalla de consentimiento OAuth2 (FS-IDN-0007) muestre permisos reales en vez de scopes inventados.

Alcance (normativo)

  • identity.permissions: el registro generado, sembrado desde las declaraciones de ruta.
  • identity.roles: roles de sistema sembrados por organización, más roles definidos por el tenant.
  • identity.role_permissions y identity.role_assignments con sujeto polimórfico.
  • Resolución de autorización: sujeto → roles → permisos, cacheada.
  • Chequeos de CI: cada ruta declara exactamente un permiso; cero divergencia entre código y base.

Fuera de alcance (normativo)

  • Permisos por registro. Son por acción, nunca por fila. “Puede editar esta campaña pero no aquella” queda fuera deliberadamente: es donde los modelos de autorización dejan de ser explicables para quien tiene que configurarlos.
  • Verificaciones de permiso dentro de los módulos. La capa de API resuelve el contexto y lo pasa hacia abajo (ADR-022).
  • Scopes OAuth — FS-IDN-0007 renderiza agrupaciones de estos permisos; no define un segundo modelo.

Comportamiento (normativo)

  1. Un permiso es {module}.{resource}.{action}, en minúsculas, separado por puntos. Lo crea una ruta declarándolo, nunca a mano y nunca un tenant.
  2. Cada endpoint de la plataforma declara exactamente uno. Cero es un defecto; dos también. CI impone ambos.
  3. El registro se genera en build y se siembra. La divergencia entre las declaraciones del código y la base falla CI — la misma disciplina que los catálogos paramétricos.
  4. Los roles de sistema se siembran por organización: owner, admin, member, analyst, support. Son is_system y el tenant no puede editarlos ni borrarlos, solo copiarlos como punto de partida.
  5. Los roles definidos por el tenant se gatean por plan.
  6. Una role_assignment tiene sujeto polimórfico: una membresía o una credencial de máquina. La resolución y la verificación son el mismo camino de código para ambos.
  7. La resolución es sujeto → roles → permisos, cacheada por sujeto con invalidación al cambiar una asignación. Una verificación de permiso hace cero consultas en el camino caliente.
  8. Los permisos son solo aditivos. No hay reglas de denegación: la unión de los roles del sujeto es lo que puede hacer. Las reglas de denegación hacen imposible razonar sobre el permiso efectivo, y todo administrador que haya depurado una sabe por qué.
  9. El rol owner siempre tiene todos los permisos, incluidos los futuros.
  10. Los permisos sensibles —core.contacts.read_national_id, identity.impersonation.start, identity.roles.updatenunca están en un rol sembrado por debajo de admin, y otorgar uno queda auditado con el actor que lo otorgó.

Datos (normativo)

API (normativo)

Eventos (normativo)

identity.role.assigned y identity.role.revoked, con sujeto, rol y actor. No se ofrecen como webhooks salientes en F1.

Criterios de aceptación (normativo)

  1. Una ruta que declara cero o dos permisos falla CI, cada caso con su fixture.
  2. Quitar un permiso de las declaraciones dejándolo sembrado falla el chequeo de divergencia nombrando el código.
  3. Una verificación de permiso hace cero consultas con la caché tibia.
  4. Una API key y un usuario con el mismo rol se autorizan idénticamente en todo el conjunto de endpoints.
  5. Revocar una asignación invalida la caché y surte efecto en el siguiente request, no al expirar.
  6. Un tenant no puede editar ni borrar un rol de sistema.
  7. Otorgar un permiso sensible escribe una fila de auditoría con el actor.
  8. Negativo: no existe regla de denegación en el modelo, y ningún endpoint resuelve permisos consultando tablas de identity desde otro módulo.

Ejecución

Un solo slice, comando síncrono. El generador y la función de resolución viven en packages/core; los chequeos de CI llegan con TS-005. Las declaraciones de ruta son la fuente: el registro está aguas abajo del código, nunca arriba.

Preguntas abiertas

Changelog

Registro de entrega

Aún no implementado.