CAPÍTULO 45 · PARTE IV

OAuth 2.0: delegación y límites del protocolo

OAuth 2.0 como autorización delegada entre clientes y recursos protegidos: Authorization Code + PKCE, tokens, audiencia, ciclo de vida, sender-constraining y límites frente a identidad y autorización de negocio.

Nivel N2–N3 · Estado published

Una aplicación puede pedir acceso sin recibir la contraseña

Una aplicación de gastos necesita consultar recibos de una API. El recurso pertenece a una persona que ya tiene una relación con el servicio, pero la aplicación no debe recibir su contraseña ni adquirir una capacidad indefinida sobre todos sus datos. La solución no consiste en llamar “autenticación” a cualquier token que viaje por HTTP. Consiste en separar quién autoriza, qué aplicación solicita, qué servidor emite un artefacto de acceso y qué servidor protege el recurso.

OAuth 2.0 es un marco de autorización delegada. Permite que un client obtenga acceso acotado a un protected resource en nombre de un resource owner, o en algunos perfiles en nombre del propio client. El client presenta después un access token al resource server (RS). El authorization server (AS) emite ese token después de procesar el grant y las reglas de su despliegue. El RS todavía debe validar la presentación y aplicar su propia decisión sobre la operación concreta.

Esta separación importa porque OAuth no define por sí solo una identidad humana, una sesión web, un sistema de provisioning ni la autorización final de una operación de negocio. Un access token tampoco es automáticamente un ID token, una cookie o un session secret. El capítulo 37 aporta la diferencia entre sujeto, principal, autenticación y sesión; el 40 aporta el modelo de policy y enforcement; el 41 distingue token y sesión; y el 44 cubre directorios y sincronización. El capítulo 46 tratará OpenID Connect (OIDC), que añade una capa de identidad sobre flujos relacionados, pero OAuth no es “login”.

La pregunta conductora será:

¿Cómo obtiene un client acceso limitado a una API sin recibir la contraseña del resource owner, y cómo decide el RS si acepta una presentación concreta?

La respuesta debe conservar actor, artefacto, precondición, autoridad y límite. “El token tiene una firma válida” no basta para afirmar que una llamada está autorizada. “El AS concedió scope=payments.read” tampoco sustituye la policy del RS sobre una acción, un objeto y un contexto.

Antes de empezar

Debes poder distinguir principal, autenticación, autorización y sesión; leer una decisión con sujeto, acción, objeto, contexto y policy; y seguir un token sin tratarlo como estado global. El capítulo 37 aporta identidad y sesión, el 40 autorización, el 41 ciclo de vida de tokens y sesiones, y el 44 la frontera de provisioning y sincronización. No necesitas conocer JWT, DPoP, mTLS ni un producto de IdP para comenzar.

Trabajaremos en dos niveles. En N2 reconstruirás roles y Authorization Code Flow, y distinguirás scope, audiencia, access token y sesión. En N3 diagnosticarás redirect URI, state, PKCE, replay, refresh rotation, revocation, introspection y sender-constraining con evidencia y límites.

1. Roles, recurso y frontera de confianza

RFC 6749 define cuatro roles. El resource owner es la entidad capaz de conceder acceso a un recurso protegido; cuando es una persona, se habla de end-user, pero el rol no convierte a OAuth en una especificación de identidad. El client es la aplicación que hace peticiones protegidas en nombre del resource owner y con su autorización. “Client” describe una función del despliegue, no que sea un navegador, un backend o una persona. El authorization server emite access tokens después de procesar el grant; el resource server hospeda el recurso y acepta o rechaza peticiones que presentan tokens.

En Northstar, Elena puede autorizar a expense-ui a leer recibos. expense-ui es el client; el servidor que presenta la pantalla de consentimiento y emite el token es el AS; receipts-api es el RS. Elena puede ser resource owner del conjunto de recibos, pero el token no prueba por sí solo quién es Elena ante cualquier consumidor. La relación con la cuenta y la autenticación que haga el AS pertenece al contexto del despliegue y a otros protocolos.

El protected resource no es “todo lo que el usuario puede hacer”. Es un recurso servido por un RS que recibe una presentación. El authorization grant es la credencial o representación de la autorización que el client usa para obtener un token; el authorization code es una forma transitoria de grant, no el access token y no una sesión. El flujo tiene un authorization endpoint para la interacción de autorización y un token endpoint para el intercambio. El RS no debe recibir el code como si fuera un token.

