> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Seguridad

> Revisa la seguridad en profundidad de Matcher: autenticación, RBAC, aislamiento de tenants, cifrado y registros de auditoría en cada capa.

Matcher implementa controles de seguridad integrales para proteger los datos de conciliación financiera. Esta guía cubre autenticación, autorización, aislamiento de inquilinos, cifrado y características de cumplimiento.

Los datos de conciliación financiera se encuentran entre los más sensibles de cualquier organización — abarcan registros de transacciones, información de contrapartes y obligaciones regulatorias. Normativas como SOC 2, PCI DSS y los requisitos de las autoridades financieras locales exigen controles específicos en torno al acceso, el cifrado y la auditabilidad. Matcher está diseñado con estos requisitos en mente, proporcionando seguridad en profundidad en cada capa del sistema.

## Descripción general

***

La arquitectura de seguridad de Matcher está construida en varias capas. Cada solicitud de API pasa por múltiples puntos de control de seguridad antes de llegar a tus datos.

<Steps>
  <Step>
    Primero, TLS cifra la conexión.
  </Step>

  <Step>
    Luego la autenticación verifica quién eres:

    * El aislamiento de inquilinos asegura que solo veas tus propios datos.
    * RBAC verifica si tienes permiso para realizar la acción.
  </Step>

  <Step>
    Finalmente, el sistema registra todo para propósitos de auditoría.
  </Step>
</Steps>

### Protección por capas

| Capa                      | Protección                                                      |
| ------------------------- | --------------------------------------------------------------- |
| Transporte                | Cifrado TLS 1.2+                                                |
| Autenticación             | Tokens JWT vía lib-auth                                         |
| Aislamiento de inquilinos | PostgreSQL con base de datos por inquilino (pool-por-inquilino) |
| Autorización              | Control de acceso basado en roles                               |
| Auditoría                 | Logs inmutables de solo anexión                                 |
| Almacenamiento            | Cifrado en reposo                                               |

## Autenticación

***

Matcher usa la biblioteca compartida `lib-auth` para el control de acceso basado en JWT. Matcher delega toda la validación criptográfica de JWT a un proveedor de autenticación externo y **no guarda ningún secreto JWT local** propio.

### Configuración

Estas variables de entorno controlan la autenticación:

| Variable              | Requerida                   | Descripción                                                                                                            |
| --------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `PLUGIN_AUTH_ENABLED` | Sí                          | Habilitar o deshabilitar la aplicación de autorización (`true`/`false`; predeterminado `false`)                        |
| `PLUGIN_AUTH_ADDRESS` | Cuando auth está habilitado | Dirección del servicio externo `plugin-auth`                                                                           |
| `AUTH_PROVIDER`       | No                          | Proveedor de validación: `plugin-auth`, `workos` o `disabled`. Cuando no se define, se deriva de `PLUGIN_AUTH_ENABLED` |

<Note>
  `AUTH_ENABLED` y `AUTH_SERVICE_ADDRESS` se aceptan como **alias heredados** de `PLUGIN_AUTH_ENABLED` y `PLUGIN_AUTH_ADDRESS`. Establecer un alias y su forma actual con valores en conflicto se rechaza durante el arranque.
</Note>

Cuando `PLUGIN_AUTH_ENABLED=false` (solo desarrollo), Matcher usa un ID de inquilino predeterminado (`11111111-1111-1111-1111-111111111111`) y omite las verificaciones de autorización.

### Estructura del token JWT

Con `AUTH_PROVIDER=plugin-auth`, la validación criptográfica se delega al servicio `plugin-auth`; con `AUTH_PROVIDER=workos`, Matcher verifica localmente los JWT de token de acceso de WorkOS contra el JWKS en caché. En cualquier caso, el token debe incluir claims de identificación de inquilino:

```json theme={null}
{
  "sub": "user_123",
  "tenant_id": "11111111-1111-1111-1111-111111111111",
  "tenant_slug": "acme-corp",
  "iat": 1705749600,
  "exp": 1705753200,
  "nbf": 1705749600
}
```

