MCP Fusion/Security and governance/Autenticação
Autenticação
Três pacotes de autenticação para conectores: verificação de JWT com JWKS, chaves de API com comparação segura no tempo e o fluxo de autorização de dispositivo OAuth 2.0 transformado em ferramentas que o agente pode conduzir.
Um conector que atua na conta de alguém precisa saber quem está fazendo a solicitação. O MCP Fusion oferece três pacotes de autenticação, cada um com um middleware e uma ferramenta de autenticação opcional, para que o agente possa ser bloqueado, desafiado e depois liberado sem que o seu handler saiba a diferença.
De onde vem a identidade
A autenticação lê a identidade de ctx, e ctx é criado por requisição por contextFactory. A configuração canônica:
registry.attachToServer(server, {
contextFactory: async (extra) => ({
token: extra.session?.authToken ?? '',
headers: extra.headers ?? {},
}),
});Tudo abaixo lê esse contexto.
JWT
npm install @mcpfusion/jwtimport { requireJwt } from '@mcpfusion/jwt';
f.query('billing.list_invoices')
.use(requireJwt({
jwksUri: 'https://auth.example.com/.well-known/jwks.json',
issuer: 'https://auth.example.com/',
audience: 'my-connector',
requiredClaims: ['sub', 'tenant_id'],
onVerified: (ctx, payload) => {
ctx.tenantId = payload.tenant_id; // derived identity for the handler
},
}))
.handle(async (input, ctx) => listInvoices(ctx.tenantId));JwtVerifier aceita secret (HS256), publicKey (PEM) ou jwksUri (conjunto de chaves remoto, armazenado em cache por verificador). Com jose instalado, RS256, ES256 e JWKS funcionam; sem ele, um caminho nativo HS256 verifica com timingSafeEqual e recusa qualquer outro algoritmo. issuer, audience, clockTolerance (60 segundos) e requiredClaims são validados em cada token. verifyDetailed() retorna { valid, payload, reason } quando você quer o motivo em vez de null.
Ordem padrão de extração do token: ctx.token, depois ctx.jwt, depois ctx.headers.authorization (o prefixo Bearer é removido). As falhas retornam um toolError autocurável com o código JWT_INVALID e uma ação auth para recuperação.
O pacote JWT verifica tokens, mas não os atualiza. O código-fonte não oferece suporte a refresh token, então um conector que precise de acesso duradouro a um provedor deve usar o fluxo OAuth abaixo ou o cofre de credenciais.
A ferramenta opcional createJwtAuthTool() expõe verify e status como ações que o agente pode chamar quando o próprio cliente mantém o token.
Chaves de API
npm install @mcpfusion/api-keyimport { requireApiKey } from '@mcpfusion/api-key';
f.mutation('billing.refund')
.use(requireApiKey({
keys: [process.env.SERVICE_KEY!],
onValidated: (ctx) => { ctx.service = 'billing-service'; },
}))
.handle(...);As chaves podem ser texto simples, com hash interno por SHA-256 na construção, ou pré-hash, ou podem ser validadas pela sua função assíncrona validator. A ordem das verificações é: não vazia, minLength (16 por padrão), prefix opcional e depois o validador ou o conjunto de hashes. A ordem de extração é: ctx.apiKey, ctx.headers['x-api-key'] e então ctx.headers.authorization (os prefixos ApiKey e Bearer são removidos).
A comparação busca ser constante no tempo: o gerenciador compara hashes de uma forma que não interrompe no primeiro byte diferente. Não trate o comprimento da chave como um segredo.
Fluxo de dispositivo OAuth para o agente
Quando o conector precisa de uma conta que o agente ainda não possui, o fluxo precisa ser conduzido por uma conversa: o servidor entrega um código e uma URL, a pessoa aprova no navegador e o agente pergunta novamente. Esse é o RFC 8628, e o pacote o transforma em ferramentas:
npm install @mcpfusion/oauthimport { createAuthTool, requireAuth } from '@mcpfusion/oauth';
const auth = createAuthTool({
clientId: process.env.OAUTH_CLIENT_ID!,
authorizationEndpoint: 'https://auth.example.com/device/code',
tokenEndpoint: 'https://auth.example.com/device/token',
onAuthenticated: (token) => { /* cache or forward the token */ },
});
f.query('analytics.report')
.use(requireAuth()) // blocks with AUTH_REQUIRED until a token exists
.handle(...);A ferramenta expõe quatro ações:
| Action | Behavior |
|---|---|
login | solicita um código de dispositivo e retorna a URL de verificação e o código |
complete | troca o código uma vez; authorization_pending significa "ainda não, pergunte novamente" |
status | informa se existe um token e, opcionalmente, a qual usuário ele pertence |
logout | limpa o token |
O loop de consulta respeita o RFC 8628: a primeira consulta é imediata, authorization_pending continua, slow_down adiciona cinco segundos, qualquer outro erro termina com a descrição do próprio provedor e o prazo lança "Device authorization expired. Start a new flow." O verificador não envia um scope por você e não há atualização automática: o armazenamento do token é um arquivo no diretório pessoal (.mcpfusion/token.json, modo 0600, com fallback para icacls no Windows), portanto trate-o como o padrão local de usuário único e configure sua própria persistência para um conector hospedado.
requireAuth() verifica a presença de um token, não a sua validade. Combine-o com requireJwt quando o token upstream precisar ser verificado criptograficamente.
Notas de produção
- Prefira credenciais da plataforma a tokens de usuário para chamadas servidor a servidor: declare-as com
defineCredentialse leia-as comrequireCredential. Consulte Credentials. - No Vinkius Cloud, invoque com um token de conexão e use Connection Tokens no console para revogar o acesso por cliente.
- O middleware de autenticação compõe com o restante da cadeia: coloque-o na camada mais externa para que chamadas não autorizadas nunca cheguem à validação, como mostrado em Middleware and context.
Próximos passos
- Multi-tenant connectors: a identidade se torna isolamento
- Security pipeline: onde a autenticação fica entre as camadas
- Credentials: segredos do servidor sem tokens de usuário
