Entrada

SCIM: el protocolo de provisioning entre IdPs y aplicaciones

SCIM es el estándar REST/JSON que permite a un IdP crear, actualizar y desactivar usuarios en aplicaciones SaaS de forma automática. Resuelve el problema histórico del joiner/mover/leaver manual en arquitecturas con decenas o cientos de apps integradas. A pesar de tener una década de estándar, su adopción irregular es una de las fricciones silenciosas del SaaS empresarial.

SCIM: el protocolo de provisioning entre IdPs y aplicaciones

Este artículo forma parte de la serie La evolución de la seguridad en aplicaciones modernas. El SSO resuelve solo la mitad del problema de identidad corporativa. La otra mitad, menos glamurosa pero igual de crítica, es asegurar que cuando alguien se une, cambia de rol o deja la organización, esos cambios se reflejan en todas las aplicaciones donde tenía acceso. Hacerlo a mano es insostenible; hacerlo con scripts ad hoc es frágil. SCIM es la respuesta estándar a ese problema.

Qué es SCIM y de dónde viene

SCIM, RFC 7643 (System for Cross-domain Identity Management: Core Schema) y RFC 7644 (System for Cross-domain Identity Management: Protocol), ambos publicados en septiembre de 2015, define dos cosas. La primera es un esquema estándar para representar identidades: recursos User y Group con atributos obligatorios y extensibles. La segunda es un protocolo REST/JSON para crear, consultar, modificar y borrar esos recursos.

El objetivo declarado es la gestión de identidades entre dominios. En la práctica, el caso dominante es este: un IdP corporativo (Okta, Microsoft Entra ID, Ping, Keycloak) necesita propagar cambios de usuarios y grupos a aplicaciones SaaS de terceros (Slack, GitHub Enterprise, Zoom, Notion, Salesforce). SCIM es el contrato entre ambos lados.

Antes de SCIM existían mecanismos propietarios, flat-file CSVs subidos por SFTP, conectores específicos de cada proveedor, y una cantidad alarmante de pegamento en Python. SCIM unificó la semántica y permitió que un IdP hablara con N aplicaciones sin escribir N integraciones distintas.

El esquema Core

El recurso User define un conjunto de atributos estándar: userName, name (con subcampos givenName, familyName), emails (multi-valor con tipo primario/secundario), active (booleano crítico), phoneNumbers, addresses, title, department, manager. El esquema admite extensiones; la más común es urn:ietf:params:scim:schemas:extension:enterprise:2.0:User, que añade employeeNumber, organization, costCenter y la referencia al manager.

El recurso Group contiene displayName y members (lista de referencias a usuarios o a otros grupos). Permite modelar roles, equipos o cualquier agrupación que la aplicación destino quiera consumir para derivar permisos.

Ambos recursos llevan metadatos (meta) con resourceType, created, lastModified y un location canónico. Cada recurso tiene un id opaco asignado por el proveedor y un externalId opcional que el cliente (normalmente el IdP) usa para mantener correlación con su propio identificador.

El protocolo

SCIM 2.0 sigue convenciones REST estándar. POST /Users crea, GET /Users/{id} lee, PUT /Users/{id} reemplaza el recurso entero, PATCH /Users/{id} aplica operaciones parciales (add, remove, replace) siguiendo RFC 6902 (JSON Patch) con adaptaciones, y DELETE /Users/{id} borra.

La operación más delicada es PATCH. Un IdP que sincroniza cambios frecuentes no puede permitirse enviar el recurso completo en cada update; tiene que enviar solo el delta. Una aplicación que no soporta PATCH obliga al IdP a hacer GET + PUT, con los riesgos de race condition asociados y más tráfico.

SCIM define también una sintaxis de filtros sobre GET /Users?filter=...: filter=userName eq "alice", filter=emails.value co "@acme.com", combinables con and/or. Los operadores incluyen eq, ne, co (contains), sw (starts with), pr (present), gt, ge, lt, le. La paginación usa startIndex y count.

El endpoint /ServiceProviderConfig publica qué operaciones soporta la implementación: si soporta PATCH, si soporta filtros, qué autenticación espera, qué esquemas entiende. Es el equivalente a .well-known/openid-configuration en OIDC.

Push vs pull

Hay dos modos de operación. En modo push, el IdP es el cliente SCIM y la aplicación el servidor. El IdP inicia las llamadas cuando detecta cambios en su directorio. Este es el modo dominante y el que describen Okta, Entra ID y Ping en sus documentaciones.

En modo pull, la aplicación consulta periódicamente al IdP. Es menos común porque requiere que el IdP exponga un endpoint SCIM y que la aplicación tenga credenciales para leerlo; en la práctica, pocos IdPs lo exponen abiertamente.

La combinación más habitual en la industria es push SCIM desde el IdP hacia la aplicación + OIDC o SAML para autenticación. El IdP es la fuente de verdad; la aplicación mantiene una réplica local del subset de usuarios que necesita.

El caso joiner/mover/leaver

El flujo canónico que justifica SCIM es el JML. Un empleado se incorpora (joiner): el IdP recibe el alta del HRIS, lo propaga con POST /Users a todas las aplicaciones configuradas, y el nuevo empleado puede hacer SSO desde el día uno con su acceso ya provisionado.

Un empleado cambia de equipo (mover): el IdP actualiza los grupos del usuario; SCIM propaga el cambio con PATCH /Groups/{id} y la aplicación recalcula permisos. Sin SCIM, este paso depende de que un administrador recuerde revisar cada app.

