Vincular una identidad federada a un usuario
POST /v1/users/{user_id}/identities · permiso users:write
Vincula una identidad federada (el sujeto externo de una conexión social, SAML u OIDC) al usuario, para que este pueda iniciar sesión con esa conexión. linked_via siempre es admin_api. La conexión debe ser una conexión habilitada de este entorno cuyo tipo coincida con type. Si la misma identidad ya está vinculada a este usuario o a otro, la solicitud falla con 409 y no se revela el propietario. El sujeto externo es un dato personal: se almacena cifrado y nunca se devuelve, y el registro de auditoría de gestión user.identity_linked (actor: la clave de API) no lo contiene. Fusionar dos usuarios (source_user_id) no está disponible; un campo desconocido devuelve 400 unknown_field.
Solicitud
| Parámetro | En | Obligatorio | Descripción |
|---|---|---|---|
user_id |
path | sí | ID de usuario, con el prefijo usr_. |
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
type |
string | sí | social, saml u oidc; debe coincidir con la conexión (social para una conexión social, saml/oidc para una conexión empresarial de la misma estrategia). |
connection_id |
string | sí | ID de conexión, con el prefijo conn_. |
subject |
string | sí | Sujeto externo en el proveedor de identidad (OIDC sub, SAML NameID), de como máximo 1024 bytes en UTF-8. |
Respuesta
201 Created con la nueva identidad, en la forma devuelta por GET /v1/users/{user_id}/identities.
{
"id": "idn_0a1b2c3d4e5f6g7h8j9k0m1n2r",
"type": "oidc",
"connection_id": "conn_0a1b2c3d4e5f6g7h8j9k0m1n2s",
"provider": null,
"linked_via": "admin_api",
"created_at": "2026-01-15T09:30:00Z"
}
Errores
Cada error es un cuerpo application/problem+json con un code estable.
| HTTP | code |
Cuándo |
|---|---|---|
| 400 | malformed_request, unknown_field |
El cuerpo no es JSON válido o tiene un campo desconocido. |
| 409 | conflict |
La identidad ya está vinculada a un usuario (errors[]: identity_already_linked), o el usuario alcanzó el límite de identidades por usuario (errors[]: identity_limit_reached). |
| 415 | unsupported_media_type |
El cuerpo se envió sin Content-Type: application/json. |
| 422 | validation_failed |
Falta un campo o no es válido (/type, /connection_id, /subject), o la conexión no es una conexión habilitada de este entorno que coincida con type (errors[]: /connection_id, connection_unavailable). |
| 404 | not_found |
El usuario no existe en este entorno, se está eliminando o el ID tiene un formato incorrecto. |
| 401 | unauthenticated |
La clave de API falta, no es válida o ha sido revocada. |
| 403 | insufficient_permissions |
La clave no tiene el permiso users:write. |
| 429 | rate_limited |
Se superó el límite de frecuencia; respete Retry-After. |
| 503 | service_unavailable |
Una dependencia no está disponible temporalmente; reintente más tarde. |
Ejemplo
curl -X POST https://api.eu.keenauth.com/v1/users/usr_0a1b2c3d4e5f6g7h8j9k0m1n2p/identities \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{"type": "oidc", "connection_id": "conn_0a1b2c3d4e5f6g7h8j9k0m1n2s", "subject": "248289761001"}'
Datos personales
Este endpoint maneja datos personales: identidades vinculadas. Datos personales en las API de KeenAuth describe qué se almacena, durante cuánto tiempo se conserva y cómo se elimina. No envíe categorías especiales de datos personales (salud, datos biométricos, religión, opiniones políticas, orientación sexual) en ningún campo.