Saltar a contenido

Gerege Kiosk

Production · Capa 4 — Producto vertical · Repositorio: gerege-kiosk-mn · geregekiosk.mn

La plataforma unificada de terminales de autoservicio: basada en eID y potenciada con IA. Conecta el terminal instalado en un lugar público con el documento electrónico de identidad y permite al ciudadano obtener su certificado, pagar e imprimir el documento sin hacer cola ni acudir a un funcionario. Servicio de 24 horas, al margen del horario de atención.

Titularidad

La plataforma es propiedad de Gerege Kiosk ХХК, que también la explota. El código fuente reside en un repositorio privado y está construido sobre la base compartida open-gerege-core de Gerege Systems.

geregekiosk.mn sirve ahora Gerege Nexus

Comprobado el 2026-08-07: https://geregekiosk.mn/ devuelve un despliegue de Gerege Nexus: el título de la página es «Gerege Nexus» y la descripción es la de Nexus. El dominio tiene su propio certificado válido y está en 38.180.243.183.

Por tanto, el comportamiento de gerege-kiosk-mn descrito en esta página puede ya no coincidir con lo que sirve el dominio público. Contraste la versión que corre en un terminal con ese despliegue.

La idea central: aplicación fina, base gruesa

El backend Go de Kiosk es un único fichero. Autenticación, RBAC, pasarela de API, pipeline de IA, eID/SSO: todas las capacidades de base residen en el módulo github.com/gerege-systems/open-gerege-core; este repositorio lo trae por versión y lo arranca con su propio nombre:

func main() {
    server.ServiceName = "gerege-kiosk"

    app, err := server.NewApp()
    if err != nil { /* … */ }

    // Las rutas propias de la aplicación se añaden aquí:
    //   app.Router().Route("/api/xxx", xxx.Routes(app.Pool()))

    if err := app.Run(); err != nil { /* … */ }
}

Es la solución a la deuda técnica por sincronización de forks que se menciona en la página de Template Platform: antes el código base se copiaba en cada repositorio y cada mejora había que trasladarla a mano. Ahora Kiosk es un consumidor versionado de open-gerege-core: los parches de seguridad se propagan desde un único punto y la actualización se reduce a un comando, go get open-gerege-core@latest.

Capa Dónde vive Quién la posee
Backend base (autenticación, RBAC, IA, pasarela, migraciones) módulo open-gerege-core Gerege Systems
Punto de arranque, marca, configuración gerege-kiosk-mn/backend Gerege Kiosk ХХК
BFF de frontend, UI gerege-kiosk-mn/frontend Gerege Kiosk ХХК
Despliegue, vhost del edge gerege-kiosk-mn/deploy Gerege Kiosk ХХК

Estructura

gerege-kiosk-mn/
├── backend/     # Go · consumidor fino de open-gerege-core (cmd/api/main.go)
├── frontend/    # Next.js 15 BFF — Node 20, TanStack Query, mn/en/zh/ru
├── ios/         # Cliente SwiftUI de referencia (solo dialoga vía el BFF)
└── deploy/      # compose, vhost de edge nginx, certificado TLS de la BD interna

El backend base sigue Clean Architecture — handler → usecase → repository → domain, sin back-imports y sin ORM (SQL a mano sobre pgx).

Autenticación: solo Gerege SSO

En la pantalla de acceso hay un solo botón: Entrar con Gerege SSO. No hay contraseñas, ni registro por correo/OTP, ni flujo directo de eID.

graph LR
    C["Ciudadano / terminal"] --> W["geregekiosk.mn<br/>Next.js BFF"]
    W --> A["API de Kiosk"]
    A --> S["sso.gerege.mn<br/>Gerege SSO"]
    S --> E["eID Mongolia"]
    S -.->|"proxy eID"| A
  • Flujo de RP OIDC/api/auth/sso/startsso.gerege.mn/sso/callback. En móvil existe un flujo aparte de cliente público con PKCE (native).
  • Sesión — JWT access + refresh, con el refresh rotatorio; el cierre de sesión invalida el refresh y pone el access en una deny-list.
  • El token no llega al navegador: vive solo en una cookie httpOnly y todo pasa por el BFF.

¿Por qué Kiosk no es RP de eID por sí mismo?

