Autenticación y autorización¶
Todas las plataformas del ecosistema usan un mismo modelo de autenticación. Esta página explica ese modelo y ofrece indicaciones prácticas a las relying parties (RP) que se incorporan.
Visión general del modelo¶
sequenceDiagram
participant U as Usuario
participant RP as Aplicación RP
participant SSO as Gerege SSO
participant EID as eID Mongolia
participant P as Teléfono
U->>RP: Pulsa «Entrar»
RP->>SSO: Authorization request (code + PKCE)
SSO->>EID: Inicio del acceso con eID
EID->>P: QR / deep link / push
P-->>EID: Aprobación con PIN1
EID-->>SSO: Ciudadano identificado
SSO-->>RP: Authorization code
RP->>SSO: code + code_verifier → tokens
SSO-->>RP: access + refresh + id_token
RP->>SSO: /userinfo
SSO-->>RP: Datos del usuario
Principio central: el RP nunca accede directamente al eID. Todo pasa por el SSO.
Métodos de acceso¶
| Método | Tipo | Nota |
|---|---|---|
| eID | Principal | Código QR · deep link móvil · push por número de registro |
| Secundario | La primera vinculación exige verificación por eID |
Lo que no existe: contraseñas, acceso por correo/OTP, acceso por OTP SMS.
Es una decisión deliberada. Una contraseña que no existe no se filtra, no se reutiliza y no cae en un phishing.
Dónde autentica una plataforma — AUTH_MODE¶
Una plataforma del ecosistema puede desempeñar uno de dos papeles:
- Servicio de identidad — autentica a los usuarios por sí misma. La
tarjeta de acceso (eID QR / número de registro · Google) aparece en su propia
portada y en
/login. - Parte confiante (RP) — delega el acceso a un SSO superior. Al pulsar «Acceder» se redirige al SSO, el usuario se autentica allí y regresa.
No se trata de una diferencia de código, sino de configuración. Lo decide
el ajuste AUTH_MODE del backend:
| Valor | Superficie de acceso |
|---|---|
provider |
La tarjeta de acceso se muestra en esta plataforma |
client |
Redirección al SSO superior (SSO_ISSUER) |
Si no se define, se deduce de si SSO_CLIENT_ID está configurado.
El frontend obtiene su modo del endpoint público GET /api/v1/site/auth — sin
autenticación y sin secretos en la respuesta:
Ser issuer es una cuestión APARTE
AUTH_MODE responde a «dónde inician sesión los usuarios de esta
plataforma». Si la plataforma es además issuer para otras
aplicaciones lo decide por separado OAUTH_ISSUER. Ambos pueden estar
activos a la vez — un montaje encadenado en el que la plataforma emite
tokens a terceros mientras envía a sus propios usuarios a un IdP superior.
Resultado práctico: un servicio SSO y una plataforma que lo consume ejecutan el mismo código. La misma imagen de Docker arranca en cualquiera de los dos papeles según su entorno. Véase Código compartido.
PIN1 frente a PIN2¶
| PIN1 | PIN2 | |
|---|---|---|
| Certificado | Authentication | Signing |
| Propósito | Entrar | Firmar |
| Consecuencia jurídica | Ninguna | Sí — no repudio |
Entrar ≠ firmar
Haber entrado con PIN1 no significa que la persona haya consentido nada. Para actos con consecuencias jurídicas (contrato, concesión de permisos, obligación financiera) hay que firmar aparte con PIN2.
Características técnicas de OIDC¶
| Elemento | Valor |
|---|---|
| Flujo | Authorization code + PKCE (S256) |
| Access token | Opaco |
id_token |
JWT, RS256 |
| Refresh token | Rotatorio, con detección de reutilización |
| Máquina a máquina | client_credentials |
| Discovery | /.well-known/openid-configuration |
| UserInfo | /userinfo |
Rotación del refresh token¶
Cada vez que se usa un refresh token se emite uno nuevo y el anterior queda invalidado. Si se reutiliza el token antiguo, es señal de robo, así que se invalida toda la cadena.
Por eso el RP debe guardar el token nuevo en cuanto refresca. Si conserva el viejo, el siguiente refresco tumbará todas las sesiones.
Sesión y cierre de sesión¶
- La sesión es un par JWT access + refresh.
- El cierre de sesión invalida tanto el refresh como el access (deny-list de access).
- Tras cerrar sesión, la persona vuelve al dominio desde el que empezó.
Pasos para ser un RP¶
1. Registrar la aplicación¶
Cree un cliente en la consola de Gerege SSO. Obtendrá:
client_id, client_secret.
Qué preparar para el registro:
- Los redirect URI (de todos los entornos — dev / staging / prod)
- El post-logout redirect URI
- Los scopes solicitados
- El nombre y el logotipo de la aplicación (aparecerán en la pantalla de consentimiento)
2. Leer el discovery¶
No codifique los endpoints a mano: léalos de aquí.
3. Authorization request¶
Implemente el flujo authorization code + PKCE (S256). Use obligatoriamente
state y nonce.
4. Intercambiar el token¶
Code + code_verifier → access_token, refresh_token, id_token.
5. Validar el id_token¶
Compruebe obligatoriamente:
- [ ] La firma RS256 — con la clave obtenida del JWKS
- [ ] Que
isscoincide con el issuer del discovery - [ ] Que
audes suclient_id - [ ] Que
expno ha vencido - [ ] Que
noncecoincide con el que usted envió
6. Datos del usuario¶
Obténgalos del endpoint /userinfo.
Errores frecuentes¶
El redirect URI debe coincidir con exactitud
Carácter por carácter: importan la / final, http frente a https, el
puerto y la subruta. Es el fallo de integración más común.
Lista de comprobación al cambiar de dominio
Al cambiar de dominio o de marca, actualice las tres cosas a la vez. Si olvida una, el acceso fallará en silencio:
- [ ] La lista de redirect URI en el SSO
- [ ] Los SAN del certificado TLS
- [ ] Las direcciones de issuer / endpoint en la configuración del RP
PKCE no se salta
PKCE se usa incluso en clientes confidenciales. El coste añadido es mínimo y la protección es real.
Modelo de autorización¶
Tras la autenticación empieza la comprobación de permisos. La jerarquía estándar del ecosistema:
Véase Convenciones comunes para el detalle.
A nivel de organización: la membresía está protegida con RLS de Postgres: cada usuario ve solo los datos de la organización a la que pertenece. Es una restricción a nivel de base de datos, no una comprobación en el código de la aplicación.
Conceder permisos de manager exige aprobación con PIN2 — véase
Convenciones comunes.