El primer control conceptual es separar tres preguntas:

  1. ¿Quién autorizó qué? El AS procesa un grant y una policy de emisión.
  2. ¿Qué artefacto se presentó? El client envía un access token con un alcance y un destinatario esperados.
  3. ¿Se permite esta operación? El RS valida el token y evalúa su policy local para acción, objeto y contexto.

Un token puede ser emitido para un recurso y seguir siendo insuficiente para una operación sensible. Una respuesta positiva del AS no hace que el RS pierda su autoridad. Tampoco una llamada aceptada prueba que la aplicación tenga una identidad humana, un permiso futuro o una sesión web equivalente.

No mezclar vocabularios

“Authorization server” no es sinónimo universal de “identity provider”. Un AS puede autenticar al resource owner como parte de un despliegue, pero OAuth no normaliza el método ni emite por eso un ID token. OIDC, que se estudiará después, define objetos de identidad adicionales. “Client” no significa “usuario”. “Scope” no significa necesariamente un permiso de negocio. “Audience” no identifica a la persona: restringe el receptor previsto del token cuando el contrato lo define.

Un servicio puede usar OAuth para proteger una API de provisioning que aparece en el capítulo 44. Eso no convierte la petición OAuth en una sincronización LDAP/SCIM ni prueba que el usuario final haya iniciado sesión. Del mismo modo, presentar un token a un RS no es una decisión de RBAC, ABAC o ReBAC: el token puede aportar entradas a la policy de cc-0040, pero el PDP/PEP o la lógica local conserva su autoridad.

2. Authorization Code Flow: dos canales y un intercambio

El flujo que usaremos como base es Authorization Code. El client prepara una solicitud para el authorization endpoint con su client_id y una redirect_uri registrada. Para proteger la correlación, el client usa state cuando el perfil lo requiere; si el AS soporta PKCE, el perfil puede permitir que PKCE aporte la protección CSRF, pero state y PKCE siguen teniendo propiedades distintas. El navegador o user agent lleva la solicitud al AS por el front-channel. El AS procesa la autorización con su método propio, que no debemos dibujar como una contraseña que vuelve al client.

Si el AS acepta el grant, redirige el user agent a la redirect URI registrada con un authorization code y, cuando corresponde, el state. El client compara el state con el estado asociado a la transacción. Después usa un back-channel para enviar el code al token endpoint; incluye el redirect_uri y el code_verifier cuando usa PKCE. El AS verifica que el code, el client, la redirect URI y el binding de PKCE correspondan. Sólo entonces puede emitir un access token y, si su policy lo contempla, un refresh token.

El authorization code debe ser de vida corta y de un solo uso: RFC 6749 exige que el AS lo invalide después de usarlo y que reduzca la ventana de exposición. No se debe enviar el access token en la redirección sólo para ahorrar el intercambio. El BCP de seguridad vigente desaconseja el implicit grant y recomienda el Authorization Code Flow porque reduce la exposición en URLs y permite vincular el resultado a un client o a un proof de posesión. Esa recomendación debe atribuirse a RFC 9700, no presentarse como si RFC 6749 original tuviera exactamente el mismo texto.

Figura 45-01 · ¿Qué cruza front-channel y back-channel en Authorization Code + PKCE?

Desliza horizontalmente para leer el diagrama a tamaño completo.

El cliente genera un verifier y envía sólo su challenge S256 por el front-channel. El authorization server devuelve un code ligado a cliente, redirect URI y challenge; el cliente canjea code y verifier por back-channel y recibe un access token. Los fallos de correlación o binding se rechazan. El flujo obtiene autorización delegada y no demuestra por sí solo login o identidad del usuario.

state no es PKCE ni identidad

state correlaciona una respuesta con la solicitud que el client inició y, cuando se usa para esa función, aporta protección contra CSRF. Debe ser impredecible, específico de la transacción y validarse antes de aceptar la respuesta. El client debe tener una defensa CSRF; si el AS soporta PKCE, RFC 9700 permite apoyarse en PKCE para esa defensa en el contexto indicado, pero no convierte a state en innecesario en todos los perfiles. state no es una prueba de que el usuario sea quien dice ser, ni contiene por sí solo una autorización.

