Voltar para o blog

Checklist prático de segurança para servidores MCP: exposição, autenticação e limites de confiança

Um servidor que permite consultar incidentes pode também alcançar documentos internos, credenciais e APIs administrativas. Quando essa integração utiliza Model Context Protocol (MCP), proteger apenas a conexão não resolve o problema: é necessário controlar quais operações cada identidade pode executar e quais dados podem atravessar cada fronteira. O protocolo conecta aplicações a ferramentas e contexto; não substitui a política de segurança dos sistemas integrados. (modelcontextprotocol.io)

Este guia propõe um checklist de implantação e operação para equipes de plataforma. O cenário é ilustrativo, não um relato de implantação real. A referência de protocolo é a revisão 2026-07-28, disponível na documentação oficial consultada para esta publicação. Clientes anteriores exigem uma matriz explícita de compatibilidade; não aplique pressupostos de sessão de 2025 indiscriminadamente às implementações de 2026. (modelcontextprotocol.io)

1. Entenda os componentes antes de definir permissões

O host é a aplicação que coordena a interação e as decisões de consentimento. Um cliente MCP comunica-se com um servidor. O servidor MCP oferece ferramentas, recursos e prompts. Uma ferramenta executa uma operação; um recurso fornece contexto; um prompt oferece uma estrutura reutilizável de interação. Esses componentes devem receber somente o contexto necessário. (modelcontextprotocol.io)

Há duas modalidades importantes:

  • stdio: o cliente inicia um subprocesso e troca mensagens pela entrada e saída padrão. Não exige uma porta TCP do servidor, mas envolve execução de código local. Logs devem ir para stderr, não contaminar stdout com texto fora do protocolo. (modelcontextprotocol.io)
  • Streamable HTTP: permite implantação remota. Na revisão 2026-07-28, cada mensagem usa POST; respostas podem ser JSON ou Server-Sent Events (SSE). Essa revisão removeu sessões de protocolo e o stream independente via GET. (modelcontextprotocol.io)

Autenticação verifica a identidade; autorização decide se uma operação é permitida. Um token válido não concede acesso irrestrito. A decisão precisa considerar ferramenta, recurso, tenant — organização ou domínio de isolamento — e contexto da solicitação. (cheatsheetseries.owasp.org)

2. Desenhe os limites de confiança

Para o cenário deste artigo, adote a seguinte arquitetura:

Usuário → Host/cliente MCP → Gateway privado → Servidor MCP
                                      ↓              ↓
                            Provedor de identidade   Política por operação
                                                     ↓
                                            Proxy de saída controlado
                                                     ↓
                                           APIs e dados autorizados

Esta é uma proposta de arquitetura, não uma topologia obrigatória do MCP. Distribua responsabilidades explicitamente:

FronteiraControle propostoEvidência exigida
Cliente → gatewayTLS, autenticação e limites de entradaRequisição sem credencial é negada
Gateway → servidorIdentidade verificável e ausência de bypassAcesso direto não contorna controles
Servidor → ferramentaAutorização por ação e objetoTenant A não acessa objetos do tenant B
Servidor → dependênciaCredencial específica e saída restritaDestino não aprovado é bloqueado
Resultado → hostTratamento como dado não confiávelTexto retornado não amplia permissões

Recomendo manter a autorização de negócio no servidor mesmo quando o gateway valida tokens. Se houver propagação de identidade por cabeçalhos internos, remova valores recebidos do cliente e autentique o emissor interno. Não transforme um simples X-User em prova de identidade. A localização e a consistência das verificações são parte essencial do controle de acesso. (cheatsheetseries.owasp.org)

3. Checklist de exposição

Servidores locais

  • [ ] Preferir stdio quando não houver necessidade de acesso remoto.
  • [ ] Revisar pacote, versão, comando completo e argumentos antes da instalação.
  • [ ] Usar sandbox e restringir diretórios, rede e credenciais disponíveis ao processo.
  • [ ] Em HTTP local, fazer bind em loopback, incluindo a revisão de IPv6.
  • [ ] Validar Origin; uma origem presente e inválida deve receber HTTP 403.

Esses controles reduzem riscos de execução local e DNS rebinding, em que a resolução de nomes é manipulada para atingir serviços internos. Loopback não torna um processo automaticamente confiável. (modelcontextprotocol.io)

Servidores remotos

