Pular para o conteúdo

Assinatura de tokens

Escolha como um client assina o ID token e o access token, quando o HS256 com o client secret faz sentido, e como apps, APIs e servidores MCP verificam cada um.

Todo token que o Authio emite é um JWT assinado. Um client tem duas configurações de assinatura: uma para o que só o seu app lê (o ID token, a resposta assinada do UserInfo e o logout token do back-channel) e outra para o access token que as suas APIs leem. O refresh token não segue nenhuma das duas: o Authio sempre o assina com a própria chave. Para tokens que ninguém fora do app deve ler, veja Tokens criptografados.

As duas configurações

Em Clients, abra o client e vá em Editar → Segurança → Configuração de tokens. Cada configuração aceita RS, PS ou ES (assimétricos, verificados com as chaves públicas do realm) ou HS (HMAC, com o client secret como chave), em 256, 384 ou 512 bits.

Assinatura do ID token e do userinfoAssinatura do access token
AssinaO ID token, a resposta assinada do UserInfo e o logout token do back-channelO access token
Quem lêSó o seu appAs suas APIs: a API do próprio client, resource servers, servidores MCP
Com RS, PS ou ESO app verifica pelo JWKS do realmQualquer API verifica pelo JWKS do realm
Com HSO app verifica com o próprio client secretSó quem tem o client secret valida localmente; qualquer outra API valida por introspecção
Omitido ao criar o clientO padrão da família: PS256 para RSA, ES256 para ECDsa, HS256 para HMACO algoritmo do ID token quando ele é assimétrico; senão, PS256

O refresh token é sempre assinado pelo Authio

Só o Authio lê refresh tokens, então eles são sempre assinados com a chave que o Authio guarda para o client, seja qual for o valor das duas configurações. Rotacionar o client secret nunca encerra uma sessão: os refresh tokens continuam funcionando, e os tokens assinados com HS antes da rotação são simplesmente substituídos na renovação seguinte.

Quando usar HS256

O HMAC serve para um client confidencial cujos tokens só são lidos pelo próprio app e pela própria API, que já têm o client secret: eles verificam os tokens sem buscar um JWKS nem guardar chaves em cache. Em qualquer outro caso, prefira um algoritmo assimétrico: qualquer um verifica com a chave pública, nada secreto é compartilhado, e quem consegue verificar um token não consegue também assinar um.

SituaçãoEscolha
Só o seu app lê o ID token, e ele tem o secretHS no ID token serve
Só a sua própria API lê o access token, e ela tem o secretHS no access token serve
APIs de terceiros, resource servers ou servidores MCP leem o access tokenRS, PS ou ES no access token
Um client público: SPA, app mobile, CLIRS, PS ou ES nos dois: um client público não tem secret
Vários serviços precisariam compartilhar o secretRS, PS ou ES

Quem verifica um token HS também consegue assinar um

No HMAC, a chave que verifica é a mesma que assina. Mantenha o client secret nos servidores do próprio client: cada serviço que recebe o secret poderia emitir tokens que o Authio nunca emitiu.

O que o Authio aceita

RegraPor quê
Um client público não pode usar HS em nenhuma das duas configurações.O HS usa o client secret como chave, e um client público não tem um.
Com HS, o client secret precisa ter no mínimo 32, 48 ou 64 bytes para HS256, HS384 ou HS512.A RFC 7518 §3.2 pede uma chave no mínimo do tamanho do hash. Rotacione o secret ou escolha um hash menor.
Quando o ID token e o access token são os dois assimétricos, usam o mesmo algoritmo.Um client tem uma única chave de assinatura, que assina os dois tokens e todo refresh token.
HS no ID token com access token assimétrico é aceito, e o contrário também.O token em HS usa o secret; o outro token e o refresh token usam a chave do client.

Uma recusa aponta o campo com problema em notifications: clientConfiguration.clientTokenConfiguration.idTokenSigningAlgorithmType para um client público pedindo HS no ID token, clientConfiguration.clientTokenConfiguration.idTokenSigningAlgorithm para um secret curto demais para ele, e clientConfiguration.clientTokenConfiguration.accessTokenSigningAlgorithm para tudo o que diz respeito ao access token, inclusive dois algoritmos assimétricos diferentes.

