SCIM 2.0: el estándar que automatiza el aprovisionamiento
Cómo SCIM 2.0 estandariza el aprovisionamiento de usuarios entre proveedores de identidad y apps — el modelo de recursos REST (User, Group, EnterpriseUser), los endpoints /Users, /Groups, /Bulk y /Schemas, las operaciones CRUD + Search + PATCH, cómo SCIM impulsa el ciclo JML y reemplaza scripts custom, y sus limitaciones reales con entitlements granulares y roles dinámicos.
Del momento del login al momento del ciclo de vida
Los protocolos hasta ahora — SAML, OAuth, OIDC — responden preguntas en el momento en que un usuario inicia sesión: quién eres, puede esta app actuar por ti. Pero ninguno crea la cuenta en primer lugar. Antes de que Sara pueda iniciar sesión en una app SaaS con SSO, una cuenta para Sara tiene que existir en esa app, con los atributos y membresías de grupo correctos — y cuando se va, tiene que removerse. Eso es aprovisionamiento, y SCIM 2.0 es el estándar que lo automatiza.
SCIM (System for Cross-domain Identity Management), definido en los RFC 7643 y RFC 7644 y finalizado en 2015, es el cableado de protocolo bajo el ciclo JML que estudiamos antes. Cuando se contrata a un joiner, SCIM crea sus cuentas; cuando un mover cambia de equipo, SCIM las actualiza; cuando un leaver se va, SCIM las desactiva y elimina. Si SAML/OAuth/OIDC tratan de usar una identidad, SCIM trata de mantener las cuentas que esa identidad posee en cada aplicación.
El problema que resuelve SCIM
Imagina una organización con un proveedor de identidad y cuarenta aplicaciones SaaS. Sin un estándar, conectarlas significa construir cuarenta integraciones — cada app con su propia API, sus propios nombres de campos, sus propias rarezas. Agrega un segundo IdP (tras una adquisición, digamos) y la cuenta se multiplica: es un problema N-por-M, donde cada fuente de identidad necesita cableado a medida hacia cada aplicación, y el mantenimiento nunca termina.
Peor aún, muchas apps ofrecían solo “lifecycle hooks” propietarios o ninguna automatización, así que los equipos recurrían a scripts custom: código pegamento frágil que se rompía cada vez que una app cambiaba su API, que nadie entendía del todo, y cuya mitad de desaprovisionamiento era la primera en saltarse o fallar en silencio — dejando justo las cuentas huérfanas que la reconciliación tiene que cazar.
SCIM reemplaza esa explosión N-por-M con un solo contrato. Cada app compatible con SCIM expone los mismos schemas de recursos, los mismos endpoints y las mismas operaciones, para que el IdP hable un protocolo con todas. Agrega una app capaz de SCIM y el aprovisionamiento en gran medida simplemente funciona; la era de los scripts custom — y sus fallos silenciosos de desaprovisionamiento — es lo que SCIM se construyó para terminar.
flowchart LR accTitle: SCIM como puente de aprovisionamiento entre el IdP y las apps accDescr: El sistema de RR. HH. alimenta al proveedor de identidad, que actúa como cliente SCIM. El proveedor de identidad empuja llamadas REST SCIM estandarizadas al endpoint SCIM de cada aplicación, que actúa como service provider SCIM, para crear, actualizar y desactivar cuentas. Un protocolo estándar reemplaza un conector custom separado por aplicación. HR[RR. HH. / fuente] --> IDP[IdP<br/>cliente SCIM] IDP -->|SCIM REST| A1[App A<br/>endpoint SCIM] IDP -->|SCIM REST| A2[App B<br/>endpoint SCIM] IDP -->|SCIM REST| A3[App C<br/>endpoint SCIM]
En términos de SCIM, el IdP (Okta, Entra ID, etc.) es el cliente SCIM, y cada aplicación es un service provider SCIM que expone un endpoint SCIM. El cliente empuja los cambios; el service provider los aplica a su propio almacén de usuarios.
El modelo de recursos: User, Group, EnterpriseUser
SCIM estandariza no solo la API sino la forma de los datos, mediante schemas identificados por URN. Tres importan más:
- User — el recurso persona central:
userName,name(congivenName/familyName),emails,active,groups, y más. - Group — un recurso colección con
members, usado para impulsar el acceso basado en grupos en la app destino. - EnterpriseUser — un schema de extensión que agrega atributos laborales que el User central no tiene:
employeeNumber,department,manager,costCenter,division.
Cada recurso SCIM es JSON y autodescriptivo: lista los schemas a los que se ajusta, para que un service provider sepa exactamente cómo interpretar cada campo que recibe. Un recurso SCIM User se ve así — nota cómo declara sus schemas y lleva la extensión enterprise como un bloque con namespace:
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User",
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User"
],
"id": "2819c223-7f76-453a-919d-413861904646",
"userName": "sara@example.com",
"name": { "givenName": "Sara", "familyName": "Lopez" },
"emails": [{ "value": "sara@example.com", "primary": true }],
"active": true,
"groups": [{ "value": "engineering", "display": "Engineering" }],
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {
"employeeNumber": "EMP-08531",
"department": "Engineering",
"manager": { "value": "26118915-6090-4610-87e4-49d8ca9f808d" }
}
}Dos campos merecen atención. El id es el identificador inmutable propio del service provider para el recurso — distinto del userName y del identificador del IdP — y es lo que las operaciones siguientes apuntan. El booleano active es el interruptor de desaprovisionamiento: ponerlo en false es cómo SCIM desactiva a un usuario sin eliminarlo, lo que mapea directamente a la regla JML de “desactivar primero”.
Los endpoints
Un service provider SCIM expone un conjunto pequeño y estándar de endpoints REST:
| Endpoint | Propósito |
|---|---|
/Users | Crear, leer, actualizar, eliminar y buscar recursos de usuario |
/Groups | Las mismas operaciones para grupos y su membresía |
/Bulk | Enviar muchas operaciones en una sola solicitud, por eficiencia a escala |
/Schemas | Descubrir los schemas (y atributos) que el servidor soporta |
/ServiceProviderConfig | Descubrir las capacidades del servidor — qué operaciones y filtros soporta |
/ResourceTypes | Descubrir los tipos de recurso que el servidor expone |
Los endpoints de discovery (/Schemas, /ServiceProviderConfig, /ResourceTypes) importan más de lo que parecen: como las implementaciones de SCIM varían en lo que soportan, un cliente bien portado consulta estos para aprender qué puede hacer realmente un service provider dado — por ejemplo si soporta PATCH u operaciones bulk — en lugar de asumir.
Las operaciones
SCIM mapea el ciclo de vida sobre verbos HTTP estándar contra esos endpoints:
| Operación | HTTP | Ejemplo |
|---|---|---|
| Create | POST | POST /Users con el nuevo recurso |
| Read | GET | GET /Users/{id} |
| Replace | PUT | PUT /Users/{id} — reemplazo completo del recurso |
| Update | PATCH | PATCH /Users/{id} — cambio parcial |
| Delete | DELETE | DELETE /Users/{id} |
| Search | GET / POST | GET /Users?filter=userName eq "sara@example.com" |
Dos distinciones importan en la práctica. PUT vs PATCH: PUT reemplaza el recurso entero — omite un campo y puede borrarse — así que el cliente debe enviar el objeto completo, mientras que PATCH aplica un cambio parcial (agregar/reemplazar/quitar atributos específicos) y es la opción más segura y ligera para actualizaciones rutinarias. Search con filtros: SCIM define una sintaxis de filtro (userName eq "...", active eq true) para que un cliente pueda encontrar un recurso por atributo, que es cómo un IdP correlaciona su usuario con el id del service provider antes de actualizar.
SCIM impulsando el ciclo JML
Junta las operaciones y obtienes el ciclo JML automatizado en forma de protocolo — el cableado concreto detrás de joiner, mover y leaver:
sequenceDiagram
accTitle: Operaciones SCIM a lo largo del ciclo JML
accDescr: Cuando una persona ingresa, el proveedor de identidad envía POST a /Users para crear la cuenta con active en true, y la app devuelve el id del recurso creado. Cuando la persona cambia de rol, el proveedor de identidad envía PATCH para actualizar atributos y membresía de grupo. Cuando la persona se va, el proveedor de identidad primero envía PATCH para poner active en false, suspendiendo el acceso, y luego envía DELETE para remover la cuenta tras el periodo de retención, reflejando la disciplina desactivar-luego-eliminar.
participant IdP as IdP (cliente SCIM)
participant App as App (service provider)
Note over IdP,App: Joiner
IdP->>App: POST /Users (active=true)
App->>IdP: 201 Created (id)
Note over IdP,App: Mover
IdP->>App: PATCH /Users/{id} (nuevo depto + grupos)
App->>IdP: 200 OK
Note over IdP,App: Leaver
IdP->>App: PATCH /Users/{id} (active=false)
App->>IdP: 200 OK
IdP->>App: DELETE /Users/{id} (tras la retención)
App->>IdP: 204 No ContentFíjate qué limpiamente el protocolo codifica la disciplina de ciclo de vida del artículo de JML. El leaver son dos pasos, no uno: un PATCH active=false corta el acceso de inmediato, y el DELETE viene solo tras la ventana de retención — desactivar primero, eliminar después, expresado en HTTP. Esto es justo por lo que SCIM importa para la seguridad, no solo para la comodidad: vuelve el desaprovisionamiento rápido y fiable una capacidad estándar en lugar del script custom más saltado.
Aprovisionamiento JIT vs SCIM
Hay una segunda forma en que se crean las cuentas, y deberías poder contrastarla con SCIM: el aprovisionamiento just-in-time (JIT). Con JIT, la cuenta se crea de forma perezosa en el primer login — cuando un usuario se autentica vía SAML u OIDC por primera vez, la app lee la assertion o el ID token y crea una cuenta local en el momento a partir de esos claims. No se necesita una llamada de aprovisionamiento previa.
El trade-off es decisivo:
- JIT es simple y no necesita integración SCIM — pero solo crea cuentas, en el login. No las actualiza cuando cambian los atributos, y crucialmente nunca las elimina. Un usuario aprovisionado por JIT que se va simplemente deja de iniciar sesión, dejando una cuenta dormida atrás. JIT no tiene historia de desaprovisionamiento en absoluto.
- SCIM aprovisiona antes del login y, decisivamente, maneja actualizaciones y desaprovisionamiento — el ciclo de vida completo, no solo el primer momento.
La regla práctica: usa SCIM siempre que necesites gestión real del ciclo de vida, que es la mayoría de los escenarios de plantilla, y trata a JIT como una comodidad ligera para casos de solo-creación o como complemento de SCIM. Si una app soporta solo JIT, entiende que acabas de heredar justo el problema de cuentas huérfanas que SCIM existe para resolver — un intercambio perfectamente razonable para una herramienta interna desechable, y uno silenciosamente peligroso para cualquier cosa que guarde datos sensibles o esté sujeta a auditoría.
Por qué SCIM reemplaza los scripts custom y los hooks propietarios
El argumento a favor de SCIM sobre los enfoques viejos es concreto:
- Un modelo de integración, no cuarenta. Aprende SCIM una vez y cada app compatible aprovisiona igual; incorporar un nuevo SaaS se vuelve configuración, no un proyecto de programación.
- Desaprovisionamiento fiable. Como
active=falseyDELETEson estándar, el offboarding es una operación de primera clase en lugar de la cola frágil de un script — encogiendo directamente el problema de cuentas huérfanas. - Mantenido por el ecosistema. Los IdP principales (Okta, Entra ID, OneLogin) y miles de apps SaaS traen soporte SCIM, así que el conector lo mantiene el proveedor, no tu pegamento frágil.
- Bidireccional e inspeccionable. Es REST/JSON plano sobre HTTPS — fácil de probar, registrar y razonar, a diferencia de la sincronización propietaria opaca.
SCIM a escala: bulk, paginación y sync inicial
Incorporar SCIM a una app que ya tiene decenas de miles de usuarios saca a la luz preocupaciones prácticas que el camino feliz esconde:
- Sync inicial. La primera corrida debe emparejar las cuentas existentes de la app con identidades del IdP — normalmente vía un filtro como
userName eq "..."— antes de poder gestionarlas. Equivócate en esta correlación y creas cuentas duplicadas en lugar de adoptar las existentes. - Paginación.
GET /Usersdevuelve resultados en páginas (startIndex,count,totalResults); un cliente debe paginar, nunca asumir que una sola respuesta contiene a todos. - Bulk. El endpoint
/Bulkpermite a un cliente enviar muchas operaciones en una solicitud, recortando los viajes de ida y vuelta para cambios masivos — aunque, como siempre, el soporte es disparejo. - Rate limits. Los service providers limitan el ritmo; un cliente bien portado hace backoff y reintenta en lugar de martillar el endpoint durante un sync grande.
Estos detalles operativos son donde los despliegues de SCIM de verdad tienen éxito o se estancan — el protocolo es simple, pero incorporar una base de usuarios existente a escala es donde se va el tiempo de ingeniería.
Asegurar el endpoint SCIM
Un endpoint SCIM está entre las interfaces más poderosas que una aplicación expone: puede crear, modificar y eliminar a cualquier usuario. Eso lo vuelve a la vez un objetivo de alto valor y una seria responsabilidad:
- Autenticación. Las llamadas SCIM se autentican, casi siempre con un bearer token de OAuth 2.0 emitido al conector del IdP. Ese token es efectivamente una credencial de admin para todo el almacén de usuarios — trátalo como tal.
- Protege el token. Guárdalo en un gestor de secretos, rótalo, acótalo tan estrechamente como el proveedor permita, y monitorea su uso. Un token SCIM filtrado le permite a un atacante crear cuentas backdoor o eliminar usuarios en masa.
- Mínimo privilegio y logging. El service provider debe autorizar al cliente de forma estricta, validar las entradas, y registrar cada operación — las acciones de aprovisionamiento son justo lo que un auditor y un respondedor de incidentes necesitan reconstruir.
- TLS siempre. Es REST sobre HTTPS; ni los datos del usuario ni el bearer token deberían cruzar nunca un canal en texto plano.
La ironía que vale interiorizar: el protocolo construido para remover acceso de forma fiable es él mismo una vía de acceso poderosa. Asegurar el canal SCIM es parte de asegurar la identidad, no una ocurrencia tardía.
Las limitaciones: lo que SCIM no hace
SCIM es excelente en lo que es y es importante entenderlo en sus bordes, porque sus limitaciones definen dónde toman el relevo otras capas:
- Sin entitlements granulares. SCIM aprovisiona cuentas y membresías de grupo, no permisos finos internos de la app. Puede poner a Sara en el grupo
Engineering; no puede expresar “puede aprobar reembolsos hasta $5,000” o “solo lectura en el dataset de la UE”. Esos entitlements viven dentro de cada aplicación o en una capa de gobernanza/autorización. - Sin roles dinámicos o basados en políticas. SCIM empuja valores concretos de atributos y grupos; no evalúa reglas como “otorga este rol a cualquiera en Finanzas en Alemania”. Esa lógica pertenece al IdP/IGA computando qué enviar, o a un motor de autorización basado en políticas en el momento del acceso.
- Modelo grueso. El estándar modela deliberadamente el común denominador — usuarios y grupos — que es por lo que es interoperable, pero también por lo que las estructuras profundas y específicas de cada app no mapean limpiamente.
- Deriva de implementación. Como advierte el callout, las diferencias de proveedor en PATCH y filtrado significan que “SCIM” en la práctica es una familia de dialectos, no un comportamiento uniforme.
En la práctica esta frontera es la fuente de un malentendido común: los equipos esperan que SCIM “sincronice permisos” y se sorprenden de que solo sincroniza cuentas y nombres de grupo. El grupo es un asa gruesa — la app destino todavía decide qué significa Engineering internamente. Cuando los stakeholders piden que SCIM cargue entitlements ricos, el movimiento correcto es empujar esa necesidad a las capas de gobernanza y autorización, no doblar el protocolo de aprovisionamiento alrededor de ella.
Nada de esto es un defecto — es alcance. SCIM es dueño del ciclo de vida de la cuenta; la autorización fina es un problema distinto resuelto por IGA (gobernanza) y por los modelos de autorización que veremos después en Access Management (RBAC, ABAC, ReBAC, motores de políticas). Conocer la frontera te evita intentar forzar lógica de entitlements en un protocolo de aprovisionamiento que nunca se diseñó para sostenerla.
Cómo encaja SCIM con los otros protocolos
Da un paso atrás y SCIM encaja en su lugar junto a los protocolos de federación — son complementarios, no alternativas:
- SCIM corre con antelación y mantiene la cuenta existente y correcta: crea la cuenta de Sara en la app, fija sus atributos, la pone en los grupos correctos, y la remueve en el offboarding.
- SAML u OIDC corren en el momento del login y prueban que es realmente Sara: ella se autentica en el IdP y es admitida a la app en la que ya tiene una cuenta.
Una configuración empresarial típica cablea ambos a la misma app desde el mismo IdP: SCIM para el ciclo de vida, SAML/OIDC para la autenticación. Quita SCIM y tienes SSO hacia cuentas que nadie mantiene — incluidos usuarios que se fueron y todavía pueden autenticarse. Quita el SSO y tienes cuentas bien gestionadas sin forma limpia de iniciar sesión. La pareja es el patrón estándar: SCIM administra la cuenta, la federación autentica al humano.
Eso también enmarca el arco de todo el módulo: directorio (dónde vive la identidad) → SAML / OAuth / OIDC (cómo viaja en el login) → SCIM (cómo se mantienen las cuentas en el tiempo). Cinco protocolos, un sistema coherente — el idioma común que este módulo se propuso enseñar.
Recapitulación
SCIM 2.0 es el estándar que automatiza el ciclo de vida de la cuenta:
- Es un estándar de aprovisionamiento REST/JSON (RFC 7643/7644) entre un IdP (el cliente SCIM) y las apps (service providers).
- Tres schemas: User, Group, y la extensión EnterpriseUser (department, manager, employeeNumber).
- Endpoints estándar —
/Users,/Groups,/Bulk,/Schemas,/ServiceProviderConfig— y operaciones estándar que mapean CRUD + Search + PATCH sobre verbos HTTP. - Es JML en forma de protocolo: POST para joiners, PATCH para movers,
active=falseluego DELETE para leavers — desaprovisionamiento desactivar-primero, estandarizado. - Reemplaza los scripts custom y los hooks propietarios, volviendo el desaprovisionamiento fiable una capacidad de primera clase y encogiendo las cuentas huérfanas.
- Sus límites definen las capas siguientes: SCIM hace cuentas y grupos, no entitlements granulares ni roles dinámicos — esos pertenecen a IGA y a los modelos de autorización. Y en un despliegue real se empareja con SAML u OIDC contra la misma app: SCIM administra la cuenta, la federación autentica al humano.
Ejercicios prácticos
Estos son prácticos — hazlos, no solo los leas:
- Lee un ServiceProviderConfig real. Encuentra la documentación de una app con SCIM (Okta, Slack, GitHub y muchas más publican sus schemas SCIM) e identifica qué operaciones soporta — ¿hace PATCH? ¿Bulk? ¿Qué operadores de filtro?
- Modela un User (caso de uso). Escribe el JSON de un recurso SCIM User para un nuevo empleado en Finanzas, incluyendo la extensión EnterpriseUser con department y manager. Marca qué campo asignaría el service provider en lugar de tú.
- Programa el ciclo de vida (caso de uso). Para un joiner, un mover (pasa a Ventas) y un leaver, escribe el verbo HTTP exacto, el endpoint y el payload clave de cada llamada SCIM — y explica por qué el leaver son dos operaciones, no una.
- PUT vs PATCH (caso de uso). Necesitas cambiar solo el departamento de un usuario. Muestra la solicitud PATCH, luego explica qué podría salir mal si usaras PUT con un body parcial en su lugar.
- Encuentra el límite (caso de uso). Tu app necesita otorgar “aprobador, hasta $10,000, solo región UE”. Explica por qué SCIM no puede expresar esto, qué sí puede hacer hacia ello (la parte de cuenta/grupo), y qué capa debe manejar el resto.
- Elige JIT o SCIM (caso de uso). Para cada uno, elige aprovisionamiento JIT o SCIM y justifícalo: una app de plantilla donde los leavers deben perder acceso en una hora; un wiki interno de bajo riesgo donde las cuentas pueden crearse en el primer login y nunca necesitan actualizarse. Luego enuncia qué perderías al elegir el otro.
Tres preguntas para autoevaluarte
- Una empresa conecta su IdP a una nueva app SaaS que anuncia “soporte SCIM”, pero los usuarios terminados siguen conservando acceso. Lista tres razones concretas por las que esto puede pasar a pesar de SCIM, y cómo diagnosticarías cada una.
- Explica cómo SCIM expresa la regla JML “desactivar primero, eliminar después” a nivel de protocolo, y por qué ese doble paso importa tanto para la seguridad como para la auditoría.
- ¿Por qué SCIM es deliberadamente incapaz de modelar entitlements granulares, y qué te dice eso sobre dónde debe vivir realmente la lógica de autorización?
Preguntas frecuentes
¿Qué es SCIM 2.0?
SCIM (System for Cross-domain Identity Management) 2.0 es un estándar REST/JSON, definido en los RFC 7643 y RFC 7644, para aprovisionar y desaprovisionar automáticamente cuentas de usuario y grupo entre un proveedor de identidad y las aplicaciones. Le da a cada app la misma API — los mismos schemas de recursos, endpoints y operaciones — para que crear, actualizar y desactivar cuentas se vuelva estandarizado en lugar de a medida por app.
¿Qué problema resuelve SCIM?
Antes de SCIM, conectar un proveedor de identidad a cada aplicación significaba un script custom o un conector propietario por app — frágil, inconsistente y una carga de mantenimiento, con el desaprovisionamiento especialmente poco fiable. SCIM reemplaza ese lío N-por-M con un único contrato REST estándar que cada app implementa igual, para que el IdP pueda crear, actualizar y remover cuentas en todas partes mediante un solo protocolo bien definido.
¿Cuáles son los schemas centrales de SCIM?
SCIM define tres: User (el recurso persona central — userName, name, emails, active, groups), Group (una colección con members) y EnterpriseUser (una extensión que agrega atributos laborales como employeeNumber, department y manager). Cada recurso declara sus schemas por URN, y los servidores exponen lo que soportan en el endpoint /Schemas, para que los clientes conozcan la forma exacta de los datos.
¿Cómo maneja SCIM el desaprovisionamiento?
De dos formas, reflejando la disciplina JML de desactivar-luego-eliminar. Para desactivar, el IdP envía un PATCH que pone el atributo active del usuario en false, lo que suspende el acceso preservando la cuenta. Para removerla por completo, el IdP envía DELETE. Las configuraciones maduras desactivan de inmediato ante un evento de leaver y eliminan solo tras la ventana de retención, así el acceso se corta rápido pero la auditoría y los datos sobreviven.
¿Cuál es la diferencia entre PUT y PATCH en SCIM?
PUT reemplaza el recurso entero con el payload que envías — lo que omitas puede borrarse — así que el cliente debe enviar el objeto completo. PATCH aplica un cambio parcial (agregar, reemplazar o quitar atributos específicos) sin reenviar todo, lo que es más seguro y eficiente para actualizaciones rutinarias como un cambio de departamento. PATCH es preferido para la mayoría de las actualizaciones del ciclo de vida, aunque el soporte de sus operaciones varía en la práctica.
¿Cuáles son las limitaciones de SCIM?
SCIM aprovisiona cuentas y membresías de grupo bien, pero no modela entitlements granulares internos de la app ni roles dinámicos basados en políticas — puede poner a un usuario en el grupo 'Ingeniería', no otorgar 'aprobar reembolsos hasta $5,000'. La autorización fina se queda dentro de cada app o en una capa de IGA/autorización. SCIM además sufre inconsistencia en el mundo real, ya que los proveedores implementan PATCH y el filtrado con diferencias sutiles.