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:readpode posteriormente precisar denotes:writepara 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:
- O cliente gera
code_verifier(aleatório) ecode_challenge(SHA256). - 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. - O usuário consente. O servidor de autorização redireciona para
redirect_uri?code=.... - O cliente faz um POST para
/token?grant_type=authorization_code&code=...&code_verifier=...&resource=.... - O servidor de autorização valida o hash do verificado em relação ao desafio armazenado e emite um token de acesso.
- 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:deleteadmin:*para capacidades administrativas (use com moderação)profile:readpara 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
Execute
code/main.py. Rastreie o fluxo de step-up de dois escopos. Observe quais etapas se repetem no step-up.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.
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.
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.
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
- MCP — Authorization spec — perfil canônico do OAuth no MCP
- den.dev — MCP November authorization spec — passo a passo das mudanças de 25-11-2025
- RFC 8707 — Resource indicators for OAuth 2.0 — a RFC de vinculação de audiência
- RFC 9728 — OAuth 2.0 protected resource metadata — a RFC do documento de descoberta
- Aembit — MCP OAuth 2.1, PKCE and the future of AI authorization — passo a passo prático do fluxo de step-up