Traducción. Autoritativo: fs-idn-0007-oauth-provider.md.
Cuando esto se entregue, una app de terceros podrá preguntarle a un tenant “¿me dejas leer tus contactos y acreditar puntos?” y recibir un token acotado — y el sitio del propio tenant podrá ofrecer “Sign in with Softcrum” para que sus clientes reutilicen la identidad que ya tienen.
Contexto
OAuth en esta plataforma corre en ambas direcciones, y el tenant elige cuál quiere:- Saliente (este spec). Softcrum es el provider. Una app de terceros actúa por cuenta del tenant con consentimiento acotado, y el sitio del tenant puede ofrecer “Sign in with Softcrum” para que un member reutilice la identidad que ya tiene con ese tenant.
- Entrante (FS-IDN-0008). Softcrum es el client. El personal del tenant entra por el proveedor de identidad de la organización, o por Google, Microsoft o GitHub.
Alcance (normativo)
identity.oauth_clients: integraciones de terceros registradas.- Authorization code con PKCE para apps que actúan por cuenta de un usuario.
- Client credentials para integraciones servidor-a-servidor.
- Pantalla de consentimiento que muestra los permisos reales solicitados.
- OIDC sobre OAuth2:
id_token,.well-known/openid-configuration, endpoint JWKS yuserinfo, para que “Sign in with Softcrum” funcione con cualquier librería estándar. - Ambos realms direccionables. Un cliente puede autenticar a un usuario organizacional o a un member. Los realms siguen separados; un cliente declara a cuál apunta y nunca alcanza el otro.
- Tokens de acceso y refresh con rotación.
- Revocación por el tenant, por cliente, visible en una lista de apps conectadas.
Fuera de alcance (normativo)
- Ser un login general para productos ajenos. “Sign in with Softcrum” se ofrece para que las superficies propias del tenant —su tienda, su portal, una herramienta socia que autorizó— reutilicen una identidad que ya pertenece a ese tenant. No es una red de identidad pública.
- Grants implícito y de contraseña. Ambos están deprecados y no se ofrecerán.
- Un marketplace público de apps. Es superficie de producto propia; esto es su precondición.
- Registro dinámico de clientes en F1b.
Comportamiento (normativo)
- Authorization code con PKCE es obligatorio para flujos de usuario, para todo cliente incluidos los confidenciales. Los grants implícito y de contraseña no se implementan.
- Los scopes son agrupaciones de permisos de la plataforma, no un vocabulario aparte.
- La pantalla de consentimiento muestra los permisos en lenguaje claro, nombra al cliente y dice qué podrá hacer — no un string de scope opaco que el tenant tenga que descifrar.
- Una autorización otorgada crea asignaciones de rol para el cliente como sujeto (FS-IDN-0002), de modo que la verificación en request es idéntica a la de un usuario.
- Los códigos de autorización son de un solo uso y expiran en 60 segundos. Los redirect URIs calzan exactamente — sin prefijos ni comodines, que es donde viven los ataques de redirección.
- Los tokens de acceso son de vida corta (1 hora); los de refresh rotan en cada uso, y reutilizar uno revoca toda la autorización y notifica al tenant. Reutilizarlo significa que fue robado.
- El tenant ve las apps conectadas y puede revocar cualquiera. La revocación es inmediata sobre tokens de acceso y de refresh.
- Un cliente pertenece a un desarrollador y se otorga por organización. Un cliente autorizado por
tres tenants tiene tres autorizaciones independientes.
8b. Un cliente declara el realm al que apunta,
useromember, al registrarse y nunca puede alcanzar el otro. Un cliente de tipo member autentica solo a members de la organización que lo otorgó, y el claimsubque recibe está acotado a esa organización — consistente con que la identidad de member es por tenant (standards/data.md§2b). Dos tenants usando el mismo cliente para el email de la misma persona reciben sujetos distintos, y correlacionarlos es imposible por diseño. - Un cliente nunca puede pedir un permiso que su registro no declara, ni uno que el usuario otorgante no tenga. Nadie puede otorgar más de lo que tiene.
- Toda autorización y revocación escribe en
core.audit_logy es visible en el rastro del tenant. - PROHIBIDO: un token en un log, un fragmento de URL persistido, o un secreto de cliente en un bundle entregado al navegador.
Datos (normativo)
API (normativo)
Los endpoints OAuth viven en la raíz, fuera de
/v1/{module}, porque siguen un estándar que las
librerías esperan en rutas convencionales. Es la excepción documentada a DEC-D1.
Eventos (normativo)
identity.oauth.authorized y identity.oauth.revoked, con cliente y organización.
Criterios de aceptación (normativo)
- Un flujo de authorization code sin PKCE se rechaza, también para clientes confidenciales.
- Un redirect URI que difiere en un carácter se rechaza — sin calce por prefijo.
- Un código de autorización es de un solo uso y expira a los 60 segundos.
- Reutilizar un refresh token revoca toda la autorización y notifica al tenant.
- Un cliente que pide un permiso fuera de su registro se rechaza en el paso de autorización, con la razón mostrada al usuario.
- Un usuario no puede otorgar un permiso que él mismo no tiene.
- Revocar una app conectada invalida sus tokens de inmediato.
- El mismo cliente autorizado por dos organizaciones tiene dos autorizaciones independientes.
8b. Un cliente de realm member no puede autenticar a un usuario organizacional, y viceversa.
8c. El mismo email como member de dos organizaciones produce dos claims
subdistintos, y ninguna respuesta permite correlacionarlos. - Negativo: los grants implícito y de contraseña devuelven
unsupported_grant_type, y ningún token aparece en logs.
Ejecución
Un solo slice, comando síncrono. F1b. La capacidad de provider de Better Auth donde calce; cualquier brecha se implementa contra la especificación en vez de relajarla. La pantalla de consentimiento es una ruta defrontend/console alimentada por los datos de este módulo.