Servicio principal de la plataforma de verificación de identidad.
Implementado en Java 21 con Quarkus, expone la API REST de
enrolamiento y verificación (v3) y se despliega en Kubernetes
dentro del entorno del cliente.
Despliegue en Kubernetes
Imagen: registry privado de ParaguayDev, etiqueta con versionado semántico (p. ej. v3.4.1).
Recursos: réplicas mínimas 2 (alta disponibilidad); límites de CPU/memoria definidos por entorno.
Service: ClusterIP interno; el Ingress expone únicamente la ruta /api/v3.
Ingress: TLS gestionado por Traefik con certificados Cloudflare.
Probes: liveness en /q/health/live y readiness en /q/health/ready.
Configuración por variables de entorno
QUARKUS_HTTP_PORT=8080
DB_URL=jdbc:postgresql://<host>:5432/gnbiometrics
DB_USERNAME=gnb_app
DB_PASSWORD=****
JWT_PRIVATE_KEY=**** # firma de tokens móviles
CEPH_ENDPOINT=https://s3.<dominio-cliente>:443
CEPH_ACCESS_KEY=****
CEPH_SECRET_KEY=****
AUTH_TOKEN_TTL_MINUTES=15 # 15–30 min según política del cliente
VLM_FALLBACK_URL=http://worker-vlm:8090
Secretos y control de acceso
Las credenciales de base de datos, claves JWT y credenciales S3 se inyectan como Kubernetes Secrets (nunca en imágenes ni en valores planos del manifiesto).
Control de acceso por rol (RBAC) con integración al directorio activo del cliente; el acceso administrativo requiere segundo factor.
Los logs de auditoría se emiten en formato estructurado (JSON) y se retienen según la política del cliente.
Métricas y observabilidad
El servicio expone métricas Prometheus en /q/metrics
(latencia, tasa de error, conteo de operaciones). Se recomienda
integrarlo con el stack de monitoreo del cliente y alertar sobre
latencia p95 y disponibilidad.
Validación post-deploy: consulte los ítems
correspondientes en la checklist (health
checks, endpoints v3, latencia y escritura en base de datos).
Componente 02 · Datos
Base de Datos — PostgreSQL 17 / SQL Server 2022
La plataforma soporta dos motores de base de datos según la
política del cliente: PostgreSQL 17 como motor primario y
Microsoft SQL Server 2022 como opción para entornos con
estándares corporativos de Microsoft.
PostgreSQL 17 (motor primario)
Esquema:gnb con tablas de perfiles, operaciones, políticas y auditoría.
Aislamiento multi-tenant:Row-Level Security (RLS) activado para separar datos por cliente y entorno.
Migraciones: versionadas con Flyway; el esquema se aplica de forma idempotente al desplegar.
Deduplicación: índice único sobre identificador biométrico normalizado para evitar perfiles duplicados.
Respaldo:pg_dump programado + WAL archiving; retención definida por el cliente.
SQL Server 2022 (opción corporativa)
Scripts DDL: se entregan scripts idénticos en estructura (CREATE TABLE, índices y restricciones) para el motor Microsoft.
Compatibilidad: el mapeo de tipos y funciones se documenta en la guía de migración entregada al cliente.
Respaldo:BACKUP DATABASE con compresión y verificación periódica de restauración.
Cifrado en reposo y en tránsito (TLS 1.2+); credenciales de aplicación con mínimo privilegio (gnb_app, sin DDL en producción).
Pruebas de restauración de respaldo al menos una vez por trimestre, con evidencia registrada.
Importante: el cambio de motor requiere
re-ejecutar la validación funcional completa (flujos enroll y
verify) — ver checklist post-deploy.
Componente 03 · Almacenamiento
Almacenamiento de Objetos — Ceph RGW
Los documentos e imágenes de verificación se almacenan en un
bucket privado Ceph RGW (compatible con la API S3). El bucket
es propiedad del cliente y reside en su infraestructura.
Credenciales: par access key / secret key emitido por el RGW para la aplicación (se inyectan como Secret en Kubernetes).
Endpoint:https://s3.<dominio-cliente> con TLS; la API lo consume vía SDK compatible S3.
Versiones: se recomienda habilitar versioning para recuperación ante borrados accidentales.
Política de ciclo de vida y retención
Regla de expiración automática de objetos a los 90 días (configurable según política del cliente).
Los recibos firmados P-256 y metadata de auditoría se conservan por separado y por más tiempo que las imágenes.
El borrado se realiza de forma diferida y registrada (soft-delete) para soportar requerimientos legales.
Acceso mediante URLs firmadas
El Web Admin y la API generan URLs presignadas con vigencia
corta (5 minutos) para visualización; nunca se exponen URLs públicas
permanentes de objetos biométricos.
Validación: subir/descargar un objeto de
prueba, verificar expiración de URL presignada y revisar la regla de
ciclo de vida aplicada.
Componente 04 · Gestión
Web Admin
Panel de administración que utiliza el personal operativo del
cliente para gestionar la plataforma: operaciones de verificación,
políticas, usuarios y auditoría.
Acceso y seguridad
Publicado bajo subdominio propio y protegido por Cloudflare Access (misma política que esta documentación).
Autenticación contra el directorio activo del cliente + segundo factor obligatorio.
Roles: operador (consulta y reproceso) y administrador (políticas, usuarios, parámetros).
Funcionalidades principales
Operaciones: búsqueda, detalle y reproceso de verificaciones fallidas.
Políticas: configuración de criterios de verificación (umbrales, criterios requeridos).
Deduplicación: gestión de perfiles duplicados detectados por el backend.
Auditoría: registro inmutable de acciones administrativas (quién, qué, cuándo).
Parámetros: TTL de tokens, URLs de fallback VLM y configuración de bucket.
Despliegue
Imagen servida por nginx, misma red Traefik que el resto de los servicios; solo HTTPS.
Se comunica con la API Core únicamente mediante red interna (sin exposición pública de la API administrativa).
Componente 05 · Integración
SDK Móvil — Android / iOS
Biblioteca de integración que se embebe en la aplicación móvil del
cliente. Permite capturar el documento y la selfie, ejecutar la
verificación de vida y completar los flujos de enrolamiento y
verificación contra la API Core.
Capacidades
Captura de documento (frente y dorso) con guía de encuadre y corrección de reflejos.
Selfie con verificación de vida (liveness) para detectar presentación (PAD).
Flujos: enrolamiento (enroll) y verificación (verify) contra la API v3.
Recibos firmados: cada operación genera un recibo con firma P-256 para integridad de extremo a extremo.
El SDK no almacena datos biométricos en el dispositivo: las imágenes se transmiten cifradas y se eliminan tras la respuesta.
Versionado semántico; el cliente recibe notas de versión y aviso de cambios incompatibles con 30 días de anticipación.
Entorno de pruebas
Se entrega un entorno sandbox con datos sintéticos para validar
la integración sin exponer información real del cliente, junto con la
documentación de referencia de la API (OpenAPI v3).
Componente 06 · Visión por computadora
Core de Visión — Worker Python con ONNX
Servicio Python que ejecuta el análisis biométrico con modelos
ONNX Runtime: extracción de datos del documento (OCR/MRZ),
coincidencia facial y detección de presentación (PAD).
Funciones
Análisis de documento: OCR y lectura MRZ con tolerancia a rotación y condiciones de captura adversas.
Coincidencia facial (face match): comparación selfie vs. documento con soporte multi-orientación.
Liveness / PAD: modelo fas_128.onnx para detectar ataques de presentación.
Resultados: devuelve criterios evaluados, puntajes y confianza por criterio.
Despliegue
Imagen: Python 3.11 + ONNX Runtime; se despliega como Deployment en Kubernetes (o contenedor sidecar según topología del cliente).
Recursos: CPU suficiente para inferencia en tiempo aceptable; opcionalmente GPU si el cliente la habilita.
Endpoints:/v1/document/analyze, /v1/biometrics/verify; solo accesible por red interna.
Escalado: réplicas según carga esperada; las operaciones son procesadas de forma asíncrona vía cola de trabajo.
Calidad y monitoreo
Métricas de latencia de inferencia, tasa de fallo de OCR y distribución de puntajes.
Registro de versión del modelo en cada resultado para trazabilidad de decisiones.
Cuando la confianza del worker no alcanza el umbral configurado, se activa el fallback VLM (siguiente componente).
Componente 07 · Resiliencia
Fallback VLM — Qwen (Dell GB10) / Gemini
Mecanismo de respaldo por modelo de lenguaje visual (VLM):
cuando el worker ONNX no alcanza el umbral de confianza o falla, una
segunda opinión analiza las mismas imágenes y emite un veredicto de
apoyo. Garantiza continuidad operativa para el cliente.
Modos de operación
Local / edge:Qwen-VL ejecutándose en un Dell GB10 (Grace Blackwell) dentro de la red del cliente — sin salida de datos al exterior.
Nube:Gemini (Google Cloud Vertex AI) como segunda alternativa cuando el entorno lo permite.
Reglas de activación
Confianza del worker ONNX por debajo del umbral configurado (p. ej. < 70%).
Timeout o error del worker: la operación se reintenta una vez y luego deriva al VLM.
El resultado del VLM nunca reemplaza la decisión biométrica; aporta una evaluación complementaria registrada en auditoría.
Privacidad y datos
Las imágenes enviadas al VLM se anonimizan (recorte de metadatos) y se eliminan tras la respuesta.
El uso del modo nube requiere aprobación expresa del cliente (política de salida de datos); por defecto opera solo en modo local.
Toda invocación al VLM queda registrada con motivo, modelo usado y resultado.
Disponibilidad: la caída del VLM no bloquea el
servicio: degrada la operación con el resultado del worker y marca la
verificación para revisión manual en el Web Admin.
Componente 08 · Seguridad móvil
Autenticación por Token — Aplicación Móvil
La aplicación móvil del cliente se autentica contra la API Core con
credenciales de máquina (modelo client credentials). El flujo
completo se administra en el backend; el SDK solo transporta el token.
1. Emisión de credenciales
El backend genera un par client_id / client_secret por entorno (sandbox, homologación, producción).
El client_secret se entrega al cliente por canal seguro (gestor de secretos del cliente, nunca por correo).
Las credenciales se almacenan únicamente en el backend; no se embeben en la aplicación móvil.
2. Obtención del JWT
POST /api/v3/auth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=<id>&client_secret=<secret>
TTL configurable de 15 a 30 minutos según la política del cliente; el valor se define por entorno.
El token incluye claims de entorno, cliente y alcance (scope: enroll, verify, read).
3. Uso del token en el SDK
El SDK adjunta Authorization: Bearer <token> en cada llamada a la API.
El SDK solicita un token nuevo de forma automática antes de la expiración (sin intervención del usuario).
Los tokens se conservan en memoria; no se persisten en almacenamiento del dispositivo.
4. Revocación y rotación
Revocación de token: el backend mantiene una denylist de JWT revocados (por incidente o cierre de sesión) y la valida en cada request.
Revocación de credenciales: al revocar un client_secret, todos los tokens emitidos con él quedan inválidos de inmediato.
Rotación: se recomienda rotar el secreto cada 90 días; el proceso deja el secreto anterior vigente por 24 h (ventana de solapamiento) para evitar caídas.
Toda emisión, revocación y rotación queda registrada en auditoría (timestamp, entorno, actor).
Parámetro
Valor recomendado
Observación
TTL del JWT
15–30 min
Definido por entorno; menor TTL = mayor seguridad
Algoritmo
RS256
Clave privada solo en backend
Rotación de secret
90 días
Con ventana de solapamiento de 24 h
Almacenamiento en app
Memoria
Nunca en preferencias ni keychain persistente
Denylist
Hasta expiración
Revisada en cada request autenticado
Seguridad: si el client_secret se
filtra o se detecta uso anómalo, revoque de inmediato la credencial
desde el Web Admin y emita un par nuevo.
Componente 09 · Seguridad de consola
Autenticación del Web Admin — JWT de IdP (validación genérica RS256/JWKS)
El Web Admin (consola de revisión, perfiles y umbrales) autentica a sus
operadores contra un proveedor de identidad (IdP). La API Core
valida el JWT del IdP de forma genérica (RS256 + JWKS, con
verificación de iss, aud, exp,
nbf y kid) y deriva el rol del operador desde
la tabla identity.rbac_users — nunca de claims no
verificables ni de headers de desarrollo.
Genérico por diseño: el validador no depende de un
IdP específico. En el entorno de demostración el edge inyecta el JWT
(header Cf-Access-Jwt-Assertion); en el entorno del
cliente se configura el issuer/JWKS/audience de su IdP corporativo
(AD/ADFS/SSO). El cambio es solo de configuración, no de código.
1. Configuración del IdP (variables de entorno)
GNB_IDP_ISSUER=<emisor del IdP> # ej. https://idp.corporativo
GNB_IDP_JWKS_URL=<JWKS del IdP> # claves públicas RS256
GNB_IDP_AUDIENCE=<aud de la app> # identifica la consola
GNB_IDP_HEADER=Cf-Access-Jwt-Assertion # header donde viaja el JWT
Con estas variables la API valida los JWT del IdP y mapea el
email verificado → rol activo en rbac_users.
El rol determina los scopes (SUPER_ADMIN, ADMIN, REVIEWER,
OPERATOR, AUDITOR, VIEWER).
2. Contención del header de desarrollo
El header X-Dev-Principal (identidad simulada de
desarrollo) se acepta solo fuera de producción y con la
variable GNB_DEV_PRINCIPAL_ALLOWED=true explícita.
En producción el flag es siempre false: si el entorno
arranca en producción con el header dev habilitado, la API
aborta el boot (guard fail-fast, mismo mecanismo que el
chequeo de rol de base de datos).
3. Alta de operadores
Los operadores se registran en identity.rbac_users
(email + rol + estado) desde el propio Web Admin (sección
Usuarios, solo SUPER_ADMIN).
El email debe coincidir con el del JWT del IdP; sin usuario activo
la API responde 401 aunque el JWT sea válido (fail-closed).
Verificación
Detalle
Algoritmo
RS256 únicamente (se rechaza none/HS256)
Claves
JWKS remoto por kid, caché 1 h
Claims
iss, aud (string o array), exp, nbf
Roles
Desde identity.rbac_users (nunca del JWT/header)
Header dev en prod
Ignorado (401) + abort de boot si queda habilitado
Integración con el IdP del cliente: para conectar
la consola al directorio corporativo solo se cambian
GNB_IDP_ISSUER, GNB_IDP_JWKS_URL y
GNB_IDP_AUDIENCE, y se cargan los operadores en
rbac_users. No requiere cambios de código ni rebuild.
Componente 10 · Cumplimiento
Gate CISEF post-motor — verificación contra la autoridad
El enrolamiento se verifica contra el servicio de identidad de la
autoridad (CISEF). El veredicto de la autoridad no lo
puntúa el motor de decisión: el motor resuelve primero con los
criterios locales (biometría, documento, edad, calidad) y el
resultado de CISEF se compone después, como gate. Este diseño
evita que una indisponibilidad del servicio externo convierta un
enrolamiento localmente válido en un rechazo.
Paridad con el screening AML/PEP: ambos gates
siguen el mismo patrón (se filtran del motor, se componen después,
su indisponibilidad degrada a revisión humana cuando son
obligatorios). La configuración de cada uno es independiente.
1. Semántica del veredicto
Respuesta de CISEF
Veredicto del enrolamiento
Responde y valida
El veredicto local del motor se mantiene sin cambios
Responde y no valida
rejected — rechazo real de la autoridad
No disponible + required = verdadero
Un resultado aprobado se degrada a manual_review (revisión humana)
No disponible + required = falso
El flujo local continúa; queda registro de auditoría
El motor ya rechazó localmente
No se consulta el servicio externo (se omite la llamada)
2. Filtrado de criterios por tipo de flujo
Los criterios cisef_* y el screening
aml_pep_screening se excluyen siempre del motor
de decisión: no son criterios puntuables.
El flujo de verify es un flujo corto sin documento: los
criterios documentales (document_*) y CISEF no
aplican y no se evalúan. Aplica solo lo que corresponde al flujo
(coincidencia facial y verificación de edad).
El flujo de enroll evalúa el conjunto completo de la
política vigente.
3. Configuración
El gate se administra desde la sección Umbrales del Web
Admin (marca Requerido).
El parámetro required tiene por defecto
verdadero: ante indisponibilidad, la sesión pasa a revisión
humana en lugar de rechazarse.
El valor puede fijarse también por configuración del entorno. El
cambio es de configuración, sin rebuild del API.
La migración de esquema correspondiente (V13) se aplica de forma
idempotente con las demás migraciones Flyway.
4. Auditoría
El detalle de la sesión registra sys_cisef_status con
los valores pass · fail ·
unavailable · disabled.
Ante error técnico se registra además sys_cisef_error,
lo que permite distinguir un rechazo de la autoridad de una
indisponibilidad del servicio, sin reconsultarlo.
Indisponibilidad del servicio de la autoridad:
con el gate activo y required = verdadero, las sesiones
afectadas quedan en revisión humana y no se aprueban ni se
rechazan automáticamente. El operador resuelve el caso desde la
consola una vez restablecido el servicio.