| Claim                        | Requerido | Descripción                                                    |
| ---------------------------- | --------- | -------------------------------------------------------------- |
| `tenant_id` o `tenantId`     | Sí        | UUID del inquilino para aislamiento de inquilinos              |
| `tenant_slug` o `tenantSlug` | No        | Identificador legible del inquilino                            |
| `sub`                        | No        | ID de usuario (usado para registro de auditoría)               |
| `exp`                        | Sí        | Tiempo de expiración del token                                 |
| `nbf`                        | No        | Tiempo not-before (el token es inválido antes de este momento) |

### Encabezados requeridos

Todas las solicitudes de API deben incluir autenticación:

```bash theme={null}
curl -X GET "https://api.matcher.example.com/v1/contexts" \
 -H "Authorization: Bearer $JWT_TOKEN"
```

### Validación de token

Matcher valida los tokens en cada solicitud:

1. **Verificación de firma**: Delegada al proveedor de autenticación configurado (servicio `plugin-auth` o JWKS de WorkOS) — Matcher no guarda ningún secreto de firma local
2. **Verificación de expiración**: Rechaza tokens expirados (claim `exp`)
3. **Verificación de not-before**: Rechaza tokens usados antes de su tiempo `nbf`
4. **Extracción de inquilino**: Extrae `tenant_id` para resolver el pool de base de datos del inquilino

## Autorización (RBAC)

***

El control de acceso basado en roles protege todos los endpoints de API. Matcher delega la autorización a un servicio de auth externo vía `lib-auth`. Los permisos son granulares y siguen el patrón de dos partes `resource:action`.

### Estructura de permisos

```
<resource>:<action>
```

Los recursos son **sustantivos de producto** planos (en plural), **sin prefijo de dominio ni segmento de sub-recurso**. Las acciones son verbos que describen la operación realizada sobre el sustantivo.

Ejemplos:

* `contexts:create` — Crear contextos de conciliación
* `match-runs:run` — Ejecutar ejecuciones de coincidencia
* `exceptions:resolve` — Resolver excepciones

### Lista completa de permisos

Matcher define un conjunto plano de aproximadamente 35 recursos — no hay agrupación en dominios. Cada endpoint requiere un permiso `resource:action` específico verificado contra el servicio de autorización externo. Las tablas a continuación están agrupadas solo para facilitar la lectura; los slugs en sí no llevan ningún calificador de dominio.

#### Configuration

| Permiso                  | Descripción                                    |
| ------------------------ | ---------------------------------------------- |
| `contexts:create`        | Crear contextos de conciliación                |
| `contexts:read`          | Ver contextos                                  |
| `contexts:update`        | Actualizar contextos                           |
| `contexts:delete`        | Archivar (borrado lógico) contextos            |
| `contexts:clone`         | Clonar un contexto y su configuración          |
| `sources:create`         | Crear fuentes de datos                         |
| `sources:read`           | Ver configuración de fuente                    |
| `sources:update`         | Modificar configuración de fuente              |
| `sources:delete`         | Eliminar fuentes de datos                      |
| `field-maps:create`      | Crear mapeos de campos                         |
| `field-maps:read`        | Ver mapeos de campos                           |
| `field-maps:update`      | Actualizar mapeos de campos                    |
| `field-maps:delete`      | Eliminar mapeos de campos                      |
| `rules:create`           | Crear reglas de coincidencia                   |
| `rules:read`             | Ver reglas de coincidencia                     |
| `rules:update`           | Actualizar reglas de coincidencia              |
| `rules:delete`           | Eliminar reglas de coincidencia                |
| `rules:reorder`          | Reordenar la prioridad de evaluación de reglas |
| `fee-schedules:create`   | Crear cronogramas de tarifas                   |
| `fee-schedules:read`     | Ver cronogramas de tarifas                     |
| `fee-schedules:update`   | Actualizar cronogramas de tarifas              |
| `fee-schedules:delete`   | Eliminar cronogramas de tarifas                |
| `fee-schedules:simulate` | Simular cálculos de cronogramas de tarifas     |
| `fee-rules:create`       | Crear reglas de tarifas                        |
| `fee-rules:read`         | Ver reglas de tarifas                          |
| `fee-rules:update`       | Actualizar reglas de tarifas                   |
| `fee-rules:delete`       | Eliminar reglas de tarifas                     |
| `schedules:create`       | Crear programaciones                           |
| `schedules:read`         | Ver programaciones                             |
| `schedules:update`       | Actualizar programaciones                      |
| `schedules:delete`       | Eliminar programaciones                        |

