01Infraestructura
Mekovault corre en AWS Lightsail, regi贸n us-east-1, sobre cuatro m谩quinas conectadas por red privada. Solo una de ellas recibe tr谩fico de Internet.
| Host | Rol | Servicios | Exposici贸n |
|---|---|---|---|
mekovault-app | Aplicaci贸n | nginx, Next.js, servicios FastAPI, addons | 脷nica expuesta: puertos 80/443 detr谩s de Cloudflare |
mekovault-data | Datos | PostgreSQL 16, Redis (2 instancias), RabbitMQ | Solo red privada |
mekovault-vault | Secretos | Infisical self-hosted, un project por tenant | Solo red privada |
mekovault-obs | Observabilidad | Grafana, Loki, Prometheus, Tempo, OpenTelemetry Collector | Solo red privada |
- Administraci贸n exclusivamente por Tailscale (WireGuard). No hay SSH abierto a Internet en ning煤n host.
- Firewall
ufwactivo en cada m谩quina con pol铆tica de denegar por defecto. - Los servicios internos (PostgreSQL, Redis, RabbitMQ, Infisical, Grafana y los procesos FastAPI) escuchan en loopback o en la interfaz privada. nginx es el 煤nico proceso que atiende tr谩fico p煤blico.
- Cloudflare termina TLS y filtra tr谩fico antes de que llegue a nginx.
02Arquitectura de servicios
La interfaz web es una aplicaci贸n Next.js 16. El backend est谩 compuesto por servicios FastAPI sobre Python 3.12 con SQLAlchemy as铆ncrono, cada uno con una responsabilidad acotada.
| Servicio | Responsabilidad |
|---|---|
svc-auth | Autenticaci贸n, sesiones, MFA y reset de contrase帽a |
svc-tenancy | Empresas, membres铆as, roles, resellers y eliminaci贸n de tenants |
svc-requests | Solicitudes de alta, baja y cambio; flujo de aprobaciones |
svc-tickets | Tickets de soporte y su seguimiento |
svc-billing | Planes, suscripciones y facturaci贸n |
svc-notifications | Correo y notificaciones a usuarios |
| addons | M贸dulos conectores. Ejemplo: super-workspace, que opera sobre Google Workspace y Microsoft 365 |
Eventos y trabajos en segundo plano
- Los servicios se comunican por eventos a trav茅s de RabbitMQ, en el exchange de tipo topic
mekovault.events. - Los trabajos pesados (provisioning, eliminaciones, exportaciones) se registran en un libro mayor de jobs en PostgreSQL y los ejecuta un worker 煤nico.
- Cada job reintenta con backoff exponencial. Sus pasos son idempotentes: volver a ejecutar un paso ya completado no produce efectos duplicados sobre el directorio.
- Cuando un job agota sus reintentos, se genera una alerta y el job queda visible con su 煤ltimo error para intervenci贸n manual.
03Identidad y sesi贸n
Los usuarios de Mekovault (administradores de TI, aprobadores, resellers) se autentican con OAuth de Google o Microsoft, o con email y contrase帽a. La sesi贸n est谩 dise帽ada para que un token robado sirva poco tiempo y sea revocable.
| Mecanismo | Detalle |
|---|---|
| M茅todos de acceso | OAuth con Google o Microsoft, o email y contrase帽a |
| Token de acceso | JWT firmado con RS256, vigencia de 15 minutos, con claims de rol y de estado MFA |
| Refresh token | Vigencia de 30 d铆as. Vive solo en una cookie HttpOnly (inaccesible desde JavaScript). Se rota en cada uso y es revocable individualmente por jti en Redis. Hereda el estado MFA de la sesi贸n y revalida la membres铆a del usuario en la empresa en cada renovaci贸n. |
| MFA | TOTP (apps de autenticaci贸n est谩ndar). L铆mite de 5 intentos por minuto; bloqueo de 15 minutos tras 10 fallos consecutivos. |
| Operaciones sensibles | Exigen que la sesi贸n tenga MFA verificado, aunque el usuario ya est茅 autenticado. |
| Reset de contrase帽a | Token de un solo uso con vigencia de 30 minutos. |
Consecuencia pr谩ctica: un access token filtrado caduca en 15 minutos como m谩ximo; el refresh no es exportable desde el navegador; y revocar el jti en Redis corta la sesi贸n de inmediato, sin esperar a que expire nada.
04Aislamiento multi-tenant
Mekovault es multi-tenant: varios clientes comparten la misma infraestructura. El aislamiento entre ellos se impone en capas independientes, de modo que un error en una no exponga datos de otro cliente.
| Capa | Control |
|---|---|
| Modelo de datos | Toda fila con datos de cliente lleva company_id. |
| Aplicaci贸n | Toda consulta filtra por la empresa que viene en el token de sesi贸n. Nunca por un par谩metro enviado por el cliente. |
| Base de datos | Row-Level Security de PostgreSQL como barrera adicional: aunque una consulta olvidara el filtro, la base de datos no devuelve filas de otra empresa. |
| Superadmin | Rol de plataforma separado de los roles de cliente. Sus acciones requieren confirmaci贸n por c贸digo y MFA verificado. |
| Resellers | Un reseller ve y opera solo sobre los tenants que administra. |
05Credenciales de proveedores y auditor铆a de uso
Para operar sobre su directorio, Mekovault recibe credenciales con permisos de administraci贸n: el JSON de una Service Account de Google con delegaci贸n a nivel de dominio, o los datos de una App Registration de Microsoft Entra ID (client id, tenant id y client secret). Son el activo m谩s sensible que manejamos.
- Se almacenan cifradas en Infisical (self-hosted, en
mekovault-vault), en un project dedicado por tenant. - Nunca se escriben en la base de datos, en logs ni en respuestas de API. La base de datos guarda solo una referencia al secreto.
- Se cargan en memoria en el momento de llamar al proveedor y se descartan al terminar la operaci贸n.
Registro inmutable de cada uso
Cada llamada a Google o Microsoft con las credenciales del cliente deja una fila en la tabla credential_usage_log.
| Campo | Contenido |
|---|---|
| Tenant | company_id del cliente due帽o de la credencial |
| Proveedor | Google Workspace o Microsoft Entra ID |
| Operaci贸n | Acci贸n ejecutada, por ejemplo create_user, suspend_user, add_group_member |
| Scopes | Scopes o permisos consumidos por esa operaci贸n |
| Qui茅n | Usuario que origin贸 la acci贸n, o el proceso autom谩tico (worker, timer) que la ejecut贸 |
| Motivo | Referencia a la solicitud, ticket o tarea que justific贸 la llamada |
| Resultado | 脡xito o fallo, con c贸digo de error si aplica |
| Latencia | Duraci贸n de la llamada al proveedor en milisegundos |
- La tabla tiene triggers de PostgreSQL que rechazan cualquier
UPDATEoDELETE. Ni el equipo de Mekovault puede editar o borrar una fila individual. - Cada fila tiene un id determinista derivado de la operaci贸n. Un reintento del mismo trabajo no genera una segunda fila, as铆 el registro no se infla ni se contradice.
- Una r谩faga de fallos sobre las credenciales de un tenant dispara una alerta al equipo de operaci贸n.
Retenci贸n
| Par谩metro | Valor |
|---|---|
| M铆nimo | 24 meses |
| M谩ximo | 84 meses |
| Configuraci贸n | Por tenant, dentro de ese rango |
| Eliminaci贸n del tenant | Se borra junto con el tenant, o a los 24 meses, lo que ocurra primero |
| Purga | Semanal, solo de filas fuera del per铆odo configurado. Cada batch purgado deja constancia en la auditor铆a. |
Exportaci贸n para auditores
El registro se exporta en CSV o JSON. Cada archivo va firmado con HMAC-SHA256 e incluye el identificador de la clave usada, de modo que un auditor puede verificar que el archivo no fue alterado despu茅s de generarse.
06Permisos que Mekovault solicita
Mekovault pide 煤nicamente los permisos que necesita para gestionar usuarios, grupos y unidades organizativas. No solicita acceso a correo, archivos, calendario ni contenido de ning煤n usuario.
| Scope | Para qu茅 se usa |
|---|---|
admin.directory.user | Crear, suspender, reactivar y modificar cuentas de usuario; asignar contrase帽a inicial y forzar su cambio. |
admin.directory.group | Crear grupos y listas, y agregar o quitar miembros durante altas, cambios y bajas. |
admin.directory.orgunit | Leer y mover usuarios entre unidades organizativas seg煤n el flujo de onboarding u offboarding. |
Las llamadas se hacen con la Service Account impersonando al administrador delegado que el cliente designa al conectar el dominio. Ese administrador queda registrado en cada fila de credential_usage_log.
| Permiso | Para qu茅 se usa |
|---|---|
User.ReadWrite.All | Crear, actualizar, deshabilitar y eliminar usuarios; asignar contrase帽a inicial. |
Group.ReadWrite.All | Crear grupos y gestionar su membres铆a. |
Directory.ReadWrite.All | Operaciones de directorio que los dos permisos anteriores no cubren, por ejemplo lecturas de estructura necesarias para validar una alta. |
En Microsoft se usa el flujo de client credentials: la aplicaci贸n act煤a con sus propios permisos, sin sesi贸n de un usuario. Los permisos son de tipo Application y requieren consentimiento de un administrador global del cliente al conectar.
07Contrase帽as iniciales y reset
- Cuando Mekovault crea una cuenta o resetea una contrase帽a, la contrase帽a temporal queda visible para el administrador que ejecut贸 la acci贸n durante 15 minutos.
- Pasado ese plazo se purga del sistema. No se puede recuperar: si se perdi贸, se genera una nueva.
- Las contrase帽as nunca se escriben en logs, eventos ni en el registro de uso de credenciales.
08Eliminaci贸n de un tenant
Un cliente puede pedir la eliminaci贸n completa de su tenant (derecho de supresi贸n, RGPD art. 17 y Ley 21.719 de Chile). El proceso est谩 dise帽ado para que las credenciales desaparezcan antes que cualquier otro dato.
- Un administrador del tenant solicita la eliminaci贸n. La solicitud se encola como job.
- El tenant queda inaccesible de inmediato: se rechazan sus sesiones y nuevos inicios de sesi贸n.
- El job revoca los secretos del tenant y elimina su project en Infisical. Desde este punto Mekovault ya no puede llamar al directorio del cliente.
- Solo despu茅s se borran en cascada los datos del tenant en PostgreSQL: usuarios, solicitudes, tickets, configuraci贸n.
- La eliminaci贸n queda registrada en la auditor铆a de plataforma.
- Los administradores reciben un correo de confirmaci贸n con el detalle de lo eliminado.
09Addons: m贸dulos con l铆mites
Los conectores a proveedores y otras extensiones se empaquetan como addons. Un addon con un defecto no debe poder degradar la plataforma completa, y el registro de addons impone esa regla.
| Etapa | Control |
|---|---|
| Declaraci贸n | Cada m贸dulo se describe en un manifiesto con sus puertos, rutas, tablas, migraciones y chequeo de salud. |
| Validaci贸n | Autom谩tica antes de activarlo: esquema del manifiesto, colisiones de puertos, rutas y tablas con otros m贸dulos, migraciones aplicables y respuesta del chequeo de salud. |
| Ejecuci贸n | Corre con l铆mites de memoria y CPU. Un m贸dulo que se desborda se reinicia sin afectar a los dem谩s. |
| Supervisi贸n | Chequeo de salud cada 60 segundos, con resultado visible en el panel de operaci贸n. |
| Kill switch | Cualquier m贸dulo puede desactivarse sin despliegue: en 15 segundos o menos sus rutas responden 503 y el resto de la plataforma sigue operando. |
10Per铆metro y navegador
| Control | Efecto |
|---|---|
| HSTS | El navegador solo se conecta por HTTPS al dominio, incluso si el usuario escribe http. |
| Content-Security-Policy | Restringe los or铆genes desde los que el portal puede cargar scripts, estilos y conexiones. |
| X-Content-Type-Options: nosniff | Impide que el navegador reinterprete el tipo de un archivo. |
| frame-ancestors 'none' | El portal no puede embeberse en un iframe de otro sitio (clickjacking). |
| CORS restringido | Solo los or铆genes de Mekovault pueden llamar a la API desde un navegador. |
| Sin source maps en producci贸n | No se publica el c贸digo fuente del frontend. |
| Sin documentaci贸n p煤blica de API | Los esquemas OpenAPI de los servicios no est谩n expuestos en producci贸n. |
| Errores sin trazas | Las respuestas de error no incluyen stack traces ni detalles internos. |
11Operaci贸n y observabilidad
| Se帽al | Destino |
|---|---|
| Logs estructurados (JSON) | Loki, consultados desde Grafana |
| M茅tricas | Prometheus |
| Trazas distribuidas | OpenTelemetry hacia Tempo |
- Antes de cada despliegue se toma un backup de la base de datos.
- Los servicios se despliegan de forma controlada; un despliegue fallido se revierte al backup previo.
Timers de higiene
| Tarea | Qu茅 hace |
|---|---|
| Purga de PII | Elimina datos personales que ya cumplieron su per铆odo de retenci贸n. |
| Cierre de tickets | Cierra tickets resueltos sin actividad despu茅s del plazo configurado. |
| Expiraci贸n de secretos | Avisa a los administradores 30, 7 y 0 d铆as antes de que caduque una credencial de proveedor (por ejemplo, un client secret de Entra ID). |
| Purga del registro de uso | Semanal; elimina solo filas fuera de la retenci贸n configurada y deja constancia del batch. |
12Resumen de capas de seguridad
| Capa | Controles |
|---|---|
| Per铆metro | Cloudflare, nginx como 煤nico proceso p煤blico, ufw |
| Red | Red privada de Lightsail, Tailscale para administraci贸n, servicios en loopback |
| Identidad | JWT RS256 de 15 min, refresh HttpOnly rotado y revocable, MFA TOTP con rate limit |
| Aplicaci贸n | Filtro por company_id del token en toda consulta |
| Datos | Row-Level Security en PostgreSQL 16 |
| Secretos | Infisical self-hosted, un project por tenant, nunca en DB ni logs |
| Auditor铆a | credential_usage_log inmutable, exportaci贸n firmada con HMAC-SHA256 |
| M贸dulos | Manifiesto validado, l铆mites de recursos, supervisi贸n cada 60 s, kill switch |
| Operaci贸n | Backups previos al despliegue, timers de higiene, logs, m茅tricas y trazas |
13Lo que est谩 en curso
Preferimos decir qu茅 falta antes de que lo pregunte un cuestionario. Estos puntos est谩n en trabajo y no deben asumirse como vigentes hasta que esta p谩gina los mueva a la secci贸n correspondiente.
| 脥tem | Estado |
|---|---|
ENVIRONMENT=production en todos los servicios (hoy algunos corren con la configuraci贸n de desarrollo endurecida) | En curso |
| Alertas de operaci贸n hacia Slack | En curso |
| Rol de PostgreSQL dedicado por addon, para que cada m贸dulo acceda solo a sus tablas | En curso |
| SOC 2 | En curso, sin fecha comprometida |
FAQPreguntas de auditor铆a frecuentes
Respuestas directas a lo que suelen preguntar los equipos de seguridad y los auditores.
- 驴D贸nde viven mis credenciales?
- En Infisical, una instancia self-hosted en la m谩quina
mekovault-vault, dentro de la red privada de AWS Lightsail en us-east-1. Cada tenant tiene su propio project. La base de datos guarda solo una referencia al secreto, nunca su valor. - 驴Qui茅n puede verlas?
- Ninguna persona las ve en operaci贸n normal. Los servicios las cargan en memoria en el momento de llamar al proveedor y las descartan al terminar. El acceso a la m谩quina del vault exige Tailscale, y ese acceso est谩 restringido al equipo de plataforma. Las contrase帽as temporales que Mekovault genera son visibles al administrador del cliente durante 15 minutos y luego se purgan.
- 驴Qu茅 pasa si dejo Mekovault?
- Un administrador solicita la eliminaci贸n del tenant. El acceso se corta de inmediato; luego se revocan los secretos y se borra el project de Infisical; solo despu茅s se borran en cascada los datos en PostgreSQL. Queda registro en la auditor铆a de plataforma y los administradores reciben un correo con el detalle. Los sub-encargados con datos residuales est谩n listados en la p谩gina de sub-encargados.
- 驴C贸mo pruebo que no usaron mis permisos para otra cosa?
- Con
credential_usage_log: cada llamada a Google o Microsoft con sus credenciales queda registrada con operaci贸n, scopes, qui茅n la origin贸, motivo, resultado y latencia. La tabla no admite UPDATE ni DELETE. Puede exportarla en CSV o JSON firmado con HMAC-SHA256 y verificar la firma con el id de clave incluido. - 驴Un token de sesi贸n robado sirve para algo?
- El access token caduca en 15 minutos. El refresh token vive solo en una cookie HttpOnly, se rota en cada uso y se puede revocar por
jtien Redis. Las operaciones sensibles exigen adem谩s MFA verificado en esa sesi贸n. - 驴Un m贸dulo con fallas puede tumbar la plataforma?
- No est谩 dise帽ado para poder hacerlo. Cada addon corre con l铆mites de memoria y CPU, se supervisa cada 60 segundos y tiene un kill switch que lo desactiva en 15 segundos o menos sin despliegue. El resto de servicios sigue operando.