Convenciones comunes¶
Los estándares de facto que se repiten en todos los repositorios del ecosistema. No nacieron de una especificación formal: son las reglas que cuajaron tras resolver varias veces los mismos problemas reales. Una plataforma nueva debe seguirlas desde el principio.
Identity casing¶
La regla: guardar en la base de datos todo el texto de identidad en minúsculas. La búsqueda no distingue mayúsculas. Para mostrarlo se convierte a la forma estándar (números de registro en mayúsculas, nombres en Title Case).
Campos exentos — estos se guardan tal como llegan:
| Campo | Por qué |
|---|---|
etsi_identifier |
El formato lo define un estándar |
| DN del certificado | Entra en la firma criptográfica; no debe alterarse |
Campos *_latin |
Transliteración latina — conserva su forma original |
document_number |
Número de un documento oficial |
| Valores de hash | Cada bit cuenta |
De dónde salió esta regla
Un ciudadano se registraba como АБ12345678 y luego intentaba entrar como
аб12345678: el sistema veía a otra persona y aparecía una cuenta
duplicada. Normalizar las mayúsculas en la capa de almacenamiento elimina
toda esa clase de error.
Jerarquía de roles¶
Reglas duras:
| Rol | Puede | NO puede |
|---|---|---|
superadmin |
Añadir/eliminar cuentas admin | — |
admin |
Conceder permisos de manager | Gestionar cuentas admin |
manager |
Operaciones del día a día | Añadir personas |
user |
Sus propias acciones | Conceder permisos |
El super admin es una cuenta aparte con MFA. Se crea mediante un asistente de onboarding: allow-list de invitaciones → Google → eID → OTP por correo → TOTP + códigos de recuperación. Se guarda en su propia tabla, indexada por la identidad de Google.
Consecuencia práctica: una misma persona puede ser admin por eID y super admin por Google — dos cuentas distintas, dos accesos distintos. Todo acceso de super admin está protegido con MFA.
Los permisos de admin se conceden por número de registro, contra un usuario dado de alta en el eID local.
Concesión de permisos validada con firma¶
La regla: conceder a alguien permisos de manager en una organización envía
a esa persona un push de eID SIGN, y la concesión solo pasa a ACTIVE tras
aprobarla con PIN2.
Por qué: conceder permisos es un acto con consecuencias jurídicas. Si un administrador nombra responsable a alguien de forma unilateral, esa persona podría negarlo después. Una firma con PIN2 aporta no repudio: cierra la puerta al «yo nunca di mi consentimiento».
Reglas de callback¶
La regla: el callback solo se devuelve en flujos same-device. En cualquier otro caso se hace poll de la sesión.
| Situación | Mecanismo |
|---|---|
| Usuario en un solo dispositivo (deep link) | Callback |
| Código QR — segundo dispositivo | Poll de sesión (long-poll) |
| Notificación push | Poll de sesión |
El motivo: en un flujo iniciado en otro dispositivo, el callback no sabe adónde volver. El poll convierte al navegador de origen en la fuente de verdad y mantiene el flujo inequívoco.
Deep links de terceros — se transmiten como parámetro de callback; al terminar, la aplicación correspondiente pasa a primer plano.
Vinculación con Google¶
La regla: antes de vincular una cuenta de Google, el usuario debe verificarse con eID. La primera vinculación la ata a una persona real; después puede entrar directamente con Google. También se puede desvincular.
El motivo: cualquiera puede crear una cuenta de Google. Por sí sola no puede aceptarse como identificación ciudadana. Una vez atada mediante eID, esa cuenta de Google apunta a un ciudadano concreto.
RP ↔ rp_app¶
La regla: en el eID solo se registra el
RP. Las distintas aplicaciones o subsistemas bajo un mismo RP se transmiten
mediante los campos rp_app / rp_app_url.
Así los registros y la pantalla del usuario muestran qué aplicación hizo la petición — sin registrar un RP por aplicación ni repartir credenciales.
El cierre de sesión termina en el dominio donde empezó¶
La regla: al cerrar sesión, la persona vuelve al dominio desde el que
empezó; no se la lanza al /login del SSO.
Por qué: el usuario estaba en la aplicación del RP. Acabar en la pantalla de acceso de un dominio completamente desconocido resulta desorientador. El cierre de sesión debe terminar dentro de la aplicación en la que comenzó.
Las credenciales tienen una única fuente¶
La regla: los clientes OAuth y sus secretos se crean solo en el SSO y solo allí viven. Ningún otro sistema los crea, los guarda ni los muestra.
El Developer Portal es el caso de prueba de esta regla: ofrece indicaciones para registrar una aplicación, pero no crea clientes; solo enlaza en profundidad con la consola del SSO.
La documentación es código¶
La regla: cada repositorio tiene su directorio docs/ y su sitio MkDocs. La
documentación vive en el mismo repositorio que el código y cambia con él en
el mismo PR.
Cobertura lingüística: como mínimo MN + EN; los repositorios principales añaden ZH · RU. Véase Multilingüismo para el detalle.
Clean Architecture — sin back-imports¶
La regla: handler → usecase → repository → domain. Las dependencias van en
una sola dirección. El núcleo de negocio (domain, usecase) nunca
importa un framework web.
Comprobación sencilla: si un fichero dentro de domain/ importa net/http o
chi, la regla se ha roto.
Lista de comprobación para añadir una plataforma¶
- [ ] La autenticación va por el SSO como RP de OIDC — sin sistema de contraseñas propio
- [ ] Jerarquía de roles
superadmin → admin → manager → user - [ ] Texto de identidad en minúsculas en la BD, campos exentos identificados
- [ ] RLS de Postgres activa + guard de aplicabilidad en el arranque
- [ ] Registro de auditoría — encadenado por hash
- [ ] Cabeceras de seguridad, allow-list de CORS y rate limits configurados
- [ ]
/metricsy/swaggercerrados en producción - [ ]
docs/+ un sitio MkDocs, MN/EN - [ ] CI: build + pruebas + comprobación estricta de la documentación