Minha política recomendada para o cenário corporativo é:

  • [ ] Endpoint privado por padrão; publicação na internet somente com justificativa e responsável.
  • [ ] Transport Layer Security (TLS) na entrada e proteção explícita do trecho interno.
  • [ ] Nenhum endpoint administrativo ou de diagnóstico publicado junto com o MCP.
  • [ ] Lista explícita de hosts e origens aceitos.
  • [ ] Bloqueio de caminhos alternativos via NodePort, outro LoadBalancer ou acesso direto ao backend.
  • [ ] Inventário de portas, domínios, certificados, responsáveis e consumidores.

Aplique essa política também a ambientes temporários. As recomendações de segurança do Kubernetes incluem restrição de exposição e segmentação; uma rede interna não elimina a necessidade de controles de aplicação. (kubernetes.io)

Cross-Origin Resource Sharing (CORS) não deve ser usado como identidade do consumidor. Clientes fora do navegador não dependem dessa política. Trate ausência de Origin conforme o transporte e os consumidores suportados, mantendo autenticação independente. (modelcontextprotocol.io)

4. Checklist de autenticação e autorização

Para HTTP protegido, o MCP define integração OAuth: o servidor MCP atua como servidor de recursos; o servidor de autorização emite access tokens. A especificação torna autorização opcional em termos gerais, mas a política proposta aqui a exige para dados corporativos e operações privilegiadas. Envie a credencial em cada requisição, nunca na query string. (modelcontextprotocol.io)

Descoberta e emissão

  • [ ] Publicar Protected Resource Metadata e testar descoberta pelo cliente.
  • [ ] Usar servidor de autorização aprovado, sem confiar automaticamente em URLs recebidas.
  • [ ] Para authorization code, exigir Proof Key for Code Exchange (PKCE), verificar suporte e usar S256 quando tecnicamente possível.
  • [ ] Validar redirects e correlacionar a resposta ao fluxo iniciado.
  • [ ] Solicitar tokens destinados ao recurso MCP correto.

Descoberta e proteção do fluxo precisam funcionar em conjunto; configurar apenas uma tela de login não estabelece interoperabilidade segura. (modelcontextprotocol.io)

Validação no servidor

  • [ ] Rejeitar tokens expirados, inválidos ou destinados a outro recurso.
  • [ ] Separar falha de autenticação, normalmente 401, de permissão insuficiente, normalmente 403.
  • [ ] Não aceitar um ID token como substituto automático de access token.
  • [ ] Não encaminhar o token recebido indiscriminadamente à API de destino.

O token usado pelo MCP para acessar outra API deve ser específico daquela integração. Token passthrough viola a separação de audiência e é proibido pela especificação. (modelcontextprotocol.io)

Se o access token for um JSON Web Token (JWT), use biblioteca validada para verificar assinatura, emissor, audiência e validade, com algoritmos permitidos explicitamente. Decodificar o payload não equivale a validar o token. A estratégia para tokens opacos deve seguir o contrato do provedor, sem presumir que todo access token é JWT. (rfc-editor.org)

Permissões de negócio

Para este projeto, proponho escopos como incidents:read e incidents:write; são nomes da aplicação, não escopos padronizados do MCP. Uma chamada deve passar por esta decisão:

Identidade verificada
  → tenant autorizado
  → ferramenta permitida
  → objeto permitido
  → argumentos válidos
  → execução limitada

Não confie no tenant_id enviado pelo modelo como autoridade. Derive o contexto de identidade verificada e valide a associação ao objeto. Ocultar uma ferramenta de tools/list não substitui verificar tools/call. As anotações de ferramenta, inclusive indicações de somente leitura, não são controles de autorização. (cheatsheetseries.owasp.org)

5. Checklist de confiança: conteúdo não é autoridade

Prompt injection ocorre quando instruções maliciosas aparecem em conteúdo processado pela aplicação, inclusive documentos e resultados de ferramentas. Um resultado dizendo para enviar credenciais ou desativar controles não deve alterar a política do host. Separe instruções confiáveis de dados externos e mantenha decisões críticas fora do texto gerado pelo modelo. (cheatsheetseries.owasp.org)

Para este cenário, estabeleça os seguintes critérios:

  • [ ] Catálogo aprovado de servidores e ferramentas, com revisão de alterações.
  • [ ] Aprovação humana para operações destrutivas, mostrando alvo e argumentos efetivos.
  • [ ] Aprovação vinculada à operação específica, sem autorizar ações futuras genericamente.
  • [ ] Ferramentas especializadas em vez de shell arbitrário ou SQL irrestrito.
  • [ ] Validação de entrada e saída, com limites de tamanho e tipos.
  • [ ] Nenhum segredo retornado ao modelo quando puder permanecer no backend.

