
# Endpoints de OAuth 2.0 y OpenID Connect

> **Estado: `planned`.** Esta página describe la superficie del protocolo de cada entorno de KeenAuth tal como se especifica en el plan (§13). Los endpoints se están desarrollando en la fase 2 y todavía no están disponibles en un entorno alojado. Los detalles pueden cambiar antes de la disponibilidad general.

Cada entorno es su propio servidor de autorización OAuth 2.0 y su propio proveedor OpenID Connect. Los endpoints no forman parte de la API de gestión: se encuentran en el host del entorno, `https://<environment-slug>.<region>.keenauth.app`, o en su dominio personalizado verificado. En la tabla, `<issuer>` es el emisor del entorno, es decir, el valor de `issuer` en el documento de descubrimiento.

## Endpoints

| Endpoint | Método y ruta | Autenticación del cliente |
|---|---|---|
| Descubrimiento | `GET <issuer>/.well-known/openid-configuration` y `GET <issuer>/.well-known/oauth-authorization-server` (RFC 8414, mismo contenido) | Ninguna |
| Claves | `GET <issuer>/.well-known/jwks.json` | Ninguna |
| Autorización | `GET` o `POST <login host>/oauth2/authorize` | Ninguna (navegador) |
| Solicitud de autorización enviada (RFC 9126) | `POST <issuer>/oauth2/par` | Obligatoria para los clientes confidenciales; `client_id` para los clientes públicos |
| Token | `POST <issuer>/oauth2/token` | Obligatoria para los clientes confidenciales; `client_id` para los clientes públicos (DPoP es opcional) |
| Autorización de dispositivo (RFC 8628) | `POST <issuer>/oauth2/device_authorization` | Igual que el endpoint de token |
| Revocación (RFC 7009) | `POST <issuer>/oauth2/revoke` | Igual que el endpoint de token |
| Introspección (RFC 7662) | `POST <issuer>/oauth2/introspect` | Solo cliente confidencial |
| UserInfo | `GET` o `POST <issuer>/oauth2/userinfo` | Token de acceso Bearer o DPoP |
| Cierre de sesión | `GET` o `POST <login host>/oauth2/logout` | Ninguna (`id_token_hint` o `client_id`) |

`<login host>` es cualquier dominio de inicio de sesión del entorno: el host predeterminado o un dominio personalizado añadido. El documento de descubrimiento solo se sirve en el host del emisor. En otro host de inicio de sesión, `/.well-known/openid-configuration` devuelve `404` con la URL del emisor en el cuerpo.

## Tipos de concesión

| Concesión | Uso |
|---|---|
| `authorization_code` | Inicio de sesión en navegador y aplicaciones nativas. Se requiere PKCE con `S256`. |
| `refresh_token` | Renueva los tokens. Cada uso rota el token de actualización, y reutilizar uno antiguo revoca toda la familia de tokens. |
| `client_credentials` | Acceso de máquina a máquina. |
| `urn:ietf:params:oauth:grant-type:device_code` | Dispositivos sin teclado, como un televisor o una herramienta de línea de comandos. |
| `urn:ietf:params:oauth:grant-type:token-exchange` | Delegación y suplantación entre servicios. |

No se admiten los flujos implícitos (`response_type=token` y cualquier variante que contenga `id_token`), la concesión de credenciales de contraseña del propietario de los recursos ni los tipos de respuesta híbridos, ni ahora ni más adelante. La RFC 9700 prohíbe los dos primeros.

## Autorización de dispositivo

Un dispositivo sin navegador inicia el flujo con `POST <issuer>/oauth2/device_authorization`. Solo pueden usarlo las aplicaciones de tipo `device` o `native` que incluyan explícitamente la concesión de dispositivo. La respuesta contiene un `device_code`, un `user_code` y una dirección de verificación. El usuario abre la dirección en otro dispositivo, inicia sesión y aprueba la solicitud. Mientras tanto, el dispositivo consulta el endpoint de token con `grant_type=urn:ietf:params:oauth:grant-type:device_code`. El `user_code` tiene 8 caracteres y se muestra como `XXXX-XXXX`. Un código de dispositivo es válido durante 10 minutos y funciona una sola vez. El dispositivo consulta como máximo cada 5 segundos; una consulta más frecuente recibe `slow_down`, que añade 5 segundos al intervalo. El `verification_uri` es `https://<login host>/u/device`, y antes de aprobar se muestra al usuario la aplicación, los ámbitos solicitados y el país del dispositivo que inició la solicitud.

## Reglas de seguridad

El entorno sigue sin excepciones las Mejores Prácticas Actuales de Seguridad de OAuth 2.0 (RFC 9700):

- El URI de redirección debe coincidir byte a byte con uno registrado. No hay comodines.
- PKCE solo acepta `S256`; `plain` siempre se rechaza. PKCE es obligatorio para los clientes públicos y está activado de forma predeterminada en todas las aplicaciones. Una aplicación `web` confidencial puede desactivarlo en su configuración, pero solo si en ese caso el entorno sigue exigiendo `nonce`.
- Los SDK oficiales envían un `state` de 128 bits y un `nonce`, y verifican ambos al recibir la respuesta.
- Un código de autorización es válido durante 60 segundos y funciona una sola vez. Presentar un código ya usado devuelve `invalid_grant` y revoca los tokens de actualización y el token de acceso que produjo el primer uso.
- Las solicitudes de autorización enviadas mantienen los parámetros de la solicitud fuera de la barra de direcciones del navegador. Están disponibles en todos los planes, y el ajuste `require_par` las hace obligatorias para una aplicación o para todo el entorno.
- Los tokens de actualización rotan en cada uso, y la detección de reutilización revoca la familia.
- DPoP (RFC 9449) vincula un token de acceso a una clave que mantiene el cliente. Para verificar tokens vinculados en su API, consulte [Verificación de tokens en su API](/docs/sdk/token-verification).

## Sesiones y cierre de sesión

Tras un inicio de sesión correcto, el entorno mantiene una sola sesión de Single Sign-On en una cookie `HttpOnly` en el host de inicio de sesión. Las aplicaciones del mismo entorno la reutilizan, de modo que una segunda aplicación no pide la contraseña otra vez, salvo que su política requiera una autenticación más fuerte o más reciente. Su código nunca ve la cookie: solo ve la respuesta de autorización.

El endpoint de cierre de sesión (OpenID Connect RP-Initiated Logout 1.0) termina esa sesión, revoca los tokens de actualización que le pertenecen y notifica a las aplicaciones que registraron una dirección de cierre de sesión de canal trasero. Para listar o revocar las sesiones de un usuario desde su backend, utilice los [endpoints de sesiones de la API de gestión](/docs/api/management/users/list-sessions).

Si el usuario inició sesión a través de una conexión empresarial, añada `federated=true` a la solicitud de cierre de sesión para cerrar también su sesión en su proveedor de identidad. La sesión aquí termina primero; después, el navegador va al cierre de sesión del proveedor de identidad (SAML single logout, o el endpoint de cierre de sesión del proveedor OpenID) y regresa a `post_logout_redirect_uri`. Esto ocurre solo cuando la conexión tiene activado el cierre de sesión en el proveedor de identidad y el proveedor publica una dirección de cierre de sesión. En caso contrario, o si no se puede contactar con el proveedor, la solicitud funciona como si no existiera el parámetro. Cerrar sesión en el proveedor de identidad también puede terminar las demás aplicaciones del usuario que lo utilizan.