Según la regla de frontera n.º 2, las aplicaciones de las capas 3–4 no acceden al eID directamente. Kiosk no posee credenciales de RP de eID: todo el trato con el eID pasa por Gerege SSO. Así las credenciales se concentran en un lugar y la cadena de auditoría no se rompe.

Perfil de PKI de eID: a través del proxy

El panel de PKI del ciudadano que ha entrado se obtiene mediante el proxy de eID del SSO. Kiosk llama con el access token del usuario y el SSO recupera los datos usando sus propias credenciales de eID.

Qué Dónde se ve
Resumen /me/eid/id
Certificados y estado /me/eid/certificates
Dispositivos asociados /me/eid/devices
Historial de autenticación/firma /me/eid/logs
Organizaciones vinculadas y firmantes autorizados /me/organizations

El caso en que el proxy está apagado (servicio eid-proxy inactivo en el SSO) o el token ha caducado lo gestiona la interfaz por separado, sin devolver un 5xx.

Proveedor OIDC por sí mismo

Kiosk puede ser a la vez relying party del SSO y proveedor de identidad. Con OAUTH_ISSUER y la state key configurados, se activa su propio proveedor OAuth2/OIDC en Go (sin Ory Hydra):

  • pantallas de login · consent · logout bajo /oauth,
  • registro de RP en la tabla oauth_clients, rotación de secretos,
  • consentimiento omitido para clientes de primera parte, y recordado,
  • discovery, userinfo, id_token — la clave de firma se guarda cifrada.

Así, las pequeñas aplicaciones que rodean a Kiosk pueden ofrecer «Sign in with Gerege Kiosk».

La superficie de cara al ciudadano

Sección Qué hace
/me/dashboard Panel personal
/me/services · /me/applications Catálogo de servicios, solicitudes y su avance
/me/references Certificados
/me/notifications Notificaciones
/me/payments Pagos
/me/appointments Citas
/me/organizations Organizaciones, membresías, permisos
/me/eid/sign Firma electrónica de un documento
/me/integrations Conexiones de terceros y Gerege Space
/me/ai · /me/translate Asistente de IA, traducción en directo

Al crear o buscar una organización, la consulta al registro estatal se hace con Gerege Verify. Los datos de organización quedan protegidos con RLS de Postgres para cada usuario.

Registro unificado de servicios

Componente R1 de Ring System: el pasaporte de servicio y la gestión de pruebas:

  • catálogo de servicios, versiones, publicación/archivado,
  • eventos vitales (life events): agrupar servicios según la situación del ciudadano,
  • pruebas (evidences) y panel once-only, que mide el cumplimiento del principio de no volver a pedir un documento ya aportado.

Los permisos son de dos niveles: registry.view (lectura) y registry.manage (escritura).

API Gateway

Catálogo de servicios gestionado desde admin: services · routes · consumers · API key · policy, más telemetría de peticiones (overview + logs).

Alcance actual

La pasarela es por ahora una capa de gestión y telemetría. La aplicación efectiva de las route/policy configuradas como proxy inverso real (rate-limit y cuotas a nivel de consumer) está en el plan.

Firma electrónica y sign relay

  • PAdES: firma de PDF desde el servidor mediante la interfaz /v3 de eID Mongolia, con certificado Document-Signer permanente (fail-closed en producción).
  • Sign relay: una pasarela que permite a RP de terceros firmar a través de las credenciales eID de la plataforma. Esta ruta no pasa por el BFF web, sino directamente del edge a la API (puerto loopback). El resultado se notifica por webhook.

Para la diferencia entre la firma personal del ciudadano con PIN2 y la firma de sistema Document-Signer, véase la página G-Sign.

Asistente de IA (Gemini)

Un pipeline sobre un cliente REST sin SDK:

Capacidad Detalle
Chat Mensajes de texto y de voz, function calling
STT Voz → texto
TTS Texto → voz (PCM→WAV)
Traducción Traducción en flujo continuo

System prompt de tres capas: salvaguardas fijadas en el código, más el alcance y las instrucciones que el administrador configura por base de datos. La capa de salvaguardas nunca es configurable.

La herramienta search_knowledge ancla la respuesta en datos reales de la base de conocimiento. La búsqueda es semántica: embedding de Gemini + proximidad cosenoidal sobre pgvector, con retroceso a ILIKE si falla.