Na Admin API

As configurações ficam em clientConfiguration.clientTokenConfiguration. algorithmJwsType agora é idTokenSigningAlgorithmType e digitalSubscriptionsAlgorithm agora é idTokenSigningAlgorithm, sem alias; accessTokenSigningAlgorithm é novo e aceita os mesmos valores. Na criação ele é opcional (omitido, vale o padrão acima); na atualização, omiti-lo mantém o algoritmo atual.

Corpo da requisiçãoJSON
{
  "clientConfiguration": {
    "clientTokenConfiguration": {
      "idTokenSigningAlgorithmType": "HMAC",
      "idTokenSigningAlgorithm": "HmacSha256",
      "accessTokenSigningAlgorithm": "RsaSsaPssSha256"
    }
  }
}
AlgoritmoFamília (idTokenSigningAlgorithmType)Valor
RS256, RS384, RS512RSARsaSha256, RsaSha384, RsaSha512
PS256, PS384, PS512RSARsaSsaPssSha256, RsaSsaPssSha384, RsaSsaPssSha512
ES256, ES384, ES512ECDsa, com jsonWebKeyECTypesEcdsaSha256, EcdsaSha384, EcdsaSha512
HS256, HS384, HS512HMACHmacSha256, HmacSha384, HmacSha512

APIs, resource servers e servidores MCP

Um access token assinado com HS não tem chave no JWKS do realm. A API do próprio client tem o client secret e o valida localmente; qualquer outra API (a de um terceiro, um resource server do realm, um servidor MCP) não tem o secret e precisa validar o token por introspecção, como o client de introspecção do resource server.

`accessTokenRequiresIntrospection`

A resposta do client traz accessTokenRequiresIntrospection: true quando o access token dele é assinado com HS e algum resource server do realm aceita o client, inclusive um servidor MCP. O console mostra isso como aviso e salva o client mesmo assim. Uma mudança nos resource servers pode levar até 5 minutos para aparecer nele.

Ou assine o access token do client com RS, PS ou ES, ou configure esses servidores para validar só por introspecção:

Node.js (Express)TypeScript
import { authioBearer } from '@hyper.authio/express'

app.use(
  '/api',
  authioBearer({
    issuer: process.env.AUTHIO_ISSUER!,
    audiences: 'https://orders.example.com',
    introspection: 'introspectionOnly',
    client: { clientId: 'orders-api', clientSecret: process.env.ORDERS_API_SECRET! },
  }),
)

O client em cada um deles é o client confidencial do próprio servidor, escolhido como Client de introspecção do resource server: o Authio informa que um token endereçado a um resource server está ativo só para esse client.

Configure o seu app e a sua API

As bibliotecas do Authio espelham o client: cada configuração é uma opção, e uma opção omitida fica desligada. Sem uma opção de assinatura, a biblioteca aceita só os algoritmos assimétricos que o realm publica, e recusa um token HS com invalid_algorithm, apontando a opção ou a introspecção. Com um algoritmo HS informado, ela verifica com o client secret, que precisa respeitar o mesmo tamanho mínimo de cima.

Node.js

No @hyper.authio/client e no @hyper.authio/bff 0.8.0, idTokenSignedResponseAlg cobre o ID token e o logout token, e userinfoSignedResponseAlg o UserInfo assinado, que segue idTokenSignedResponseAlg quando omitido. No @hyper.authio/server e no @hyper.authio/express, accessTokenSignedResponseAlg (um algoritmo ou vários) verifica HS com o clientSecret de client: { clientId, clientSecret }.

Login (client)TypeScript
import { createAuthioClient } from '@hyper.authio/client'

