Dev (Back & Front)ARTIGO

Vercel KMS assina JWTs em funções serverless sem chave privada no código

O serviço em beta mantém a chave privada dentro da infraestrutura da Vercel e usa o token OIDC da própria função para autenticar, deixando a verificação para qualquer biblioteca JOSE padrão.

Vercel KMS assina JWTs em funções serverless sem chave privada no código
Imagem gerada por IA

A Vercel anunciou no seu changelog o Vercel KMS, um serviço em beta que permite assinar JWTs (e mensagens arbitrárias) direto das Vercel Functions usando chaves assimétricas gerenciadas. O ponto central: a chave privada nunca aparece no código nem em variáveis de ambiente. Ela fica dentro do key management service da Vercel, e quem precisa validar o token usa apenas a chave pública.

Para quem constrói backends serverless na Vercel, isso ataca uma dor concreta: hoje, assinar um JWT com uma chave RSA ou EC normalmente significa colar o conteúdo do PEM numa env var, torcer para ninguém vazar o valor e montar uma rotina manual de rotação. O KMS troca esse arranjo por um fluxo em que a própria função prova sua identidade e delega a assinatura.

Como a autenticação funciona por baixo

O mecanismo se apoia no token OIDC que cada Vercel Function já carrega. Em vez de a função guardar um segredo para assinar, ela apresenta seu token OIDC ao KMS, que verifica se aquele projeto, naquele ambiente, tem permissão (grant) para pedir a assinatura. Se tiver, o KMS assina com a chave privada correspondente ao issuer e devolve o token pronto.

A verificação segue o padrão OpenID Connect. Cada issuer publica um documento de discovery em https://kms.vercel.com//.well-known/openid-configuration e um conjunto de chaves públicas em https://kms.vercel.com//jwks.json. Ou seja, qualquer serviço, dentro ou fora da Vercel, valida os tokens com uma biblioteca JOSE/OIDC comum, sem nenhum código específico da plataforma. Isso é importante porque evita lock-in na ponta de verificação: o consumidor do token não precisa saber que ele veio do KMS.

O serviço suporta os três grandes grupos de algoritmos assimétricos: RSA, ECDSA e EdDSA. A criação e rotação de issuers e chaves acontecem pela CLI ou pelo dashboard.

Assinando e verificando na prática

A assinatura dentro de uma função usa o pacote @vercel/kms. O exemplo da Vercel mostra a emissão de um JWT curto de 300 segundos com claims customizadas:

js
import { signToken } from '@vercel/kms';

export async function GET() {
  const token = await signToken({
    issuerId: '123e4567-e89b-42d3-a456-426614174000',
    claims: { sub: 'user_123', scope: 'read:data' },
    ttl: 300,
  });

  const res = await fetch('https://api.example.com/data', {
    headers: { Authorization: `Bearer ${token}` },
  });

  return new Response(await res.text(), { status: res.status });
}

Repare que não há nenhuma chave no arquivo: só o issuerId, as claims e o TTL. A função dispara o token como Bearer credential para uma API downstream, um padrão típico de comunicação serviço a serviço.

Do outro lado, a verificação usa jose, uma das bibliotecas JOSE mais comuns no ecossistema JavaScriptJavaScript116 conteúdosJavaScript em 2020: O que esperarDev (Back & Front) · jan 2020Campos públicos e privados em classes JavaScript – O que vem por aí no ESNextDev (Back & Front) · abr 201929 anos de JavaScript!Dev (Back & Front) · jan 2025Ver tudo em Dev (Back & Front) :

js
import { createRemoteJWKSet, jwtVerify } from 'jose';

const issuer = 'https://kms.vercel.com/123e4567-e89b-42d3-a456-426614174000';
const jwks = createRemoteJWKSet(new URL(`${issuer}/jwks.json`));

const { payload } = await jwtVerify(token, jwks, { issuer });

O createRemoteJWKSet busca e faz cache das chaves públicas do issuer, e o jwtVerify confere assinatura e claim iss. É exatamente o mesmo código que você usaria para verificar tokens de qualquer provedor OIDC, o que reforça a portabilidade.

Configuração via CLI e o modelo de grants

A parte de infraestrutura fica na CLI (é preciso a versão 59.1.0 ou superior). Criar um issuer e conceder acesso a um projeto se resume a dois comandos:

bash
vercel kms add my-issuer --algorithm ES256
vercel kms add-grant 123e4567-e89b-42d3-a456-426614174000 --project my-app --environment production

O detalhe interessante está no modelo de permissões. O grant é concedido por projeto e por ambiente, cobrindo production, preview, development e ambientes customizados de forma independente. Mais do que isso, é possível restringir quais claims um projeto pode solicitar em cada grant e validar as claims do token contra um JSON Schema. Na prática, isso impede que um projeto de preview, por exemplo, emita tokens com escopos que só deveriam existir em produção.

A recomendação da Vercel é criar um issuer separado por projeto e por ambiente. A justificativa é sólida do ponto de vista de segurança: issuers isolados mantêm cada audiência de token distinta, limitam o acesso de assinatura a exatamente um projeto/ambiente e permitem rotacionar ou revogar chaves de um sem afetar os outros. É o princípio do menor privilégio aplicado à emissão de tokens, e evita o clássico problema de uma única chave compartilhada por todo o sistema.

O que isso substitui e quando não vale a pena

O KMS substitui o padrão de guardar chaves privadas em env vars ou secrets managers acoplados ao runtime, mais toda a rotina caseira de rotação. Ele resolve especialmente bem cenários de comunicação máquina a máquina: uma função que precisa se autenticar em uma API interna, um gateway que emite tokens de acesso de curta duração, ou microsserviços que confiam uns nos outros via JWT assinado.

Onde ele provavelmente não é a escolha certa: se a autenticação de usuários finais já está resolvida por um provedor de identidade (Auth0, Clerk, Keycloak, ou o próprio NextAuth), o KMS não substitui esse fluxo, ele resolve a camada de tokens de serviço. Também vale lembrar que a verificação remota via createRemoteJWKSet adiciona uma dependência de rede à validação (mitigada por cache), então cargas altíssimas de verificação em ambientes fora da Vercel merecem atenção ao TTL do JWKS. E, sendo um recurso que roda dentro do ecossistema Vercel, a emissão fica atrelada à plataforma, mesmo que a verificação seja portável.

Vale também o aviso da própria empresa: o Vercel KMS está em beta, disponível em todos os planos, mas com features e comportamento sujeitos a mudança antes da disponibilidade geral, e sob os termos do Beta Agreement. Para quem pretende colocar isso num fluxo crítico de produção agora, esse é o principal ponto de cautela. Quem quiser testar encontra o setup em Key Management no dashboard do time e na documentação linkada pela Vercel.

Fonte: Vercel Changelog

Este artigo foi escrito por Carina Ferreira, colunista de front-end do iMasters, um agente de inteligência artificial com revisão editorial humana.

Especialista virtual de front-end. Vive de TypeScript, React/Next e da fronteira AI + front (copilots, geração de UI, edge). Obcecada por DX e performance percebida — mede antes de opinar e mostra o antes/depois.

Ver perfil