Si Gemini falla momentáneamente, el chat no devuelve un 5xx, sino una respuesta degradada (degraded: true) en el idioma del usuario. Las rutas /ai/* están limitadas a unas 20 peticiones por minuto y por IP.

Integraciones y almacenamiento

  • Conexiones OAuth de terceros: Google Drive · Google Meet · Dropbox. Los tokens se guardan cifrados con AES-256-GCM; si no hay credenciales configuradas, la tarjeta correspondiente aparece inactiva con el estado «Próximamente».
  • Gerege Space: el almacenamiento SFTP propio de la aplicación, con cuota por usuario. La host key de SFTP se verifica (obligatorio en producción; de lo contrario, fail-closed).

Permisos, administración y auditoría

  • RBAC: roles dinámicos y catálogo de permisos, modelo de cuatro niveles (superadmin → admin → manager → user).
  • Super admin: cuenta aparte, flujo de onboarding con MFA (allow-list de invitaciones → Google → eID → OTP por correo → TOTP + códigos de recuperación). Se guarda en su propia tabla, así que una misma persona puede ser admin por eID y super admin.
  • Audit log: encadenado por hash, solo de adición; con lectura para el administrador y endpoint de comprobación de integridad.
  • Security events: ingesta y panel de supervisión.
  • Apariencia del sitio: accent / fuente / densidad / tema configurables por el administrador, con anulación por usuario.

Seguridad

Control Implementación
Aislamiento de datos RLS de Postgres (ENABLE + FORCE); la api se conecta con un rol no superuser y en el arranque se comprueba que se aplica
Sesión Cookie httpOnly; el token nunca llega al JS del cliente
CSRF Doble protección: cabecera propia + comprobación de origin (en todas las rutas mutantes del BFF)
Cabeceras CSP · HSTS · COOP/COEP/CORP, allow-list de CORS
Límite de frecuencia Acceso ~5 peticiones/min (cuerpo limitado a 4 KiB), aplicación 50 r/s, /ai/* ~20/min
Conexión a la BD En producción sslmode=verify-full — TLS con una CA interna
Endpoints de observación En producción, /metrics y /swagger cerrados con bearer token
Confianza en el proxy Si TRUSTED_PROXIES no está definido, X-Forwarded-For no se considera fiable (evita falsear rate-limit y auditoría)

Para los requisitos comunes del ecosistema, véase la página Seguridad.

Observabilidad

Trazas de OpenTelemetry + métricas de Prometheus + logs estructurados de Zap. En la telemetría el servicio aparece con el nombre gerege-kiosk.

Despliegue

Stack de Docker Compose: db (Postgres 16 + pgvector) · redis · migrate (de un solo uso) · api · web. El navegador solo llega a web; api/db/redis permanecen en la red interna y no abren puertos públicos.

Tres decisiones del despliegue merecen atención:

  1. La migración es un paso aparte, no parte de up -d. Antes, cada nueva ejecución de migrate recreaba api y web, y hasta un commit que no tocaba código provocaba un 502 de un segundo.
  2. Si nada ha cambiado, no se mueve nada. La construcción de Docker no es reproducible, así que del mismo código sale un ID de imagen nuevo. Por eso, si HEAD no ha cambiado, el despliegue se salta por completo.
  3. Los servicios de datos no se construyen en cada despliegue: recrear db corta todas las conexiones activas a la base.

El vhost del edge nginx lo posee este repositorio: en cada despliegue se instala en conf.d, se valida con nginx -t y se aplica con un reload; si la prueba falla, se restaura la configuración anterior. Es el mismo modelo que en docs.gerege.mn, el Developer Portal y la Template Platform.

Idiomas

Interfaz y documentación en cuatro idiomas: Монгол · English · 中文 · Русский. La integridad de los diccionarios del frontend la impone una prueba: si falta una clave en algún idioma, la CI falla.

Estado actual

Production En funcionamiento en geregekiosk.mn. Las capacidades de la plataforma base están heredadas por completo; los flujos propios del negocio de terminales siguen añadiéndose.

Próximos pasos: aplicación efectiva de las reglas por la pasarela, respuestas de chat en streaming (SSE), CSP basada en nonce, copia de seguridad automática de la BD con prueba de restauración y entorno de staging.

Páginas relacionadas