Esses controles complementam, mas não tornam infalível, a defesa contra prompt injection. A especificação também recomenda supervisão humana e validação de ferramentas. (cheatsheetseries.owasp.org)

SSRF e saída de rede

Server-Side Request Forgery (SSRF) permite induzir o serviço a acessar destinos indevidos. Proteja ferramentas que recebem URLs e componentes que buscam metadados OAuth. Valide esquema, destino, resolução DNS e redirecionamentos; bloqueie metadata de nuvem, loopback e redes não autorizadas. Serviços privados necessários devem ser exceções específicas, não uma liberação de toda a rede interna. (cheatsheetseries.owasp.org)

Estado e isolamento

Na revisão usada aqui, estado de negócio pode existir mesmo sem sessões de protocolo. Um identificador de workflow não autentica seu portador: vincule-o à identidade e ao tenant. Para clientes legados que utilizam sessões, aplique os controles da revisão correspondente. (modelcontextprotocol.io)

6. Exemplo cotidiano: consultar incidentes sem abrir um console administrativo

Problema: uma equipe deseja pesquisar incidentes e consultar runbooks. O protótipo possui um token compartilhado com acesso de escrita e uma ferramenta genérica para executar requisições HTTP.

Solução proposta: separar consulta de mutação. Oferecer ferramentas específicas, como search_incidents e get_runbook, com autorização por projeto. Esses nomes são exemplos de ferramentas da aplicação.

Implementação planejada: endpoint privado, OAuth por usuário, API de incidentes com credencial própria, proxy de saída restritivo e catálogo versionado. A futura ferramenta de encerramento de incidentes exigirá escopo adicional e aprovação vinculada ao incidente.

Resultado esperado: o comprometimento de um cliente de consulta não deve conceder capacidade de alterar incidentes ou acessar outros projetos. Essa é uma hipótese verificável por testes de autorização, não uma métrica de redução de risco já observada.

7. Kubernetes: exemplo completo de isolamento de rede

O manifesto abaixo é um exemplo didático aplicável a workloads existentes, não uma implantação completa do servidor. Ele pressupõe:

  • namespace mcp existente;
  • Pods do servidor com app: mcp-server;
  • gateway no namespace mcp-gateway, com app: mcp-gateway;
  • proxy de saída no namespace egress-system, com app: egress-proxy;
  • DNS do cluster identificado por k8s-app: kube-dns;
  • plugin Container Network Interface (CNI) com suporte efetivo a NetworkPolicy.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: mcp-restricted-network
  namespace: mcp
spec:
  podSelector:
    matchLabels:
      app: mcp-server
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: mcp-gateway
          podSelector:
            matchLabels:
              app: mcp-gateway
      ports:
        - protocol: TCP
          port: 8080
  egress:
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: kube-system
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
    - to:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: egress-system
          podSelector:
            matchLabels:
              app: egress-proxy
      ports:
        - protocol: TCP
          port: 3128

A política isola os Pods selecionados nas duas direções. namespaceSelector e podSelector, dentro do mesmo item, restringem conjuntamente o peer. Somente o gateway indicado entra na porta 8080; a saída permite DNS e o proxy. Outras políticas permissivas podem ampliar esse acesso, pois NetworkPolicies são aditivas. Elas não configuram TLS nem filtram URLs. (kubernetes.io)

Adapte portas, labels e DNS, especialmente com NodeLocal DNSCache. Configure a aplicação para usar o proxy explicitamente; esta política não redireciona tráfego. O proxy deve aplicar a lista de destinos aprovada e validar resolução e redirects. Sem essas regras, permitir acesso ao proxy apenas desloca o problema. (kubernetes.io)

Antes de produção, teste também telemetria, descoberta OAuth, atualização de chaves e recuperação de credenciais: neste desenho, dependências HTTP externas precisam passar pelo proxy. Conexões não HTTP exigem regras específicas. Não libere 0.0.0.0/0 apenas para corrigir um timeout.

Identidade e endurecimento dos Pods

Adote ServiceAccount dedicada, sem montagem automática de token quando o servidor não usa a API Kubernetes. Evite permissões de administrador. Role-Based Access Control (RBAC), execução sem root, filesystem somente leitura, seccompProfile: RuntimeDefault, remoção de capabilities e bloqueio de escalada devem compor a política do workload. (kubernetes.io)

Restrinja leitura de Secrets e habilite criptografia em repouso. Não coloque credenciais em imagens, argumentos ou Git. Defina rotação e verifique se a aplicação recarrega a credencial; criar um novo Secret não garante que um processo já iniciado o utilizará. (kubernetes.io)

8. Limites de execução, capacidade e disponibilidade