PKCE añade otro vínculo. El client crea un code_verifier secreto para esa transacción y envía al AS un code_challenge; la opción recomendada es S256(BASE64URL(SHA-256(ASCII(code_verifier)))), no el texto literal del verifier. El verifier queda para el intercambio en el token endpoint. Un interceptor que obtenga el code pero no el verifier no puede completar ese intercambio bajo el contrato PKCE. PKCE no autentica al resource owner y no arregla una redirect URI abierta, un AS mal identificado o un access token que después se filtra.

En una aplicación pública, como una SPA o una aplicación nativa, no debe colocarse un client_secret esperando que JavaScript o el paquete distribuido lo mantenga confidencial. Un public client no puede guardar un secreto estático de forma fiable. Un backend que mantiene una credencial fuera del navegador puede clasificarse como confidential client, pero “confidential” describe la capacidad de proteger credenciales, no una garantía de que la implementación sea segura o confiable. Los public clients deben usar PKCE según el BCP vigente; PKCE también es recomendable para confidential clients cuando ayuda a prevenir inyección o uso indebido del code.

Redirect URI, TLS y mix-up

La redirect URI es una frontera de retorno, no un texto decorativo. El AS debe compararla con el registro del client con la exactitud exigida por el perfil; un wildcard u open redirector puede permitir que un code o token termine en un destino no autorizado. La excepción de puertos variables para loopback en aplicaciones nativas está acotada por su BCP y no convierte en válidos los patrones arbitrarios.

TLS protege el canal conforme a su configuración, pero no reemplaza state, PKCE, registro de redirect ni comprobación de audience. Si un client habla con más de un AS, debe defenderse del mix-up: puede usar la identificación del issuer en la respuesta según RFC 9207 u otra separación de endpoints/redirects que permita distinguir la autoridad. Descubrir metadata de un AS o de un RS tampoco crea automáticamente una trust anchor; el issuer y la forma de validar esa metadata deben estar dentro del modelo de confianza.

Un diagnóstico profesional separa fallos: redirect URI incorrecta, state ausente o de otra transacción, verifier que no corresponde, issuer equivocado y code reutilizado no son una única categoría “OAuth roto”. Cada uno tiene una precondición, una evidencia y un control distinto.

3. Cliente, token y decisión del recurso

Después del intercambio, el client presenta un access token al RS. RFC 6749 permite que el token sea un identificador que el RS consulta o un valor autocontenido verificable; no obliga a que sea JWT. El formato, los claims y el transporte dependen del contrato del deployment. RFC 6750 describe el bearer token: si las demás comprobaciones pasan, quien posee el artefacto puede intentar usarlo. Eso no debe confundirse con identidad, y la posesión no elimina la necesidad de TLS, audience, vigencia, scope y policy.

El RS debe validar las condiciones que el contrato declara. Entre ellas pueden estar el issuer esperado, la audience o resource previsto, exp y nbf, el tipo de token, la firma y las claves permitidas, el estado consultado mediante introspection y el sender binding. No todos los tokens contienen todos esos campos, por lo que no se debe convertir una forma concreta en requisito universal. Un token opaco puede requerir introspection; uno autocontenido puede validarse localmente, pero la elección tiene consecuencias de revocación, caché, disponibilidad y rotación.

Validación local no significa “usar una respuesta cacheada del AS”. En el camino local, el RS verifica en cada presentación los claims y la firma contra sus claves y política de issuer/audience, aunque sus claves o metadatos tengan caché propia. En el camino de introspection, el RS consulta el estado que conoce el AS y puede cachear esa respuesta sólo dentro de una freshness/lifetime declarada. Ambas rutas pueden divergir después de una revocación; la diferencia debe aparecer en la evidencia y en la decisión de riesgo.

Resource, audience y scope

El parámetro resource, cuando el deployment usa Resource Indicators, permite señalar al AS el recurso protegido al que se solicita acceso. aud puede restringir el destinatario de un token. Scope es un vocabulario acordado por el deployment que describe el acceso concedido o solicitado. Los tres conceptos se relacionan, pero no son sinónimos:

