AI Engineering Academy · Aula

Segurança e autenticação no MCP

Adicione autenticação ao seu servidor MCP usando tokens OAuth 2.0, implemente validação de entrada para impedir ataques de injeção e aplique o princípio do menor privilégio às permissões das ferramentas.

Aula 4 de 413 etapas

Segurança e autenticação no MCP é uma aula grátis de AI Engineering Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Engineering Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Engineering Academy inclui 4 aulas no total.

Por que a segurança do MCP é importante

Um servidor MCP é uma porta de entrada para os seus sistemas. Sem a segurança adequada, um cliente de IA comprometido ou um prompt malicioso poderia ler dados confidenciais, acionar operações destrutivas ou exfiltrar informações pelo canal de chamadas de ferramentas. A segurança dos servidores MCP deve seguir uma abordagem de defesa em profundidade: autenticação na camada de transporte, autorização no nível das ferramentas e validação de entradas em todas as chamadas.

Segurança de servidores locais versus remotos

O transporte stdio, usado pelo Claude Desktop, tem segurança inerente: o servidor é executado como um processo local, acessível somente ao usuário que o iniciou. Servidores MCP expostos na rede usando HTTP/SSE enfrentam toda a variedade de ameaças de segurança da Web: contorno de autenticação, ataques de injeção e acesso não autorizado. Os requisitos de segurança diferem drasticamente conforme o modo de implantação.

  • stdio local: confie no usuário local; concentre-se na validação de entradas
  • HTTP/SSE remoto: autenticação completa, TLS, limitação de taxa e higienização de entradas

Autenticação por chave de API para servidores remotos

A forma mais simples de autenticação para servidores MCP remotos é validar uma chave de API por meio de um cabeçalho HTTP. Verifique o cabeçalho Authorization: Bearer <token> em todas as solicitações recebidas e rejeite solicitações não autenticadas com HTTP 401. Armazene as chaves de API válidas em um banco de dados com metadados do usuário para poder revogar chaves individuais.

# For HTTP/SSE MCP servers using FastAPI or similar:
from fastapi import FastAPI, HTTPException, Depends, Header
from typing import Optional
import secrets

app_http = FastAPI()

# In production: store in database with user_id, created_at, last_used
VALID_KEYS = {'sk-mcp-abc123': {'user': 'alice', 'scopes': ['read']},
              'sk-mcp-def456': {'user': 'bob', 'scopes': ['read', 'write']}}

async def verify_api_key(authorization: Optional[str] = Header(None)) -> dict:
    if not authorization or not authorization.startswith('Bearer '):
        raise HTTPException(status_code=401, detail='Missing API key')
    key = authorization.removeprefix('Bearer ')
    if key not in VALID_KEYS:
        raise HTTPException(status_code=401, detail='Invalid API key')
    return VALID_KEYS[key]  # Returns user context

# Use in route handlers:
# @app_http.get('/sse')
# async def sse_endpoint(user=Depends(verify_api_key)):

OAuth 2.0 para servidores MCP empresariais

Para implantações empresariais, use OAuth 2.0 para que os usuários se autentiquem com o provedor de identidade corporativa, como Okta, Azure AD ou Google Workspace. O cliente MCP obtém um token de acesso OAuth, que inclui nas solicitações de chamadas de ferramentas. Seu servidor valida a assinatura do token usando as chaves públicas do provedor de identidade, com python-jose ou authlib.

from jose import jwt, JWTError
import httpx

AUTH_DOMAIN = 'your-tenant.auth0.com'
AUDIENCE = 'https://api.your-mcp-server.com'

async def get_jwks():
    async with httpx.AsyncClient() as client:
        resp = await client.get(f'https://{AUTH_DOMAIN}/.well-known/jwks.json')
        return resp.json()

async def verify_oauth_token(token: str) -> dict:
    jwks = await get_jwks()
    try:
        payload = jwt.decode(
            token,
            jwks,
            algorithms=['RS256'],
            audience=AUDIENCE,
            issuer=f'https://{AUTH_DOMAIN}/'
        )
        return payload  # Contains sub (user ID), scope, exp, etc.
    except JWTError as e:
        raise ValueError(f'Invalid token: {e}')

Autorização baseada em escopos

Nem todas as ferramentas MCP devem estar disponíveis para todos os usuários. Use escopos OAuth ou declarações de função no token JWT para determinar quais ferramentas o usuário autenticado pode chamar. Verifique a autorização no início de cada execução de ferramenta, antes de qualquer chamada ao banco de dados ou à API.