#### Ingestion

| Permiso                         | Descripción                                                             |
| ------------------------------- | ----------------------------------------------------------------------- |
| `imports:create`                | Cargar archivos de transacciones                                        |
| `imports:preview`               | Previsualizar el análisis de importación antes de confirmar             |
| `import-jobs:read`              | Ver trabajos de importación                                             |
| `ingestion-transactions:search` | Buscar transacciones                                                    |
| `ingestion-transactions:ignore` | Marcar transacciones como ignoradas                                     |
| `extraction-reviews:create`     | Encolar extracciones de documentos con IA y aprobar/rechazar revisiones |
| `extraction-reviews:read`       | Ver revisiones de extracción                                            |

#### Matching

| Permiso                   | Descripción                                           |
| ------------------------- | ----------------------------------------------------- |
| `match-runs:run`          | Ejecutar ejecuciones de coincidencia                  |
| `match-runs:read`         | Ver resultados de ejecuciones de coincidencia         |
| `match-groups:read`       | Ver grupos de coincidencia                            |
| `match-groups:unmatch`    | Deshacer coincidencia de grupos                       |
| `open-items:read`         | Ver el libro de ítems abiertos residuales arrastrados |
| `manual-matches:create`   | Crear coincidencias manuales                          |
| `adjustments:create`      | Crear entradas de ajuste                              |
| `rule-suggestions:create` | Producir y aprobar/rechazar sugerencias de reglas     |
| `rule-suggestions:read`   | Ver sugerencias de reglas                             |

#### Excepciones y disputas

| Permiso                       | Descripción                               |
| ----------------------------- | ----------------------------------------- |
| `exceptions:read`             | Ver excepciones e historial               |
| `exceptions:resolve`          | Forzar coincidencia o ajustar entradas    |
| `exceptions:assign`           | Asignar excepciones a usuarios            |
| `exceptions:dispatch`         | Despachar excepciones a sistemas externos |
| `callback-credentials:read`   | Listar credenciales de callback           |
| `callback-credentials:write`  | Generar o rotar credenciales de callback  |
| `callback-credentials:delete` | Revocar credenciales de callback          |
| `disputes:read`               | Ver disputas                              |
| `disputes:write`              | Crear o actualizar disputas               |
| `disputes:close`              | Cerrar disputas                           |
| `disputes:submit-evidence`    | Enviar evidencia de disputas              |
| `comments:read`               | Ver comentarios                           |
| `comments:write`              | Agregar comentarios en excepciones        |
| `comments:delete`             | Eliminar comentarios                      |

<Note>
  Los callbacks entrantes de sistemas externos se autentican mediante un token bearer opaco, no mediante RBAC, por lo que no existe un permiso `callbacks:process`. Los permisos `callback-credentials:*` protegen únicamente la superficie protegida por JWT que genera, rota, lista y revoca esos tokens.
</Note>

#### Reportes y analíticas

| Permiso                | Descripción                                                     |
| ---------------------- | --------------------------------------------------------------- |
| `dashboards:read`      | Acceder a analíticas y métricas del dashboard                   |
| `reports:read`         | Ver reportes (coincidentes, no coincidentes, resumen, varianza) |
| `reports:export`       | Exportar reportes                                               |
| `reports:count`        | Contar filas de reportes                                        |
| `export-jobs:create`   | Crear trabajos de exportación                                   |
| `export-jobs:read`     | Ver estado de trabajos de exportación                           |
| `export-jobs:cancel`   | Cancelar trabajos de exportación                                |
| `export-jobs:download` | Descargar archivos de exportación                               |