En Northstar, receipts.read puede ser suficiente para GET /receipts/2048, pero no para POST /payments/approve. Un token con aud=receipts-api y scope de lectura no se vuelve permiso de aprobación porque esté firmado. El RS debe verificar que es el destinatario y después consultar su policy de acción, objeto, contexto y estado. Puede decidir reject, review o permit según ese contrato. El scope es una entrada acotada, no una orden universal al PEP.

Figura 45-02 · ¿Cómo se separan resource, audience, scope y autorización local?

Desliza horizontalmente para leer el diagrama a tamaño completo.

El cliente pide un recurso y scopes; el authorization server aplica el grant y puede reducirlos al emitir un token destinado a una audience. El resource server verifica que es el destinatario e interpreta el scope, pero todavía evalúa acción, objeto, contexto y política local. Audience incorrecta o scope insuficiente se rechazan; ninguno identifica al usuario ni concede por sí solo un permiso de negocio.

La audiencia tampoco es una identidad humana. Que un token tenga aud=receipts-api no prueba que Elena lo haya usado, que la aplicación sea confiable ni que el recurso esté permitido para cualquier método. Cuando la llamada cruza tenants, APIs o intermediarios, el contrato debe declarar qué identifica el resource y cómo se valida. La recomendación de restringir el token al RS previsto aparece en RFC 9700; no se debe afirmar que todos los despliegues históricos ya tienen esa restricción.

Autenticación del client frente a autorización del recurso

La autenticación del client en el token endpoint responde a una pregunta distinta de la autorización del resource owner y de la aceptación de una llamada al RS. Client credentials, mTLS o una clave privada pueden autenticar al client ante el AS; un token sender-constrained puede demostrar después la posesión de una clave ante el RS. Ninguna de esas operaciones, aislada, decide si el objeto invoice-2048 admite approve.

El capítulo 40 ayuda a escribir la última parte: formaliza sujeto/principal operativo, acción, objeto, contexto y sesión, además de PDP, PEP y estados indeterminados. OAuth puede aportar un principal delegado o un scope, pero no reemplaza las entradas que falten ni convierte un active=true de introspection en un permit de negocio.

4. Refresh tokens, rotación y reuse

Un refresh token permite al client pedir nuevos access tokens bajo el contrato del AS sin repetir todo el grant cada vez. No es una sesión web y no debe aparecer en una página pública o en un log. Su uso, expiración, sender binding y revocación dependen del client y de la policy. La emisión de un refresh token no es obligatoria para todos los grants ni convierte al client en dueño del recurso.

Para un public client, el BCP vigente exige que los refresh tokens estén sender-constrained o que el AS use rotation para detectar replay. Con rotation, el uso de RT0 entrega un nuevo access token y RT1, invalida RT0 y conserva la relación entre ambos. El uso posterior de RT1 genera RT2 e invalida RT1. Si alguien presenta de nuevo RT0, el AS detecta reuse y revoca el refresh token activo asociado al grant; cortar además toda una familia, revocar el grant u otros tokens es una respuesta adicional definida por la política del despliegue. La detección no demuestra cuál de dos presentadores era el legítimo: una carrera entre dos peticiones puede producir la misma señal. La recuperación puede obligar a obtener un grant nuevo, pero no debe describirse como logout global automático.

Figura 45-03 · ¿Qué ocurre al rotar y reutilizar una familia de refresh tokens?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Cada uso de RT0 produce un access token y RT1, invalida RT0 y conserva su parentesco. Si luego alguien presenta RT0, el servidor detecta reutilización, pero no sabe si la petición anterior o la actual era legítima; revoca el token activo asociado y fuerza un grant nuevo. La carrera concurrente puede causar la misma protección y debe gestionarse explícitamente.

La evidencia debe distinguir emisión, uso, invalidación y observación del rechazo. Una respuesta de invalid_grant en el token endpoint no indica por sí sola si hubo atacante, cliente duplicado, reloj inválido o token ya usado; hay que revisar la línea temporal, la familia y el contrato. La carrera de dos refresh simultáneos puede hacer que una petición válida pierda la punta de la familia y active el mismo control de reuse. Un access token ya emitido puede seguir siendo aceptado en un RS que valida localmente hasta expirar o hasta aplicar otra señal. Revocar un refresh token no implica que cada access token, cookie o sesión web se cierre en el mismo instante.

5. Bearer, mTLS y DPoP: limitar el replay