Rate limiting por endereço IP não é suficiente para meu desenho multiusuário. Proponho quotas por identidade, tenant e ferramenta, além de limite global. Como ponto inicial hipotético para testes, não benchmark:

ControleValor inicial ilustrativo
Corpo da requisição256 KiB
Resultado de ferramenta1 MiB, com paginação
Concorrência por identidade4 operações
Prazo de consulta15 segundos
FilaLimitada, com rejeição explícita ao saturar

Ajuste esses valores com testes de carga e requisitos de negócio. Limite também consultas downstream, conexões e trabalho após cancelamento; não dependa apenas de um timeout no gateway. Limites por camada reduzem possibilidades de exaustão. (cheatsheetseries.owasp.org)

Para produção, proponho três réplicas distribuídas entre zonas disponíveis, com capacidade para perder uma réplica sem saturar as restantes. Configure requests a partir da carga observada e limites que protejam o cluster sem provocar throttling ou encerramentos desnecessários por memória. (kubernetes.io)

Use startupProbe para inicialização, readinessProbe para elegibilidade ao tráfego e livenessProbe para falhas locais recuperáveis por reinício. Não faça a liveness depender de todos os serviços externos. Um problema remoto não deve provocar reinícios em cascata. (kubernetes.io)

Um PodDisruptionBudget ajuda em interrupções voluntárias, mas não garante sobrevivência à perda de zona. Horizontal Pod Autoscaler (HPA) pode usar métricas de recursos ou métricas customizadas; para este cenário, avalie operações em execução e saturação de filas, não somente CPU. (kubernetes.io)

9. Testes de aceitação antes da publicação

Transforme o checklist em testes automatizados. Para a arquitetura proposta, exija:

TesteResultado esperado
Token ausente ou expiradoOperação protegida não executada
Token de outra audiênciaRejeição
Escopo somente leitura em mutaçãoRejeição
Objeto pertencente a outro tenantNenhum dado retornado
Origem inválida, com autenticação válidaHTTP 403
URL que redireciona para destino proibidoSaída bloqueada
Texto malicioso em runbookNenhuma ampliação de permissão
Saturação de concorrênciaRejeição controlada, sem fila ilimitada
Reinício durante operação de escritaReconciliação, sem repetição cega

São critérios propostos para este serviço. Execute testes de origem com credencial válida para não confundir bloqueio de autenticação com validação de Origin. Registre evidências de ausência de efeitos colaterais, não apenas o código HTTP.

Em clientes da revisão 2026-07-28, inclua testes de coerência entre metadados e corpo. Um gateway não deve autorizar uma ferramenta indicada no cabeçalho enquanto o backend executa outra indicada no JSON. (modelcontextprotocol.io)

10. Troubleshooting orientado a evidências

SintomaPossível causaInvestigaçãoCorreção
401 após loginToken expirado ou audiência incorretaVerificar decisão do validador sem registrar tokenCorrigir emissão, recurso e renovação
403 somente no navegadorOrigem recusada ou escopo insuficienteCorrelacionar gateway e aplicaçãoAjustar origem exata ou permissão necessária
Timeout após NetworkPolicyDNS, proxy ou dependência bloqueadaConferir labels, peers e fluxos negadosCriar a menor exceção necessária
Falhas após upgradeCliente e servidor de revisões diferentesVerificar versões e erros de protocoloCorrigir compatibilidade, sem desativar autenticação
Pods reiniciandoMemória insuficiente ou probe inadequadaExaminar estado anterior e eventosCorrigir consumo, limites ou probe

Essas hipóteses devem ser confirmadas nos logs e nas configurações; os comportamentos de autenticação, rede e probes estão documentados separadamente. (modelcontextprotocol.io)

Comandos de investigação para o workload assumido no exemplo:

kubectl get pods -n mcp -o wide
kubectl get deployments -n mcp
kubectl get networkpolicy -n mcp -o yaml
kubectl describe deployment mcp-server -n mcp
kubectl logs -n mcp deployment/mcp-server --all-containers=true --tail=200
kubectl get events -n mcp --sort-by=.metadata.creationTimestamp

Para investigar um reinício específico, substitua POD_NAME pelo nome observado:

kubectl describe pod POD_NAME -n mcp
kubectl logs POD_NAME -n mcp --previous

11. Observabilidade sem criar um repositório de segredos

Proponho um evento de auditoria com identidade pseudonimizada, tenant, ferramenta, decisão, duração, resultado, versão da política e identificador de correlação. Evite registrar argumentos completos por padrão. Tokens, cookies e conteúdo sensível precisam ser removidos antes de chegar ao armazenamento de telemetria. (opentelemetry.io)