TOOL_REQUIRED_SCOPES = {
    'list_products': ['read:products'],
    'search_products': ['read:products'],
    'create_order': ['write:orders'],
    'delete_order': ['admin:orders']
}

def check_authorization(tool_name: str, token_payload: dict):
    '''Raise ValueError if user lacks required scope for the tool.'''
    required = TOOL_REQUIRED_SCOPES.get(tool_name, [])
    if not required:
        return  # No scope required

    user_scopes = set(token_payload.get('scope', '').split())
    missing = [s for s in required if s not in user_scopes]
    if missing:
        raise ValueError(
            f'Access denied. Tool "{tool_name}" requires scopes: {missing}. '
            f'Your token has: {list(user_scopes)}'
        )

# In call_tool handler:
# check_authorization(name, current_user_token)
# ... then execute the tool

Validação de entradas e prevenção de injeções

Todas as entradas das ferramentas são, em última análise, strings geradas por um LLM — trate-as como não confiáveis. Valide cada entrada em relação aos tipos e padrões esperados antes de usá-la. Em particular, proteja-se contra: injeção de SQL, usando consultas parametrizadas e nunca SQL interpolado em strings; injeção de comandos, nunca passando entradas do usuário para comandos do shell; e travessia de diretórios, normalizando e validando caminhos de arquivos.

import re
from pathlib import Path

BASE_DATA_DIR = Path('/data/mcp-files')

def safe_file_path(user_input: str) -> Path:
    '''Validate and normalize a file path to prevent traversal attacks.'''
    # Remove any path traversal sequences
    clean = re.sub(r'\.\./', '', user_input)
    clean = re.sub(r'\.\.\\\\', '', clean)
    path = (BASE_DATA_DIR / clean).resolve()

    # Ensure the resolved path is still within the allowed base directory
    if not str(path).startswith(str(BASE_DATA_DIR)):
        raise ValueError(f'Path traversal detected: {user_input}')

    return path

def safe_identifier(value: str) -> str:
    '''Validate a database identifier (table/column name).'''
    if not re.match(r'^[a-z_][a-z0-9_]{0,63}$', value, re.IGNORECASE):
        raise ValueError(f'Invalid identifier: {value}')
    return value

Limitando a taxa de chamadas de ferramentas

Um agente LLM em um loop poderia chamar ferramentas dispendiosas centenas de vezes por minuto, esgotando as conexões do banco de dados, as cotas de APIs de terceiros ou o orçamento computacional. Implemente limites de taxa por usuário usando um algoritmo de balde de tokens no Redis. Rejeite chamadas de ferramentas que excedam o limite com um erro descritivo, para que o agente saiba que deve aguardar.

import redis
import time

r = redis.Redis.from_url('redis://localhost:6379')

def check_rate_limit(user_id: str, tool_name: str, limit: int = 60, window: int = 60) -> None:
    '''Allow at most `limit` calls per `window` seconds per user per tool.'''
    key = f'rate:{user_id}:{tool_name}'
    pipe = r.pipeline()
    pipe.incr(key)
    pipe.expire(key, window)
    count, _ = pipe.execute()

    if count > limit:
        retry_after = r.ttl(key)
        raise ValueError(
            f'Rate limit exceeded for {tool_name}. '
            f'Limit: {limit} calls/{window}s. '
            f'Retry after {retry_after} seconds.'
        )

Princípio do menor privilégio

Aplique o princípio do menor privilégio em todas as camadas do seu servidor MCP. O usuário do banco de dados deve ter permissão somente de SELECT nas tabelas necessárias ao servidor. O processo do servidor deve ser executado como um usuário do OS que não seja root. As ferramentas devem solicitar apenas as permissões de que precisam. As chaves de API devem ter o escopo mínimo necessário para sua finalidade. Cada permissão que você negar representa um possível ataque que não poderá ser bem-sucedido.

-- PostgreSQL: Create a dedicated read-only database user for your MCP server
CREATE ROLE mcp_reader LOGIN PASSWORD 'strong_random_password';

-- Grant SELECT on only the tables the server needs
GRANT SELECT ON products, categories, public_content TO mcp_reader;

-- Explicitly deny access to sensitive tables
REVOKE ALL ON users, api_keys, payment_methods FROM mcp_reader;