Un bearer token depende de la posesión del artefacto. Si una copia llega a otro host y el RS acepta issuer, audience, lifetime y scope, la copia puede ser utilizable. TLS reduce exposición durante el transporte, pero no deshace una filtración en un proxy, un proceso o un log.

Un token sender-constrained añade una prueba de que el presentador tiene una clave o certificado ligado al token. RFC 8705 separa la autenticación mTLS del client (§2) del access token certificate-bound que comprueba el RS (§§3–3.2). Cuando un AS emite un refresh token a un public client que usa tokens ligados a certificado, RFC 8705 recomienda —SHOULD, no MUST— ligarlo también al certificado y comprobar ese vínculo al canjearlo; deja el mecanismo concreto a criterio del AS (§4). Para confidential clients autenticados con mTLS, el refresh token queda ligado indirectamente mediante el client ID y la autenticación basada en certificado exigida al canjearlo (§7.1). Estas funciones son complementarias: autenticar al client ante el AS no demuestra por sí solo el binding de un access token presentado al RS. El RS debe comparar el certificado de la conexión con la confirmación del token. Un certificado del servidor TLS no es automáticamente la credencial del client.

RFC 9449 define DPoP. El client firma un proof JWT por petición con una clave privada; el proof contiene datos de la petición como método y URI y, al presentar un access token al RS, debe incluir ath para vincular el proof a ese token. El receptor valida firma, binding, frescura y replay (jti y, cuando se exige, nonce). DPoP demuestra posesión de una clave para una petición; por sí solo no es login ni autorización de acceso. Tampoco protege si el atacante roba el token y la clave, controla el cliente legítimo o logra que éste firme una petición peligrosa.

El contraste profesional es condicional:

Desliza horizontalmente para consultar todas las columnas.

Modelo Lo que debe presentar el llamante Qué reduce Qué no resuelve por sí solo
Bearer Token y transporte/validaciones del contrato Exposición accidental sólo si otros controles la contienen Uso por cualquier poseedor de una copia válida
mTLS-bound Token y clave privada del certificado en conexión mTLS Replay por quien sólo robó el token Robo conjunto de token y clave, policy de negocio, identidad humana
DPoP Token y proof firmado ligado a clave y request Replay en otro request/cliente sin la clave Compromiso del cliente/clave, autorización local, todas las formas de exfiltración

No se debe mostrar DPoP como cifrado, ni mTLS como una policy de negocio. Sender-constraining reduce una clase de replay; no convierte un scope amplio en mínimo privilegio ni sustituye audience, expiry, revocation o policy.

Figura 45-04 · ¿Qué prueba adicional exigen mTLS y DPoP frente a bearer?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Con bearer, una copia del token puede bastar si las demás validaciones pasan. Un token certificate-bound exige además demostrar en mTLS la clave del certificado cuyo thumbprint está ligado al token. DPoP exige un proof firmado ligado a la clave, token y petición. Ambos reducen el uso de un token robado, pero no protegen si también se roba la clave ni autentican por sí solos al usuario.

6. Revocación, introspection y ventana de aceptación

RFC 7009 define un endpoint de revocación. La respuesta satisfactoria puede no revelar si el token era válido para evitar filtraciones y no prueba que todos los receptores hayan observado el cambio. RFC 7662 define introspection: el RS consulta al AS si el token está activo y recibe metadatos que puede usar en su propia decisión. active=false no explica toda la causa, no es una identidad y no es una autorización de negocio.

Ventanas y pruebas negativas

Supón que el client revoca AT1 en t0. El RS A consulta introspection en cada petición y puede rechazar al recibir active=false. El RS B valida localmente un token autocontenido: si sigue vigente y el contrato no le entrega una denylist, evento u otra señal de revocación, puede aceptarlo hasta exp. Su caché de claves o metadata sirve para verificar firma y confianza, pero no crea estado de revocación ni fija por sí sola t1. La observación correcta no es “revocación cerró el ecosistema”, sino “A rechazó desde la consulta observada; B siguió aceptando hasta exp o hasta recibir y aplicar la señal contratada; la ventana medida fue…”. Una caché sí puede prolongar la aceptación cuando almacena explícitamente una respuesta previa de introspection con active=true; entonces su TTL y el lifetime del token delimitan el riesgo.

