Phase 13 - Lesson 16

Segurança de MCP II — OAuth 2.1, Indicadores de Recurso, Escopos Incrementais

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Servidores MCP remotos precisam de autorização, não apenas autenticação. A especificação de 25-11-2025 se alinha com OAuth 2.1 + PKCE + indicadores de recurso (RFC 8707) + metadados de recurso protegido (RFC 9728). A SEP-835 adiciona o consentimento de escopo incremental com autorização step-up em 403 WWW-Authenticate. Esta lição implementa o fluxo de step-up como uma máquina de estados para que você possa ver cada etapa.

Tipo: Build Linguagens: Python (stdlib, simulador de máquina de estados OAuth) Pré-requisitos: Fase 13 · 09 (transports), Fase 13 · 15 (security I) Tempo: ~75 minutos

Objetivos de Aprendizado

  • Distinguir as responsabilidades do servidor de recursos daquelas do servidor de autorização.
  • Percorrer o fluxo de código de autorização OAuth 2.1 protegido por PKCE.
  • Usar resource (RFC 8707) e metadados de recurso protegido (RFC 9728) para evitar ataques de deputado confuso.
  • Implementar autorização step-up: o servidor responde 403 com WWW-Authenticate solicitando um escopo maior; o cliente solicita novamente o consentimento do usuário e tenta novamente.

O Problema

As primeiras versões do MCP (pré-2025) enviavam servidores remotos com chaves de API ad-hoc ou até mesmo sem autenticação. A especificação de 25-11-2025 resolve essa lacuna com um perfil OAuth 2.1 completo.

Três necessidades do mundo real:

  • Servidores remotos comuns. O usuário instala um servidor MCP remoto que acessa seu Notion / GitHub / Gmail. O OAuth 2.1 com PKCE é o formato adequado.
  • Escalação de escopo. Um servidor de notas que recebeu permissão notes:read pode posteriormente precisar de notes:write para uma ação específica. Em vez de refazer todo o fluxo, o step-up (SEP-835) solicita o escopo adicional.
  • Prevenção de deputado confuso. O cliente possui um token com escopo de audiência para o Servidor A. O Servidor A é malicioso e tenta apresentar o token ao Servidor B. Indicadores de recurso (RFC 8707) vinculam o token à sua audiência pretendida.

O OAuth 2.1 não é novo. O que é novo é o perfil do MCP: fluxos específicos obrigatórios (apenas código de autorização + PKCE; sem fluxo implícito ou credenciais de cliente por padrão), indicadores de recurso obrigatórios em cada solicitação de token e metadados de recurso protegido publicados para que os clientes saibam onde ir.

O Conceito

Papéis

  • Cliente. O cliente MCP (Claude Desktop, Cursor, etc.).
  • Servidor de recursos. O servidor MCP (notas, GitHub, Postgres, etc.).
  • Servidor de autorização. Emite tokens. Pode ser o mesmo serviço do servidor de recursos ou um IdP separado (Auth0, Keycloak, Cognito).

No perfil do MCP, os servidores de recursos e de autorização PODEM ser o mesmo host, mas DEVEM ser distinguidos por URLs.

Código de autorização + PKCE

O fluxo:

  1. O cliente gera code_verifier (aleatório) e code_challenge (SHA256).
  2. O cliente redireciona o usuário para /authorize?response_type=code&client_id=...&redirect_uri=...&scope=notes:read&code_challenge=...&resource=https://notes.example.com.
  3. O usuário consente. O servidor de autorização redireciona para redirect_uri?code=....
  4. O cliente faz um POST para /token?grant_type=authorization_code&code=...&code_verifier=...&resource=....
  5. O servidor de autorização valida o hash do verificado em relação ao desafio armazenado e emite um token de acesso.
  6. O cliente usa o token: Authorization: Bearer ... em cada requisição para o servidor de recursos.

O PKCE evita ataques de interceptação de código de autorização. Os indicadores de recurso impedem que o token seja válido em outros locais.

Metadados de recurso protegido (RFC 9728)

O servidor de recursos publica um documento em .well-known/oauth-protected-resource:

{
  "resource": "https://notes.example.com",
  "authorization_servers": ["https://auth.example.com"],
  "scopes_supported": ["notes:read", "notes:write", "notes:delete"]
}

O cliente descobre o servidor de autorização a partir do servidor de recursos. Reduz a configuração — o cliente precisa apenas da URL do recurso.

Indicadores de recurso (RFC 8707)

O parâmetro resource na solicitação de token vincula a audiência pretendida do token. O token emitido contém aud: "https://notes.example.com". Outro servidor MCP que receber este token verificará aud e o rejeitará.

Modelo de escopo

Escopos são strings separadas por espaço. Convenções comuns do MCP:

  • notes:read, notes:write, notes:delete
  • admin:* para capacidades administrativas (use com moderação)
  • profile:read para identidade