#### Gobernanza y privacidad

| Permiso                       | Descripción                                       |
| ----------------------------- | ------------------------------------------------- |
| `audit-logs:read`             | Ver logs de auditoría                             |
| `archives:read`               | Ver archivos                                      |
| `archives:download`           | Descargar archivos                                |
| `actor-mappings:read`         | Ver mapeos de actores                             |
| `actor-mappings:write`        | Crear o actualizar mapeos de actores              |
| `actor-mappings:delete`       | Eliminar mapeos de actores                        |
| `actor-mappings:pseudonymize` | Seudonimizar actores (derecho al olvido del GDPR) |
| `actor-mappings:deanonymize`  | Revelar identidades de actores seudonimizadas     |

#### Discovery

| Permiso                         | Descripción                                    |
| ------------------------------- | ---------------------------------------------- |
| `discovery-status:read`         | Ver estado de discovery                        |
| `discovery-connections:read`    | Ver conexiones de discovery                    |
| `discovery-connections:create`  | Crear conexiones de discovery                  |
| `discovery-connections:update`  | Actualizar conexiones de discovery             |
| `discovery-connections:write`   | Escribir datos de conexiones de discovery      |
| `discovery-connections:delete`  | Eliminar conexiones de discovery               |
| `discovery-connections:test`    | Probar conexiones de discovery                 |
| `discovery-connections:extract` | Disparar la extracción de discovery            |
| `discovery-extractions:read`    | Ver extracciones de discovery                  |
| `discovery-extractions:poll`    | Consultar el estado de extracción de discovery |
| `discovery-refresh:execute`     | Ejecutar la actualización de discovery         |

#### System

| Permiso                       | Descripción                                         |
| ----------------------------- | --------------------------------------------------- |
| `system-runtime-config:admin` | Administrar la configuración de runtime del sistema |
| `streaming-manifest:read`     | Leer el manifiesto de streaming                     |

### Gestión de roles

El servicio de autorización externo gestiona los roles, no Matcher en sí. Configura los roles y sus permisos asociados en tu proveedor de identidad o servicio de auth. Matcher verifica los permisos en cada solicitud llamando al servicio de auth con el recurso y la acción requeridos.

## Aislamiento de inquilinos

***

Matcher usa aislamiento pool-por-inquilino en PostgreSQL: los datos de cada inquilino viven en su propia base de datos, proporcionando una fuerte separación de datos entre inquilinos.

### Cómo funciona

Cuando llega una solicitud, Matcher extrae el ID del inquilino del token JWT (nunca de parámetros de consulta o encabezados que tú controlas). Luego resuelve el pool de conexiones dedicado a la base de datos de ese inquilino, por lo que cada consulta se ejecuta contra la base de datos propia del inquilino en completo aislamiento. No hay cambio de esquema compartido — no se usa `SET search_path`.

<Note>
  Como los datos de cada inquilino viven en una base de datos físicamente separada, un bug en la capa de aplicación aún no puede alcanzar los datos de otro inquilino.
</Note>

**Detalles de implementación**

1. **ID de inquilino solo desde JWT**: Nunca aceptado desde parámetros de solicitud
2. **Resolución automática de pool**: El pool de conexiones de la base de datos del inquilino se resuelve desde el contexto
3. **Aislamiento físico**: Las consultas de cada inquilino se ejecutan contra su propia base de datos, no una compartida
4. **Sin acceso entre inquilinos**: Las bases de datos físicamente separadas imponen el aislamiento

### Garantías de aislamiento

| Garantía                      | Implementación                                         |
| ----------------------------- | ------------------------------------------------------ |
| Aislamiento de datos          | Una base de datos PostgreSQL separada por inquilino    |
| Alcance de consultas          | Pool de conexiones por inquilino resuelto desde el JWT |
| Sin suplantación de inquilino | Inquilino solo desde JWT                               |
| Separación de auditoría       | Tablas de auditoría por inquilino                      |