La prueba negativa debe ejecutarse por RS y con un token sintético autorizado: registrar t0, consultar o presentar el token sin almacenar su valor secreto, observar el status y correlacionar la decisión. Una respuesta HTTP 200 del endpoint de revocación no es la prueba final de rechazo en todos los recursos. Tampoco se debe afirmar que un JWT “no se puede revocar”: puede existir denylist, introspection, expiración corta, rotación de claves u otra política, pero cada opción tiene costes y alcance.

Figura 45-05 · ¿Qué pueden afirmar revocación e introspection bajo caché y propagación?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Una solicitud de revocación puede recibir 200 aunque el token ya fuese inválido; el authorization server actualiza su estado, pero cada resource server deja de aceptar según su ruta de validación. Introspection puede devolver active false tras consulta y caché; validación local requiere otra señal, estado o expiración. La prueba concluyente es el rechazo observado en todos los receptores dentro de una ventana definida, no la respuesta del endpoint.

7. Workloads, client credentials y token exchange

El grant Client Credentials sirve para un client que actúa según su propia autorización, por ejemplo un job de conciliación que llama a una API interna. No debe fingirse que existe un resource owner humano si el contrato no lo define. El RS puede registrar el client o un principal de workload, pero eso no equivale a atribuir la acción a Elena.

La delegación con usuario es distinta: el client obtiene un grant en nombre de un resource owner y recibe un token con alcance acotado. La policy del RS aún puede exigir que el actor operativo, el objeto y el contexto sean válidos. El mismo nombre “access token” no borra la diferencia entre el sujeto delegado y el client que lo presenta.

Token Exchange de RFC 8693 es una extensión para solicitar un token a partir de un security token o una representación de confianza. Puede expresar impersonation o delegation y puede conservar subject y actor con semánticas distintas. No debe enseñarse como una escalada automática. El AS debe declarar qué audiencia, scope, subject, actor y policy permiten la emisión, y el RS debe validar el resultado. Si el capítulo no puede citar una implementación concreta, debe mantener token exchange como modelo limitado y no como parte obligatoria del Authorization Code Flow.

En todos los casos hay que preguntar: ¿quién está autenticando al client?, ¿qué sujeto representa el token?, ¿qué actor lo presenta?, ¿qué recursos y operaciones quedan autorizados?, ¿qué evidencia permite distinguir delegación de impersonation? Una cadena de tokens no hereda permisos sin contrato explícito. El hecho de que un servicio pueda intercambiar un token no le concede automáticamente todos los scopes del token de entrada.

8. Diagnóstico: separar observación, inferencia y control

Los fallos de OAuth deben investigarse por etapa. En Northstar, una llamada puede fallar antes del AS, en el redirect, en el intercambio, en la validación del RS o en la policy de negocio.

Redirección y transacción

Si la URI vuelve a https://client.example/callback-test pero sólo está registrada https://client.example/callback, la evidencia es una discrepancia de redirect. Si el state no corresponde a la transacción pendiente, la respuesta no debe aceptarse aunque el code tenga formato correcto. Si el verifier no corresponde al challenge, el token endpoint debe rechazar el intercambio. Si hay varios AS y la respuesta no identifica al esperado, hay una hipótesis de mix-up que necesita su propia evidencia. No es válido resumir todo como “TLS estaba activo”.

Token y receptor

Si la firma es válida pero iss no pertenece al trust model, el token no es aceptable. Si el issuer es correcto pero aud apunta a otra API, el RS equivocado debe rechazarlo. Si audience e issuer son correctos pero el scope no cubre la operación, el RS debe rechazar por alcance insuficiente; si el scope sí la cubre, todavía debe aplicar la autorización local sobre acción, objeto y contexto. Si el token está expirado o introspection devuelve active=false, la llamada no debe continuar. Cada decisión debe indicar el RS, la policy, el reloj usado y el motivo.

Replay y ciclo de vida

Dos usos del mismo refresh token después de una rotación prueban una señal de reuse, no la identidad del atacante. Un access token rechazado por DPoP puede indicar proof inválido, key binding incorrecto, ath erróneo, URI/método discrepante o replay, no necesariamente robo. Una revocación confirmada por el AS debe contrastarse con el estado observado por cada RS. Los logs deben conservar IDs sintéticos, hashes o referencias de evento, issuer/audience, timestamps, result codes y decisiones, nunca passwords, client_secret, authorization codes, refresh tokens o access tokens completos.