-- Never grant: INSERT, UPDATE, DELETE, TRUNCATE, or DDL permissions

TLS e segurança do transporte

Os servidores MCP remotos devem usar TLS para proteger os dados em trânsito. Configure seu servidor para aceitar somente conexões HTTPS. Em produção, use um proxy reverso, como nginx ou Caddy, para gerenciar a terminação do TLS e manter os certificados atualizados com renovação automática, usando o Let's Encrypt via Certbot ou o suporte ACME integrado do Caddy.

# Example Caddyfile for TLS-terminating MCP server at a subdomain:
#
# mcp.yourcompany.com {
#     reverse_proxy localhost:8080
#     encode gzip
#     tls internal  # Use Let's Encrypt in production
#     header {
#         Strict-Transport-Security 'max-age=31536000; includeSubDomains'
#         X-Content-Type-Options nosniff
#         X-Frame-Options DENY
#     }
# }

Injeção de prompts por meio de recursos MCP

Um vetor de ataque sutil: se o seu servidor MCP ler conteúdo de fontes externas, como páginas da Web, arquivos enviados por usuários ou bancos de dados não confiáveis, e retorná-lo como resultado de uma ferramenta, um invasor poderá inserir instruções maliciosas nesse conteúdo. O modelo poderá obedecer a instruções ocultas nos dados recuperados — isso é uma injeção indireta de prompt. Higienize o conteúdo recuperado e nunca retorne texto bruto não confiável diretamente como saída de uma ferramenta.

import re

def sanitize_for_mcp_output(text: str) -> str:
    '''Remove patterns that look like instructions to the LLM.'''
    # Remove common injection patterns
    dangerous_patterns = [
        r'ignore previous instructions',
        r'ignore all prior instructions',
        r'system:',
        r'<\|.*?\|>',  # Special tokens
        r'\[INST\]',
        r'<s>',
    ]
    for pattern in dangerous_patterns:
        text = re.sub(pattern, '[FILTERED]', text, flags=re.IGNORECASE)
    return text[:10000]  # Also cap length to prevent context stuffing

Auditoria e monitoramento de segurança

Registre todos os eventos relevantes para a segurança: êxitos e falhas de autenticação, violações do limite de requisições, recusas de autorização, erros de validação e padrões de acesso incomuns. Configure alertas para: várias tentativas de autenticação malsucedidas (força bruta), um único usuário chamando ferramentas destrutivas rapidamente e qualquer chamada de ferramenta com entradas extremamente grandes. Revise os registros de auditoria regularmente e automatize a detecção de anomalias.

Verificação rápida

Teste sua compreensão dos conceitos de segurança e autenticação do MCP.

Recapitulação da lição

Nesta lição, você aprendeu que: os servidores MCP remotos exigem autenticação OAuth 2.0 ou por chave de API em todas as requisições, a autorização baseada em escopos controla quais ferramentas cada usuário autenticado pode chamar e todas as entradas das ferramentas devem ser validadas para evitar ataques de injeção e travessia de caminhos. Isso conclui o módulo sobre MCP — a seguir, exploraremos estratégias avançadas de segmentação para recuperação RAG de alta precisão.

Grátis para começar

Aprenda Python com um tutor de IA — grátis

Escreva e execute código real no seu navegador, obtenha ajuda instantânea de um tutor de IA 24/7 e continue de onde parou na web ou no app.

Cursos
30
Aulas
120

Perguntas Frequentes

A aula “Segurança e autenticação no MCP” é grátis?

Sim — o texto completo de “Segurança e autenticação no MCP” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Engineering Academy, atualize para CoddyKit PRO. O curso de AI Engineering Academy inclui 4 aulas no total.

O que vou aprender em “Segurança e autenticação no MCP”?

Adicione autenticação ao seu servidor MCP usando tokens OAuth 2.0, implemente validação de entrada para impedir ataques de injeção e aplique o princípio do menor privilégio às permissões das ferramen… Você pratica AI Engineering Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar AI Engineering Academy?

Nenhuma experiência prévia é necessária. AI Engineering Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Segurança e autenticação no MCP”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de AI Engineering Academy?

Sim. Cada aula de AI Engineering Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. O que é MCP e por que ele importa
  2. Criando seu primeiro servidor MCP
  3. Disponibilizando recursos de banco de dados via MCP
  4. Segurança e autenticação no MCP
← Voltar para AI Engineering Academy