export const authio = createAuthioClient({
  issuer: process.env.AUTHIO_ISSUER!,
  clientId: 'storefront',
  clientSecret: process.env.AUTHIO_CLIENT_SECRET!,
  checks: ['pkce', 'state', 'nonce'],
  codeChallengeMethod: 'S256',
  idTokenSignedResponseAlg: 'HS256',
  redirectUri: 'https://shop.example.com/callback',
})

Sem resource, o aud do access token é a audiência configurada no client (Authio, a menos que você tenha mudado). Qualquer outra API valida por introspecção, como mostrado acima.

.NET

O Authio.Client, o Authio.AspNetCore e o Authio.AspNetCore.Bff 0.8.0 leem IdTokenSignedResponseAlg, UserinfoSignedResponseAlg (omitido, vale o do ID token) e AccessTokenSignedResponseAlg (um valor ou uma lista) da seção Authio. O HS é verificado com o ClientSecret, em bytes UTF-8.

appsettings.json (BFF)JSON
{
  "Authio": {
    "Authority": "https://authio.api.hyperio.tech",
    "Realm": "acme",
    "ClientId": "acme-web",
    "ClientSecret": "YOUR_CLIENT_SECRET",
    "IdTokenSignedResponseAlg": "HS256",
    "AccessTokenSignedResponseAlg": "HS256"
  }
}

Next.js (NextAuth v4 e Auth.js v5)

O @hyper.authio/provider-nextauth 4.0.0 recebe os metadados de client do próprio NextAuth: client.id_token_signed_response_alg para o ID token e client.userinfo_signed_response_alg para o UserInfo assinado. O HS é verificado com o clientSecret (AUTH_AUTHIO_SECRET no v5). O provider não tem configuração para o access token: ele lê o access token só para as claims de session.authio, e quem o verifica é a sua API.

auth.tsTypeScript
import NextAuth from 'next-auth'
import { createAuthio } from '@hyper.authio/provider-nextauth/v5'

export const authio = createAuthio({
  checks: ['pkce', 'state', 'nonce'],
  client: { id_token_signed_response_alg: 'HS256' },
  authorization: { params: { scope: 'openid profile email roles offline_access' } },
})

export const { handlers, auth, signIn, signOut } = NextAuth({
  providers: [authio.provider],
  callbacks: authio.callbacks,
  events: authio.events,
})

PKCE só com `plain` não funciona com o NextAuth

O NextAuth e o Auth.js só enviam challenges S256, e codeChallengeMethod: 'plain' é recusado quando a integração é criada. Um client com PKCE ligado que só permite plain recusa todo login vindo deles: permita S256 no client.

Problemas comuns

SintomaCausa e correção
invalid_algorithm no app ou na APIO client assina com HS e a biblioteca não foi avisada. Defina idTokenSignedResponseAlg, accessTokenSignedResponseAlg ou client.id_token_signed_response_alg, ou valide por introspecção.
invalid_signature em tokens HSA biblioteca tem um secret diferente do atual do client, depois de uma rotação, por exemplo. Atualize-o.
Um resource server ou servidor MCP recusa todo tokenO access token do client é assinado com HS. Passe-o para RS, PS ou ES, ou valide por introspecção (introspectionOnly).
O salvamento recusa HS: client públicoDê um secret ao client (autenticação de client ligada) ou escolha RS, PS ou ES.
O salvamento recusa HS: o secret é curto demaisRotacione o secret, ou escolha HS256, que pede 32 bytes.
O salvamento recusa dois algoritmos assimétricosEscolha o mesmo algoritmo para os dois, ou assine o ID token com HS.
A biblioteca falha na inicialização pedindo um secret maiorUm algoritmo HS foi informado e o client secret que ela recebeu tem menos de 32, 48 ou 64 bytes.

Cookies de analytics

Gostaríamos de medir como o console é usado, com o Google Analytics, para enxergar em quais telas as pessoas travam. Isso grava um cookie que reconhece este navegador na sua próxima visita.

Recusar não muda mais nada. Os cookies que mantêm você conectado e lembram o seu idioma e o seu tema são necessários para o console funcionar, e ficam de qualquer forma. Ler a Política de Privacidade