Causalidad y límites

La investigación debe clasificar:

OAuth no arregla por sí solo un account provisionado mal, una policy PEP que falla abierta, una sesión web que conserva estado o una cuenta LDAP que todavía está activa. Esas hipótesis se investigan en las fronteras de cc-0037, cc-0040, cc-0041 y cc-0044.

Figura 45-06 · ¿Qué amenaza rompe qué supuesto y qué control BCP la contiene?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Cinco amenazas se vinculan a supuestos y controles distintos: redirect URI estricta, PKCE para code injection/interception, correlación CSRF, identificación del issuer contra mix-up y audience/sender constraint contra replay. Cada fila incluye una prueba negativa y un límite; TLS o PKCE aislados no hacen seguro todo el flujo, y OAuth sigue siendo autorización delegada, no protocolo de login.

9. Extensiones, perfiles y estado de las normas

El núcleo del capítulo usa RFC 6749, RFC 6750, RFC 7636 y el BCP de seguridad RFC 9700. Según la necesidad, se mencionan RFC 7009, 7662, 8252, 8414, 8705, 8707, 9207, 9396, 9449 y 10017. Cada extensión conserva la frontera principal; no reemplaza consentimiento, PKCE, validación de redirect, audience ni policy del RS.

RFC 10017 es una BCP publicada en agosto de 2026 para aplicaciones basadas en navegador. Sus perfiles deben distinguirse, no colapsarse: browser-only deja al navegador como public client y exige decidir dónde se guardan y presentan los tokens; un token-mediating backend conserva o media tokens para el browser sin convertirlo mágicamente en un confidential client; un backend-for-frontend (BFF) mantiene la sesión/token boundary en el backend y presenta al navegador una interfaz de aplicación. Son arquitecturas con amenazas y trade-offs distintos, no una recomendación universal. RFC 10017 aporta un modelo de amenazas para JavaScript, extracción de tokens y elección del perfil; no debe convertirse en la afirmación de que todo browser client requiere BFF ni en una regla para ocultar fallos de CSRF, redirect o policy. Tampoco debe mezclarse con RFC 8252: las aplicaciones nativas tienen su propia guía de external user-agent y redirects.

RFC 9126 (PAR) puede llevar parámetros de autorización al AS antes del redirect; RFC 9396 (RAR) puede transportar detalles estructurados de autorización; RFC 8414 y RFC 9728 publican metadata. Estas extensiones no son atajos para trust, policy o validación. Si aparecen en una integración, deben tener un claim, un locator y una razón para entrar en el flujo; si no, quedan fuera del núcleo.

OAuth 2.1 no es un RFC publicado. A fecha de esta edición, draft-ietf-oauth-v2-1-16 sigue siendo Internet-Draft y debe rotularse como borrador, con su fecha y versión. Las decisiones actuales deben derivarse de RFC publicados y BCP 240 (RFC 9700), no de una promesa sobre el contenido final de OAuth 2.1. No se deben enseñar implicit grant ni Resource Owner Password Credentials como prácticas actuales sólo porque aparezcan en material histórico.

Síntesis

OAuth 2.0 separa al client que solicita, al AS que emite, al resource owner que concede y al RS que protege. Authorization Code + PKCE reduce el riesgo de que un code interceptado o inyectado se canjee sin el vínculo de la transacción. Redirect URI, state, issuer y TLS resuelven propiedades distintas. El access token expresa acceso delegado para un recurso y alcance definidos; su firma o su estado activo no sustituyen audience, expiración, sender binding ni autorización local.

Refresh rotation y revocation trabajan sobre ciclos de vida que no son idénticos a la sesión web. Introspection puede informar el estado que el AS conoce, pero la aceptación efectiva depende de cada RS, su caché y su policy. mTLS y DPoP limitan ciertas formas de replay mediante posesión de una clave; no son login ni autorización. Client Credentials y Token Exchange representan perfiles distintos de workload y delegación, y no deben atribuir identidad humana o permisos transitivos sin contrato.

El modelo profesional conserva la pregunta “¿qué se observó, quién tenía autoridad, qué artefacto cruzó qué frontera y qué conclusión queda limitada?”. Esa disciplina evita convertir OAuth en un sistema de identidad, una sesión, un directorio o una policy engine.

Fuentes principales