## Pista de auditoría

***

Matcher registra todas las acciones en un log de auditoría inmutable de solo anexión para cumplimiento y análisis forense.

### Eventos auditados

| Categoría             | Eventos                                                   |
| --------------------- | --------------------------------------------------------- |
| Acceso a datos        | Ver coincidencias, ver excepciones, exportar datos        |
| Modificación de datos | Crear coincidencia, resolver excepción, actualizar reglas |
| Configuración         | Crear contexto, modificar fuente, cambiar configuración   |

### Consultar logs de auditoría

Usa los endpoints de logs de auditoría de gobernanza para recuperar registros de auditoría:

```bash theme={null}
curl -X GET "https://api.matcher.example.com/v1/governance/audit-logs" \
 -H "Authorization: Bearer $TOKEN"
```

<Tip>Referencia de API: [Listar logs de auditoría](/es/reference/matcher/list-audit-logs)</Tip>

## Mapeos de actores y privacidad

***

Los mapeos de actores asocian identificadores del sistema (como los claims `sub` de JWT) con nombres legibles y direcciones de correo electrónico. Esto mejora la legibilidad de los logs de auditoría sin almacenar datos personales en cada entrada de log.

### Gestionar mapeos de actores

El parámetro de ruta del ID de actor acepta hasta 255 caracteres (coincidiendo con la restricción de columna de base de datos). Los espacios en blanco iniciales y finales se recortan automáticamente. Los valores que excedan este límite se rechazan con un error `400 Bad Request`.

```bash cURL theme={null}
curl -X PUT "https://api.matcher.example.com/v1/governance/actor-mappings/user-abc-123" \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{
   "display_name": "John Doe",
   "email": "john.doe@company.com"
 }'
```

La operación de upsert devuelve el mapeo de actor persistido directamente en la respuesta, para que puedas verificar los valores guardados sin una solicitud GET separada.

<Tip>Referencia de API: [Upsert de mapeo de actor](/es/reference/matcher/upsert-actor-mapping) | [Obtener mapeo de actor](/es/reference/matcher/get-actor-mapping) | [Eliminar mapeo de actor](/es/reference/matcher/delete-actor-mapping)</Tip>

### Pseudonimización GDPR

Para cumplir con las solicitudes de derecho al olvido, pseudonimiza un actor para reemplazar sus datos personales con `[REDACTED]`. La pseudonimización no es reversible desde la aplicación; los registros subyacentes pueden conservarse según la política de cumplimiento y auditoría.

```bash cURL theme={null}
curl -X POST "https://api.matcher.example.com/v1/governance/actor-mappings/user-abc-123/pseudonymize" \
 -H "Authorization: Bearer $TOKEN"
```

<Tip>Referencia de API: [Pseudonimizar actor](/es/reference/matcher/pseudonymize-actor)</Tip>

### Archivos de logs de auditoría

Los logs de auditoría históricos se comprimen periódicamente y se mueven a almacenamiento a largo plazo. Usa los endpoints de archivos para listar y descargar datos archivados para revisiones de cumplimiento.

```bash cURL theme={null}
curl -X GET "https://api.matcher.example.com/v1/governance/archives" \
 -H "Authorization: Bearer $TOKEN"
```

<Tip>Referencia de API: [Listar archivos](/es/reference/matcher/list-archives) | [Descargar archivo](/es/reference/matcher/download-archive)</Tip>

## Cifrado de datos

***

### Cifrado en tránsito

TLS cifra todos los datos transmitidos hacia y desde Matcher.

| Requisito         | Configuración                     |
| ----------------- | --------------------------------- |
| Protocolo         | TLS 1.2 o superior                |
| Suites de cifrado | Solo cifrados fuertes             |
| Certificado       | Certificado válido firmado por CA |
| HSTS              | Habilitado con max-age de 1 año   |

### Cifrado en reposo