Para este serviço, acompanhe:

  • latência, throughput e falhas por ferramenta;
  • negações por motivo, sem confundi-las automaticamente com indisponibilidade;
  • filas, concorrência, cancelamentos e dependências saturadas;
  • CPU, memória, reinícios e réplicas disponíveis;
  • falhas de atualização de chaves e de descoberta OAuth.

Defina um Service Level Objective (SLO) para consultas autorizadas concluídas dentro do prazo. Não use apenas sucesso HTTP: a ferramenta pode falhar semanticamente. Para custos de observabilidade, estabeleça retenção e amostragem distintas para auditoria e diagnóstico, com acesso restrito. Estas são escolhas operacionais propostas, a validar com os requisitos da equipe.

12. Desenvolvimento, produção e FinOps

AspectoDesenvolvimentoProdução proposta
ImplantaçãoLocal ou uma réplicaMúltiplas réplicas e zonas
DadosSintéticosClassificação e autorização por objeto
IdentidadeCredenciais de teste restritasIdentidade individual e rotação
ObservabilidadeDiagnóstico simplificadoAuditoria, SLO e alertas
MudançasExperimentação isoladaPipeline, revisão e rollback

Mesmo no desenvolvimento, não execute pacotes desconhecidos com credenciais de produção.

Para FinOps, inclua no orçamento réplicas ociosas, gateway, proxy de saída, tráfego entre zonas, armazenamento de auditoria e chamadas às APIs integradas. Minha recomendação é começar com capacidade mínima previsível, medir utilização e ajustar requests e autoscaling. Spot pode ser avaliado para capacidade adicional tolerante a interrupções, não como única sustentação de um serviço crítico. Não há preços ou economias presumidos neste exemplo.

13. Upgrades, rollback e resposta a incidentes

Versione imagem, dependências, catálogo de ferramentas e políticas. Execute canário com a matriz de clientes suportados. Rollback de Deployment reverte o template de Pods, não restaura automaticamente Secrets, políticas externas ou alterações no banco. Versione essas mudanças separadamente. (kubernetes.io)

No runbook proposto, uma suspeita de comprometimento deve permitir bloquear a ferramenta, interromper sua saída de rede, revogar credenciais e preservar auditoria. Mantenha backup dos dados de negócio e consentimentos persistentes, com teste de restauração. Não restaure credenciais já revogadas como parte da recuperação.

14. Quando utilizar e quando simplificar

Adote a arquitetura remota governada quando houver múltiplos consumidores, dados sensíveis, segregação entre tenants e necessidade de auditoria. Para uma ferramenta local de escopo pequeno, prefira avaliar stdio com sandbox antes de construir gateway, cluster e proxy dedicados. Para automação determinística entre dois serviços, uma API convencional pode ser suficiente.

Esses são critérios de decisão, não uma recomendação universal. Um gateway central favorece padronização, mas concentra dependências operacionais; políticas nos serviços preservam contexto de negócio, mas exigem disciplina de implementação. Kubernetes faz sentido quando a equipe já consegue operar isolamento, observabilidade e atualizações com segurança.

Resumo prático

Antes de aprovar o serviço, peça evidências de cinco propriedades:

  1. Somente consumidores previstos conseguem alcançá-lo.
  2. Credenciais são validadas para o recurso correto.
  3. Cada operação respeita identidade, tenant e objeto.
  4. Conteúdo externo não altera permissões nem destinos autorizados.
  5. Falhas podem ser detectadas, contidas e recuperadas sem execução duplicada ou exposição de segredos.

Conclusão

A proposta deste checklist é transformar segurança MCP em contrato operacional: responsáveis definidos, fronteiras explícitas, testes negativos e evidências reproduzíveis. Em DevOps e Platform Engineering, isso pode se tornar um caminho padronizado de implantação. Em SRE, os mesmos controles devem ser exercitados em falhas e mudanças, não apenas na revisão inicial.

O critério de aprovação não deve ser apenas conseguir conectar um cliente. Deve ser demonstrar o que o servidor não consegue fazer, mesmo diante de credenciais inadequadas, conteúdo malicioso ou dependências indisponíveis.

Quer aplicar isso no seu ambiente?

Agende uma conversa de 30 minutos sem compromisso. Eu olho o seu cenário e digo por onde começar.

Agendar uma conversa

Receba os novos artigos por e-mail

Um e-mail quando sair artigo novo sobre infraestrutura, backend e IA. Sem spam, cancele quando quiser.