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

# Login social y SSO empresarial

> Cuando esto se entregue, un equipo entra con la cuenta de Google que ya usa, y un cliente empresarial enruta toda su organización por su propio proveedor de identidad.

> Traducción. Autoritativo: [`fs-idn-0008-social-sso.md`](/modules/identity/features/fs-idn-0008-social-sso).

## Contexto

Esta es la **mitad entrante de la dualidad OAuth** (FS-IDN-0007 es la saliente): acá Softcrum es el
cliente, autenticando usuarios por el proveedor de identidad de otro. Ambas direcciones son
configuración, y un tenant bien puede usar las dos — enrutando a su personal por su IdP corporativo
mientras expone "Sign in with Softcrum" a sus clientes.

Dos necesidades distintas comparten ese mecanismo.

**El login social** quita una contraseña del flujo de registro, lo que mejora medible­mente la
activación. Es conveniencia y es barato.

**El SSO empresarial** es requisito de venta. Sobre cierto tamaño de empresa, "¿soporta SAML u OIDC?"
aparece en la checklist antes de que se evalúe el producto, y un "no" termina la conversación.

La consecuencia de seguridad que da forma al diseño: cuando una organización exige SSO, **la
contraseña y el magic link deben dejar de funcionar para sus miembros**. Una exigencia de SSO que
deja abierta la vía de contraseña no es una exigencia — el proceso de desvinculación del cliente
asume que revocar a alguien en su IdP revoca su acceso acá.

## Alcance *(normativo)*

* Proveedores sociales: Google, Microsoft y GitHub.
* Vinculación de cuenta: un usuario existente agrega un proveedor social a la misma cuenta.
* SSO empresarial sobre OIDC, por organización.
* Enrutamiento por dominio: un usuario de un dominio reclamado se envía al IdP de su organización.
* Exigencia de SSO, desactivando los demás métodos para esa organización.
* Aprovisionamiento JIT de membresía en el primer ingreso por SSO.

## Fuera de alcance *(normativo)*

* **SAML en F1b.** OIDC primero, que cubre los IdP modernos; SAML llega cuando firme un cliente que
  lo necesite. Agregarlo es un proveedor, no un rediseño.
* Aprovisionamiento SCIM — F2. El JIT cubre el alta; la baja sigue dependiendo del administrador
  hasta que llegue SCIM, y esa limitación se le dice al cliente en vez de ocultarse.
* Mapeo de roles desde grupos del IdP — F2.
* Login social para members, que se autentican en `core`.

## Comportamiento *(normativo)*

1. Un ingreso social que calza con un email **verificado** existente se vincula a ese usuario. Un
   calce no verificado **no** se vincula automáticamente — eso es toma de cuenta por una afirmación
   sin verificar.
2. Un usuario puede vincular varios proveedores y desvincular cualquiera, siempre que quede al menos
   un método de autenticación.
3. Una organización reclama un dominio por **verificación DNS**. Los dominios sin verificar nunca
   enrutan.
4. Con SSO exigido, contraseña y magic link quedan **desactivados para todo miembro de esa
   organización**, las sesiones existentes se revocan, y a los miembros se les explica por qué en su
   siguiente intento.
5. El aprovisionamiento JIT crea usuario y membresía en el primer ingreso por SSO, con un rol por
   defecto que la organización configura. Nunca otorga un permiso sensible.
6. Un owner de la organización queda **exento de la exigencia de SSO** y conserva vía de contraseña.
   Si el IdP se cae, alguien tiene que poder entrar y desactivar la exigencia; sin la excepción, una
   caída del IdP es un bloqueo total sin remedio.
7. Los cambios de configuración de SSO exigen reautenticación y quedan auditados.
8. Un IdP que deja de devolver a un usuario **no** desactiva su membresía. La baja es explícita hasta
   que exista SCIM, y desactivar en silencio ante una consulta fallida convertiría un hipo del IdP en
   un bloqueo masivo.

## Datos *(normativo)*

| Tabla                      | Invariantes clave                                                                                                                                                |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `identity.sso_connections` | `organization_id`; `protocol` oidc; issuer, client id, secreto cifrado; `claimed_domains` verificados por DNS; `is_enforced`; `jit_default_role_id`; `is_active` |

Los vínculos con proveedores sociales viven en `identity.auth_accounts` (FS-IDN-0003) y no acá: son
un método de un usuario, no una conexión de una organización.

## API *(normativo)*

| Endpoint                                          | Clase      | Permiso                               | Presupuesto  |
| ------------------------------------------------- | ---------- | ------------------------------------- | ------------ |
| `GET /v1/identity/auth/oauth/{provider}`          | Runtime    | público                               | p95 \<300 ms |
| `GET /v1/identity/auth/oauth/{provider}/callback` | Runtime    | público                               | p95 \<1 s    |
| `POST /v1/identity/auth/sso/discover`             | Runtime    | público, con rate limit               | p95 \<300 ms |
| `GET/PUT /v1/identity/sso-connection`             | Management | `identity.sso.{read\|update}`, reauth | p95 \<1 s    |
| `POST /v1/identity/sso-connection/verify-domain`  | Management | `identity.sso.update`                 | p95 \<1 s    |

## Eventos *(normativo)*

Ninguno más allá de los eventos de membresía que FS-IDN-0001 ya emite cuando el JIT crea una.

## Criterios de aceptación *(normativo)*

1. Un ingreso social con email verificado coincidente se vincula al usuario existente; con uno sin
   verificar no lo hace, y lo explica.
2. Desvincular el último método de autenticación se rechaza.
3. Un dominio enruta a un IdP solo tras verificación DNS.
4. Exigir SSO desactiva contraseña y magic link para esa organización y revoca sus sesiones.
5. Un owner conserva vía de contraseña bajo la exigencia.
6. El JIT crea usuario y membresía con el rol por defecto configurado, nunca uno con permiso
   sensible.
7. Un IdP que devuelve error no desactiva ninguna membresía.
8. **Negativo:** ningún proveedor social vincula a una cuenta cuyo email esté sin verificar en
   cualquiera de los dos lados.

## Ejecución

Un solo slice, comando síncrono. F1b. Proveedores por Better Auth; cada proveedor nuevo es
configuración, no una integración — un protocolo genuinamente nuevo (SAML) necesitaría su propio ADR.

## Preguntas abiertas

| # | Pregunta                                                                    | Decide | Para                            |
| - | --------------------------------------------------------------------------- | ------ | ------------------------------- |
| 1 | ¿El SSO empresarial se gatea a tier enterprise, o está en todos los planes? | Daniel | antes del lanzamiento comercial |
| 2 | ¿Qué proveedores sociales entran primero — los tres, o solo Google?         | Daniel | antes de aprobar                |

## Changelog

| Versión | Fecha      | Cambio           | Por qué | Autor                  |
| ------- | ---------- | ---------------- | ------- | ---------------------- |
| 0.1.0   | 2026-08-17 | Borrador inicial | —       | daniel + claude-opus-5 |

## Registro de entrega

*Aún no implementado.*
