Resumen

  • La revisión 11 de draft-ietf-oauth-attestation-based-client-auth se publicó el 3 de septiembre de 2026. El grupo OAuth abrió su Last Call el día 8 y recibirá comentarios hasta el 22.
  • Los desafíos del servidor son opcionales. Su vigencia y la posibilidad de usarlos en una o varias pruebas dependen solo de la política local. El cliente debe tomar el último desafío recibido y puede reutilizarlo.
  • Si el servidor admite un único uso, responde use_attestation_challenge en el siguiente intento, entrega un valor nuevo y el cliente debería reintentar una vez, nunca sin límite. El modo combinado DPoP utiliza otra vía.
  • La nueva metadata descubre métodos y algoritmos, no la regla de consumo. Daniel Kade propone describirla en un perfil de frescura; es una recomendación editorial, no una obligación acordada por el IETF.

Una decisión abierta llega a Last Call

El anuncio del grupo OAuth pide respaldo u objeciones razonadas antes del 22 de septiembre. El Datatracker muestra la revisión 11 como borrador activo del grupo y en Last Call. La noticia es que empieza una comprobación de consenso sobre el texto. Todavía no es un RFC, una aprobación definitiva ni una decisión atribuible a todo el IETF.

El borrador intenta autenticar una instalación concreta de software, no solo un nombre de cliente. Un Client Attester emite un Client Attestation JWT firmado y vinculado a la clave de esa instancia. Al contactar con el servidor de autorización o con un recurso protegido, la instancia aporta además una prueba de posesión. Así demuestra que controla la clave que el atestador incluyó en su declaración.

La prueba dedicada, denominada Client Attestation PoP JWT, incorpora un momento de creación y un identificador jti. El receptor también puede imponer frescura mediante un desafío propio. Puede enviarlo tras un error, aprovechar otra respuesta anterior o publicar un endpoint al que el cliente lo solicite. Cuando el cliente ha recibido uno, está obligado a usar el más reciente.

Lo que la revisión 11 no unifica es su consumo. La duración y la posibilidad de incluir el mismo desafío en más de una prueba quedan “solely” en manos de la política local del servidor de autorización o del recurso. Al cliente se le permite repetir el valor. Al servidor se le permite declararlo agotado después del primer éxito.

La libertad responde a despliegues distintos. Un sistema distribuido quizá quiera una breve ventana reutilizable para no coordinar cada petición. Otro, expuesto a mayor riesgo, puede reservar estado y exigir un valor por prueba. El problema de interoperabilidad no es que existan ambas opciones, sino que la cadena opaca no comunica cuál recibió el cliente.

La negociación ocurre después de gastar la petición

La ruta de recuperación está bien delimitada. Si falta el desafío esperado o ya no es aceptable, un servidor de autorización devuelve HTTP 400 con use_attestation_challenge; un recurso protegido devuelve HTTP 401 en su respuesta de autenticación. Ambos adjuntan un nuevo OAuth-Client-Attestation-Challenge. El cliente genera otra prueba y debería repetir la operación una vez. Tiene prohibido entrar en un ciclo interminable.

Ese límite contiene el daño, pero no evita el rechazo que sirve de descubrimiento. Imagine una aplicación que consulta el endpoint de desafíos antes de iniciar un lote y reparte el valor entre varios procesos. Con una política reutilizable, cada proceso puede construir su propio JWT y cada jti distingue la prueba. Con consumo único, el primer ganador invalida el valor para los demás. La única señal previa y la única señal posterior tienen el mismo aspecto; la diferencia vive en el servidor.

El capítulo de seguridad muestra por qué “usa desafíos” no es una descripción suficiente. El servidor puede registrar los jti vistos durante una ventana deslizante. Ese mecanismo detecta que alguien volvió a enviar la misma prueba. Si registra también los desafíos emitidos por el endpoint, obtiene una protección más fuerte gobernada por valores escogidos por él, con el coste de memoria y de un posible viaje adicional.

También puede construir desafíos autocontenidos y no guardar el conjunto de valores vistos. Esa opción escala, pero solo garantiza frescura: dentro de la ventana aceptada no evita por sí misma la repetición. Una tercera variante asocia un desafío con una sesión de la Client Instance y valida el único valor esperado en ella. Los tres diseños tienen costes y promesas diferentes aunque produzcan el mismo campo en el JWT.

El borrador conserva jti como requisito obligatorio y lo presenta como alternativa mínima cuando el servidor no soporta desafíos. También pide comprobar un intervalo temporal admisible. Son bases útiles, pero no convierten automáticamente un valor proporcionado por el servidor en una credencial de un solo uso ni en una prueba completa contra la repetición.

El modo combinado conserva la frontera de DPoP

Existe una segunda forma de probar posesión. En el modo combinado, una prueba DPoP del RFC 9449 cumple a la vez la función asociada a la atestación y la de restringir el token de acceso a una clave. La revisión 11 establece que esta ruta utiliza exclusivamente el nonce de DPoP.

Por eso el error correcto es use_dpop_nonce y la nueva frescura llega en DPoP-Nonce, no en el encabezado genérico de atestación. El endpoint de desafíos puede transportar ese nonce de antemano, pero no lo transforma en attestation_challenge. El transporte común ayuda a evitar un viaje; la semántica sigue separada.

La comparación oficial entre las revisiones 10 y 11 identifica como cambios la exclusividad del nonce en modo combinado, su entrega opcional desde el endpoint y la aclaración sobre soporte opcional y errores. Una biblioteca que fusione las dos cachés de frescura perdería precisamente esa mejora.

Se descubre la capacidad, no el contrato de frescura

Otra novedad es la metadata del cliente basada en el modelo del RFC 7591. El servidor puede publicar métodos de prueba aceptados y algoritmos de firma. La presencia de challenge_endpoint informa de dónde obtener un valor de manera proactiva. Antes de firmar, el cliente puede descartar un algoritmo o un modo que el otro extremo no entienda.

No puede descartar una estrategia de consumo incompatible. La metadata no declara que el desafío sea obligatorio, reutilizable, de un solo uso o ligado a sesión. Tampoco revela una clase de vigencia, si el servidor conserva valores vistos, si el formato autocontenido solo ofrece frescura o cuántos reintentos espera un perfil. Al operador le falta incluso una versión de política con la que explicar un cambio repentino en los rechazos.

No hace falta exponer el número exacto de segundos ni la estructura de almacenamiento. El servidor podría publicar una clase de duración y una etiqueta de consumo. single-use comunica lo necesario para serializar sin revelar cómo se implementa. freshness-only evita que un auditor atribuya defensa contra repetición a un valor autocontenido que no la proporciona.

Daniel Kade propone un pequeño objeto freshness-policy en un perfil de despliegue. Separaría attestation_pop_jwt de dpop_combined y declararía soporte o exigencia, canales de emisión, clase de vida, modo de consumo, postura de repetición, presupuesto de reintentos y época de política. Un recibo firmado podría fijar qué versión consultó el cliente antes de actuar.

Nada de esto figura como requisito en la revisión 11 ni representa consenso del grupo. El propio borrador contempla perfiles de ecosistema. Allí puede probarse la idea sin reescribir DPoP ni eliminar la discreción local que el texto quiso conservar.

Fuentes