Un empleado deja la organización (leaver): el IdP marca al usuario como active: false y la aplicación debe revocar acceso inmediatamente. Este es el escenario donde SCIM justifica su existencia. En organizaciones sin SCIM, las cuentas de ex-empleados en SaaS terceros pueden seguir activas durante semanas, y son uno de los vectores de ataque más comunes.

La operación de desactivación (active: false) no es lo mismo que el borrado (DELETE). Desactivar preserva datos de auditoría; borrar los elimina. La mayoría de políticas corporativas exigen desactivar en el momento del leaver y borrar tras un periodo de retención.

Errores comunes en implementaciones

La lista negra de implementaciones SCIM problemáticas es larga. Estos son los patrones más frecuentes.

No soportar PATCH. Obliga a hacer PUT completos, lo que sobrecarga y provoca drift cuando dos updates concurren.

Confundir desactivación con borrado. Algunas apps interpretan active: false como “borra todo”; otras lo ignoran silenciosamente. Ninguna de las dos respuestas es correcta. El contrato es: desactivar suspende el acceso pero preserva el recurso.

Drift entre IdP y aplicación. Alguien edita un usuario directamente en la aplicación (bypass del IdP). SCIM no tiene un mecanismo estándar de reconciliación; el IdP reescribirá el cambio en la siguiente sincronización, o no, dependiendo de cómo esté configurado. La regla operativa es: el IdP es la única fuente de verdad, los cambios en la app están prohibidos salvo casos excepcionales auditados.

Filtros incompletos. Algunas implementaciones soportan filter=userName eq pero no filter=emails.value co, lo que rompe casos de uso habituales del IdP.

Manejo de grupos inconsistente. Los grupos anidados, los members de tipo group, y los cambios de membership vía PATCH son donde más bugs aparecen.

Autenticación frágil. SCIM no define un mecanismo estándar; la mayoría de integraciones usan un bearer token estático de larga duración, lo que es un secreto crítico que rara vez se rota.

Rota el bearer token SCIM al menos anualmente y trátalo como una credencial de alto valor. Un token SCIM comprometido permite crear, modificar y desactivar usuarios en la aplicación integrada.

Comparación con LDAP

La pregunta inevitable es por qué no basta con LDAP, que lleva dando servicio a la identidad corporativa desde los noventa. La respuesta tiene varias partes.

LDAP es binario, stateful, y su modelo de consulta es excelente para directorios centralizados dentro de una red corporativa. SCIM es REST/JSON, stateless, y está diseñado para cruzar fronteras de red e integrarse con SaaS a través de Internet. Un proveedor SaaS no va a abrir un puerto LDAP hacia su red; un endpoint HTTPS con bearer token sí.

LDAP y Active Directory siguen siendo la fuente de verdad de la identidad en muchas organizaciones. SCIM no los reemplaza; los complementa. El patrón habitual es AD como directorio autoritativo, el IdP (Entra ID, Okta) como broker que lee de AD y expone OIDC/SAML/SCIM hacia las aplicaciones.

Cuándo vale la pena

SCIM paga su coste cuando tienes al menos una decena de aplicaciones SaaS integradas con el IdP y un flujo JML activo. En ese escenario, automatizar provisioning reduce riesgo (cuentas huérfanas) y carga operativa (tickets de alta/baja) de forma medible.

Para organizaciones pequeñas con tres o cuatro apps y rotación baja, JIT provisioning vía OIDC suele ser suficiente. En JIT, la cuenta se crea la primera vez que el usuario hace SSO contra la app; los claims del token OIDC rellenan los atributos básicos. No cubre el leaver (la cuenta queda pero sin acceso efectivo porque el SSO fallará), pero es más simple y no requiere que la app soporte SCIM.

Cuándo no

Si la aplicación no soporta SCIM o lo soporta mal (sin PATCH, sin desactivación, con autenticación frágil), forzar la integración puede dar más problemas que valor. Un conector custom con webhooks específicos del proveedor puede ser más robusto a corto plazo, aunque menos estándar.

Tampoco tiene sentido para aplicaciones con pocos usuarios muy estables: el coste de mantener la integración no se amortiza.

Encaje arquitectónico

En un stack empresarial moderno, SCIM es la pieza de plumbing entre el IdP y el SaaS. La autenticación va por OIDC o SAML; el provisioning va por SCIM; la autorización fina, una vez dentro de la aplicación, la gestiona cada app según su modelo (RBAC, ABAC, ReBAC). Los tres protocolos resuelven problemas distintos y coexisten sin solaparse.

La observabilidad de SCIM es un punto frecuentemente descuidado. Monitorizar tasas de éxito de las operaciones, drift entre IdP y aplicación, y alertar ante fallos de desactivación es lo que convierte una integración funcional en una defensa operativa real.

Artículos relacionados en esta serie

Referencias

  • RFC 7642 (septiembre 2015). System for Cross-domain Identity Management: Definitions, Overview, Concepts, and Requirements.
  • RFC 7643 (septiembre 2015). System for Cross-domain Identity Management: Core Schema.
  • RFC 7644 (septiembre 2015). System for Cross-domain Identity Management: Protocol.
  • RFC 6902 (abril 2013). JavaScript Object Notation (JSON) Patch.
  • Okta (2024). SCIM Provisioning Developer Guide.
  • Microsoft (2024). Tutorial: Develop a SCIM endpoint for user provisioning to apps from Microsoft Entra ID.
Esta entrada está licenciada bajo CC BY 4.0 por el autor.