Resumo

  • A revisão 11 de draft-ietf-oauth-attestation-based-client-auth foi publicada em 3 de setembro de 2026. O grupo OAuth abriu Last Call no dia 8, com prazo até 22 de setembro.
  • Desafios fornecidos pelo servidor são opcionais. A validade e a possibilidade de usar um valor em um ou vários Client Attestation PoP JWTs dependem somente da política local. O cliente usa o mais recente e pode reutilizá-lo.
  • Um servidor de uso único recusa a segunda tentativa com use_attestation_challenge, envia um valor novo e espera uma única repetição, nunca um loop. O modo combinado DPoP segue o nonce do RFC 9449.
  • A nova metadata anuncia métodos e algoritmos, mas não a regra de consumo. Daniel Kade propõe uma declaração de política de frescor em um perfil; a ideia é análise editorial, não requisito do IETF.

O Last Call abre uma decisão, não a encerra

O aviso do grupo OAuth pede manifestações de apoio ou objeções justificadas até 22 de setembro. No Datatracker, a revisão 11 aparece como documento ativo do grupo em Working Group Last Call. O estágio importa porque o grupo está testando se o texto pode avançar; não transforma a proposta em RFC nem prova consenso do IETF inteiro.

O projeto trata da autenticação de uma instância específica de software. Um Client Attester assina um Client Attestation JWT que liga sua declaração à chave daquela instalação. Ao chegar ao servidor de autorização ou ao recurso protegido, a instância apresenta outra prova de que controla a chave privada correspondente. Atestado e prova de posse cumprem funções complementares.

No modo normal, essa segunda peça é um Client Attestation PoP JWT. Ela inclui tempo de criação e um jti único. O servidor também pode impor frescor com um desafio opaco de sua autoria. Há três maneiras de entregá-lo: em resposta a um erro, em uma resposta anterior ou por um challenge endpoint que o cliente consulta proativamente. Depois de receber uma versão, o cliente tem de usar a mais recente.

A revisão 11 não define uma validade comum. Também não decide se um desafio pode constar de uma ou de várias provas. Esses dois pontos pertencem exclusivamente à política local do servidor de autorização ou do recurso. O cliente pode reaproveitar a sequência; o servidor que a aceita uma única vez pode considerar o segundo uso inválido.

Há razões para os dois desenhos. Um servidor que consome cada valor obtém uma fronteira estreita, mas precisa guardar estado e coordenar concorrência. Um valor reutilizável por pouco tempo combina melhor com serviços distribuídos, desde que outro identificador diferencie uma prova legítima de um replay. A incompatibilidade nasce porque o valor opaco não anuncia qual desenho está do outro lado.

A falha virou uma consulta de política

Depois da divergência, o protocolo é objetivo. O servidor de autorização devolve HTTP 400 e use_attestation_challenge; o recurso protegido responde HTTP 401 na camada de autenticação. Ambos devem entregar um desafio fresco em OAuth-Client-Attestation-Challenge. O cliente cria uma prova nova e deveria tentar outra vez, mas apenas uma. Repetir indefinidamente é proibido.

O limite evita uma espiral, não o primeiro tropeço. Uma aplicação pode buscar o valor antes e distribuí-lo a dez processos que farão requisições de token. Com política reutilizável, cada processo assina seu próprio JWT, com jti diferente. Com política de consumo único, a primeira conclusão invalida o valor para os outros nove. Todos estavam em conformidade quando decidiram reutilizar; só o erro revela que precisavam serializar.

O capítulo de segurança descreve opções que dão peso a essa diferença. O servidor pode conservar jti já vistos numa janela deslizante e detectar o reenvio da mesma prova. Pode ainda guardar os desafios emitidos pelo endpoint. Aí ganha detecção de replay mais forte com um valor que ele próprio escolheu, pagando pela estrutura de dados e, às vezes, por uma viagem adicional.

Outra opção é emitir um desafio autocontido sem armazenar a lista dos já vistos. O ganho é escala. A limitação é explícita: há frescor, mas não proteção contra replay dentro da janela aceita. O servidor pode ainda associar um desafio a uma sessão da Client Instance e validar o valor esperado para aquela sessão. O mesmo campo transporta compromissos operacionais e garantias diferentes.

O suporte a desafios continua opcional para manter simples a implementação mínima. O jti é obrigatório e funciona como fallback; o servidor também deve avaliar uma janela temporal aceitável. Portanto, ativar um desafio não significa, sozinho, que ele seja descartável ou que exista memória de replay.

O modo DPoP combinado não usa esse desafio

No modo combinado, uma prova DPoP definida pelo RFC 9449 demonstra a posse da chave da instância e também restringe o token de acesso ao remetente. A revisão 11 esclarece que esse caminho usa exclusivamente o mecanismo de nonce do DPoP.

Quando o nonce esperado falta, a resposta correta é use_dpop_nonce com o cabeçalho DPoP-Nonce, não use_attestation_challenge. O challenge endpoint pode fornecer esse nonce antecipadamente e poupar uma ida de falha, mas não transforma as duas espécies de valor em sinônimos. Um infraestrutura de entrega é uma coisa; semântica de protocolo é outra.

A comparação oficial entre as revisões 10 e 11 destaca a exclusividade do nonce no modo combinado, a possibilidade de entregá-lo pelo endpoint e o esclarecimento do erro quando desafios são opcionais. Um SDK que compartilhe cache e tratamento entre as duas vias desfaz justamente essa precisão nova.

A metadata termina antes da decisão mais cara

Outro acréscimo da revisão é a metadata de cliente apoiada no modelo geral do RFC 7591. Cliente e servidor podem anunciar algoritmos de assinatura e métodos de prova compatíveis, como attestation_pop_jwt e dpop_combined. A URL de challenge_endpoint também é detectável. Isso permite rejeitar certas combinações antes de gerar a prova.

O cliente ainda não consegue descobrir a estratégia que muda seu escalonamento. Não sabe se o desafio é exigido, a classe de validade, se o primeiro sucesso o consome, se o servidor guarda valores presenciados, se o formato autocontido garante apenas frescor ou a qual modo cada regra se aplica. Tampouco há uma época de política para ligar uma mudança no servidor a uma onda de erros de segundo uso.

Divulgar segundos exatos ou a estrutura interna seria desnecessário. A política pode variar com carga e risco. Categorias externas já bastam: single-use, reusable ou session-bound; witnessed-state ou freshness-only. Elas dizem ao cliente como se organizar e ao auditor que garantia não deve presumir, sem entregar o segredo de implementação.

Daniel Kade propõe um objeto enxuto de perfil chamado freshness-policy. Para cada modo de prova, ele indicaria se o frescor fornecido pelo servidor é suportado ou obrigatório, canais de emissão, classe de vida, consumo, postura contra replay, quantidade de repetições automáticas e versão da política. Um recibo assinado poderia vinculá-lo à metadata realmente consultada.

Essa proposta não está na revisão 11 e não representa consenso do grupo OAuth. O documento já admite perfis de ecossistema. É nesse nível que a ideia deve ser testada, preservando a escolha local do protocolo básico sem forçar cada fornecedor a codificar uma regra privada.

Fontes