A seleção de escopo deve seguir o princípio do menor privilégio: solicite o que você precisa agora e faça o step-up quando precisar de mais.

Autorização step-up (SEP-835)

O usuário concede notes:read. Mais tarde, ele pede ao agente para excluir uma nota. O servidor responde:

HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope",
    scope="notes:delete", resource="https://notes.example.com"

O cliente vê o erro de insufficient_scope, exibe ao usuário uma caixa de diálogo de consentimento para o escopo adicional, realiza um mini fluxo OAuth para ele e tenta novamente a solicitação com o novo token.

Validação de audiência do token

A cada requisição: o servidor verifica se token.aud == self.resource_url. Divergência = 401. Isso impede o reuso de tokens entre servidores.

Tokens de curta duração e rotação

Tokens de acesso DEVEM ser de curta duração (padrão de 1 hora). Tokens de atualização (refresh tokens) rotacionam a cada atualização. O cliente lida com a atualização silenciosa em segundo plano.

Sem repasse de token

Servidores de amostragem (Fase 13 · 11) NÃO DEVEM passar o token do cliente para outros serviços. A solicitação de amostragem é o limite.

Prevenção de deputado confuso

O token se vincula a aud. O cliente se vincula a client_id. Cada solicitação é validada em relação a ambos. A especificação proíbe explicitamente o antigo padrão de "passagem de token" que era comum em ecossistemas de ferramentas remotas pré-MCP.

Descoberta de ID do cliente

Cada cliente MCP publica seus metadados em uma URL fixa. Os servidores de autorização podem buscar o documento de metadados do cliente para descobrir as URIs de redirecionamento e as informações de contato. Isso elimina o registro manual do cliente.

Gateways e OAuth

A Fase 13 · 17 mostra como um gateway corporativo lida com OAuth: o gateway mantém as credenciais dos servidores upstream, os tokens para o cliente são emitidos pelo gateway e os tokens upstream nunca saem do gateway. Isso inverte o modelo de confiança — os usuários se autenticam no gateway uma vez; o gateway lida com N autorizações de servidores.

Use-o

O arquivo code/main.py simula o fluxo completo de step-up do OAuth 2.1 como uma máquina de estados. Ele implementa:

  • Geração de code-verifier / challenge do PKCE.
  • Fluxo de código de autorização com indicador de recurso.
  • Endpoint de metadados de recurso protegido.
  • Validação de token com verificação de audiência.
  • Step-up em caso de insufficient_scope.

Não há servidor HTTP nesta lição; a máquina de estados roda em memória para que você possa rastrear cada etapa. A lição de gateway da Fase 13 · 17 conecta isso a um transporte real.

Envie

Esta lição produz outputs/skill-oauth-scope-planner.md. Dado um servidor MCP remoto com ferramentas, a skill projeta o conjunto de escopos, regras de vinculação e política de step-up.

Exercícios

  1. Execute code/main.py. Rastreie o fluxo de step-up de dois escopos. Observe quais etapas se repetem no step-up.

  2. Adicione rotação de token de atualização: cada atualização emite um novo token de atualização e invalida o antigo. Simule um token de atualização roubado sendo usado após a rotação e confirme que ele falha.

  3. Implemente o endpoint de metadados de recurso protegido como uma resposta HTTP real usando o http.server da biblioteca padrão. Espelhe o endpoint /mcp da Lição 09.

  4. Projete uma hierarquia de escopo para um servidor MCP do GitHub: ler repositório, gravar PR, aprovar PR, mesclar PR, administrador. Use step-up entre cada nível.

  5. Leia a RFC 8707 e a RFC 9728. Identifique o único campo na 9728 que o MCP usa de forma diferente do exemplo da RFC. (Dica: diz respeito a scopes_supported.)

Termos-chave

Termo O que as pessoas dizem O que isso realmente significa
OAuth 2.1 "OAuth moderno" RFC consolidada que exige PKCE e proíbe o fluxo implícito
PKCE "Prova de posse" Code verifier + challenge que evitam a interceptação do código de autorização
Indicador de recurso "Audiência do token" Parâmetro resource da RFC 8707 que vincula o token a um único servidor
Metadados de recurso protegido "Doc de descoberta" RFC 9728 .well-known/oauth-protected-resource
Autorização step-up "Consentimento incremental" Fluxo da SEP-835 para adicionar escopos sob demanda
insufficient_scope "403 com WWW-Authenticate" Sinal do servidor para obter novo consentimento para um escopo maior
Deputado confuso "Reuso de token entre serviços" Ataque onde um portador confiável encaminha um token de forma inadequada
Token de curta duração "TTL do token de acesso" Portador que expira rapidamente; o token de atualização o renova
Hierarquia de escopo "Pilha de menor privilégio" Conjunto de escopos graduais com step-up entre os níveis
Metadados do ID do cliente "Doc de descoberta do cliente" URL na qual o cliente publica seus próprios metadados OAuth

Leitura Adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).