| Tipo de datos              | Método de cifrado                            |
| -------------------------- | -------------------------------------------- |
| Base de datos              | PostgreSQL TDE (Transparent Data Encryption) |
| Almacenamiento de archivos | Cifrado AES-256                              |
| Respaldos                  | Cifrados antes de almacenamiento             |
| Secretos                   | Vault con cifrado de sobre                   |

## Cumplimiento SOX

***

Matcher mantiene registros para los requisitos de auditoría SOX (Sarbanes-Oxley).

### Características de control SOX

| Control                      | Característica de Matcher                                  |
| ---------------------------- | ---------------------------------------------------------- |
| **Segregación de funciones** | RBAC con permisos granulares                               |
| **Gestión de cambios**       | Pista de auditoría para todos los cambios de configuración |
| **Control de acceso**        | Autenticación JWT con aplicación de roles                  |
| **Pista de auditoría**       | Logs inmutables de solo anexión                            |
| **Integridad de datos**      | Checksums y validación de transacciones                    |

## Seguridad de API

***

### Limitación de tasa

Algunos endpoints incluyen limitación de tasa adicional para proteger contra abuso:

| Tipo de endpoint           | Limitación de tasa |
| -------------------------- | ------------------ |
| Despacho de excepciones    | Sí                 |
| Endpoints de exportación   | Sí                 |
| Procesamiento de callbacks | Sí                 |

### Protección SSRF

Matcher bloquea las solicitudes HTTP salientes a rangos de IP privados al despachar excepciones a sistemas externos. Esto previene ataques de Server-Side Request Forgery (SSRF).

Los rangos bloqueados incluyen `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`, `127.0.0.0/8` y equivalentes IPv6.

### Verificación de firma de webhooks

Matcher firma los payloads de webhooks salientes con HMAC-SHA256 usando un secreto compartido por destino. La firma aparece en el encabezado `X-Signature-256`, con el formato `sha256=<hex-digest>`, permitiendo a los receptores verificar la autenticidad. (El despacho también establece un encabezado `X-Idempotency-Key` para entrega como máximo una vez).

## Mejores prácticas

***

<AccordionGroup>
  <Accordion title="Usa acceso de mínimo privilegio">
    Otorga a los usuarios solo los permisos que necesitan. Comienza con acceso mínimo y agrega permisos según sea necesario.
  </Accordion>

  <Accordion title="Rota credenciales regularmente">
    Implementa rotación automática para credenciales de servicio y secretos JWT. Usa tokens de corta duración cuando sea posible.
  </Accordion>

  <Accordion title="Habilita el registro de auditoría">
    Mantén los logs de auditoría habilitados y revísalos regularmente. Configura alertas para actividad sospechosa.
  </Accordion>

  <Accordion title="Usa limitación de tasa">
    Mantén los límites de tasa predeterminados habilitados para proteger contra abuso. Ajusta los umbrales según los patrones de tráfico esperados.
  </Accordion>

  <Accordion title="Revisa el acceso regularmente">
    Realiza revisiones periódicas de acceso. Elimina el acceso rápidamente cuando los usuarios cambien de rol o se vayan.
  </Accordion>

  <Accordion title="Verifica firmas de webhooks">
    Valida siempre las firmas HMAC-SHA256 en los payloads de webhooks para confirmar que se originan de Matcher.
  </Accordion>

  <Accordion title="Monitorea eventos de seguridad">
    Configura monitoreo y alertas en tiempo real para eventos de seguridad. Investiga anomalías de inmediato.
  </Accordion>
</AccordionGroup>

## Próximos pasos

***

<Card title="Reglas de coincidencia" icon="scale-balanced" href="/es/matcher/configuration/matcher-match-rules" horizontal>
  Configura reglas de coincidencia de forma segura.
</Card>

<Card title="Enrutamiento de excepciones" icon="route" href="/es/matcher/configuration/matcher-exception-routing" horizontal>
  Configura flujos de trabajo de excepciones seguros.
</Card>
