MCP Audit Gateway
Gateway MCP que adiciona RBAC por ferramenta, isolamento de tenant, exportação de auditoria e redação de PII a qualquer servidor.
Documentação
MCP Audit Gateway
Gateway MCP que adiciona RBAC por ferramenta e um registro de auditoria exportável a qualquer servidor MCP, além de isolamento por tenant, redação de PII em resultados de ferramentas, limites de taxa por tenant e políticas de permitir/negar em nível de tenant. Ele fica entre um cliente MCP (Claude Desktop, um runtime de agente, seu próprio aplicativo) e um ou mais servidores MCP upstream. O caso concreto para o qual foi construído: colocar RBAC por ferramenta e um registro de auditoria exportável na frente de um servidor MCP do QuickBooks ou HubSpot, para que cada tools/call contra os livros passe por um ponto de estrangulamento aplicável, registrado e redigido.
Relacionados: QuickBooks Online MCP Server · HubSpot CRM MCP Server · O que o MCP de produção realmente exige
Aponte-o para qualquer servidor MCP, descreva seus tenants e papéis em YAML, e a política é um único arquivo que você pode ler em uma revisão. Assinatura de solicitação HMAC e transportes stdio e HTTP streamable estão incluídos. MIT, sem camada paga.
Por que isso existe
Um servidor MCP puro expõe todas as ferramentas a qualquer chamador, sem identidade, sem cota, sem registro e sem redação. Isso é aceitável em um laptop, mas não é viável em um produto multi-tenant. Este gateway adiciona esse plano de controle sem tocar no servidor upstream. O artigo complementar, docs/what-production-mcp-actually-requires.md, percorre cada recurso com uma história concreta de falha.
Ferramentas
O gateway não expõe ferramentas próprias. Ele faz proxy de tools/list e tools/call para os servidores MCP upstream configurados para o tenant chamador, colocando cada ferramenta com proxy em um namespace como <upstream>.<tool> e aplicando filtragem RBAC, limitação de taxa e redação de PII no caminho. Iniciado sem upstreams configurados, initialize e tools/list ainda são bem-sucedidos e a lista de ferramentas retorna vazia.
Sua própria superfície é o plano de controle da CLI:
validate: verifica um arquivo de política (papéis, principais, tenants, upstreams, detectores) antes de servir qualquer tráfego.serve --transport stdio: executa o gateway via stdio para um cliente MCP local, como o Claude Desktop.serve --transport http: executa o gateway via HTTP streamable para clientes remotos ou agentes.audit export --format csv: exporta o registro de auditoria como CSV para uma planilha ou ingestão em SIEM.audit export --format json: exporta os mesmos registros como JSON.
Prova: a demonstração com dois tenants
A evidência aqui é uma demonstração que você mesmo executa, não um site em que peço para confiar. demo/run_demo.py coloca o gateway na frente de dois tenants, acme (um subprocesso upstream stdio) e globex (um upstream HTTP streamable), e executa doze cenários que exercitam RBAC, kill-switches de tenant, redação de PII, isolamento entre tenants, assinatura HMAC, rejeição de ferramenta desconhecida e limitação de taxa por tenant contra o servidor MCP de brinquedo incluído. Não há instância hospedada para manter viva nem serviço externo para alcançar; tudo roda em loopback e termina em segundos.
A saída confirmada é o artefato:
- docs/demo-transcript.md: cada etapa, a decisão do gateway e o resultado que o cliente realmente viu, seguidos por uma tabela resumo dos resultados de auditoria.
- docs/demo-audit.csv: a trilha de auditoria completa legível por máquina que a mesma execução produziu.
Ambos os arquivos são regenerados literalmente por python demo/run_demo.py, para que a transcrição e sua tabela de auditoria sempre reconciliem com uma execução que você pode reproduzir localmente.
Arquitetura
flowchart LR
subgraph Clients
C1[Tenant A client]
C2[Tenant B client]
end
subgraph Gateway [mcp-audit-gateway]
direction TB
AUTH[Authenticate principal] --> SIG[Verify HMAC signature]
SIG --> RBAC[RBAC and allow/deny policy]
RBAC --> RL[Per-tenant rate limit]
RL --> ROUTE[Resolve tenant upstream]
ROUTE --> RED[PII redaction on result]
RED --> AUD[(Audit log JSONL)]
end
subgraph Upstreams
U1[Tenant A MCP server<br/>stdio]
U2[Tenant B MCP server<br/>streamable HTTP]
end
C1 -->|signed JSON-RPC| AUTH
C2 -->|signed JSON-RPC| AUTH
ROUTE --> U1
ROUTE --> U2
U1 --> RED
U2 --> RED
RED -->|redacted result| C1
Cada solicitação é autenticada para um principal, que a vincula a exatamente um tenant e papel. Um tenant só pode alcançar seus próprios upstreams, credenciais e estado. O pipeline faz curto-circuito no primeiro portão que falha e registra a decisão.
Recursos
| Recurso | O que faz |
|---|---|
| RBAC por ferramenta | Listas de permitir/negar de papel para ferramenta com padrões glob; negar sempre vence. |
| Isolamento por tenant | Cada tenant recebe seus próprios processos/endpoints upstream, credenciais, catálogo de ferramentas, balde de limite de taxa e estado. Nomes de ferramentas entre tenants são invisíveis. |
| Registro de auditoria | JSONL somente de anexação de quem chamou qual ferramenta, com quais argumentos (redigidos), status do resultado, latência e contagens de redação. Exportável para CSV e JSON. |
| Redação de PII | Detectores configuráveis (email, telefone, SSN, SIN canadense, cartão de crédito) aplicados aos resultados das ferramentas antes de saírem do gateway. Modos mask, hash ou partial. |
| Limitação de taxa | Balde de tokens por tenant (requests_per_minute + burst). |
| Políticas de permitir/negar | Kill-switch de ferramenta em nível de tenant que substitui papéis: uma camada de governança acima do RBAC. |
| Assinatura de solicitação | HMAC-SHA256 sobre o corpo da solicitação com uma janela de frescor de timestamp para impedir replay. |
| Transportes | stdio e HTTP streamable nos lados voltados para o cliente e para o upstream. |
Início rápido
uv venv --python 3.12
uv pip install -e ".[dev]"
# Validate the bundled two-tenant demo config
python -m mcp_gateway validate --config config/demo.yaml
# Run the full scripted demo (starts a stdio upstream and an HTTP upstream,
# proves tenant isolation, and writes docs/demo-transcript.md)
python demo/run_demo.py
Instalado como pacote, os mesmos comandos são executados pelo script de console mcp-audit-gateway.
Executando sem configuração
O gateway inicia sem nenhum arquivo de configuração, que é o que um cliente MCP ou um rastreador de registro vê em uma primeira sondagem tools/list:
mcp-audit-gateway serve --transport stdio
Isso atende a um principal local contra zero upstreams: initialize e tools/list são bem-sucedidos, a lista de ferramentas está vazia, nada é gravado em disco. Aponte-o para um arquivo de política para torná-lo útil, seja com --config ou definindo MCP_AUDIT_GATEWAY_CONFIG.
Executando o gateway
# Streamable HTTP, for remote/agent clients (reads host/port from the config)
python -m mcp_gateway serve --config config/demo.yaml --transport http
# stdio, for a local client such as Claude Desktop (pins the session to a principal)
python -m mcp_gateway serve --config config/demo.yaml --transport stdio --principal acme-admin
--principal é necessário apenas quando a configuração define mais de um; com um único principal, a sessão stdio o utiliza.
O tenant globex da demonstração faz proxy de um upstream HTTP esperado em http://127.0.0.1:9100/mcp. Para servir o gateway contra demo.yaml diretamente, inicie esse upstream primeiro:
python -m mcp_gateway.toy_upstream --transport http --host 127.0.0.1 --port 9100 --dataset globex
demo/run_demo.py lida com essa conexão automaticamente em uma porta efêmera, então é a maneira mais rápida de ver tudo funcionar.
Comandos upstream stdio que começam com python ou python3 são iniciados sob o próprio interpretador do gateway, então um upstream python -m ... funciona independentemente de python estar no PATH do chamador. Qualquer outro comando é executado literalmente.
Exportando o registro de auditoria
python -m mcp_gateway audit export --input config/audit-log.jsonl --format csv --output audit.csv
python -m mcp_gateway audit export --input config/audit-log.jsonl --format json
Referência de configuração
gateway:
name: mcp-audit-gateway-demo
http: { host: 127.0.0.1, port: 8080 }
security:
require_signature: true # enforce HMAC signing on incoming requests
signature_max_age_seconds: 300 # replay window
redaction:
enabled: true # redact tool RESULTS before returning them
mode: mask # mask | hash | partial
detectors: [email, phone, ssn, sin, credit_card]
redact_arguments: true # also redact arguments written to the audit log
audit:
enabled: true
path: audit-log.jsonl # relative to the config file's directory
argument_logging: redacted # redacted | full | keys_only | none
roles: # role -> tool allow/deny (glob patterns, deny wins)
admin: { allow_tools: ["*"] }
analyst: { allow_tools: ["billing.get_*", "billing.list_*"], deny_tools: ["billing.delete_*"] }
principals: # a credential = one identity = tenant + role + signing secret
- { id: acme-admin, tenant: acme, role: admin, secret: "demo-only-secret" }
tenants:
acme:
deny_tools: ["billing.delete_invoice"] # optional tenant-level kill switch
upstreams:
- { name: billing, transport: stdio, command: ["python", "-m", "mcp_gateway.toy_upstream", "--dataset", "acme"] }
rate_limit: { requests_per_minute: 60, burst: 10 }
As ferramentas são colocadas em namespace como <upstream>.<tool> (por exemplo, billing.get_invoice), para que os padrões de RBAC e política sejam estáveis entre tenants e colisões entre upstreams sejam impossíveis.
Executando os testes
uv run pytest
A suíte é totalmente offline. Os servidores MCP "externos" com os quais ela fala são o upstream de brinquedo incluído, exercitados de verdade tanto via stdio (subprocesso) quanto via HTTP streamable (loopback): sem rede, sem mocks de mocks, e termina em segundos.
Notas de segurança e escopo
- Segredos YAML estáticos são apenas para demonstrações locais. Em produção, carregue segredos de principal de um gerenciador de segredos e prefira credenciais de curta duração por solicitação; veja o artigo.
- A assinatura HMAC protege o salto cliente-gateway. Ela não substitui TLS ou controles de rede.
- A redação é uma defesa em profundidade baseada em regex, melhor esforço, não uma garantia DLP certificada. Trate-a como uma camada.
- O registro de auditoria é um registro pontual do que o gateway observou. Não é uma atestação de conformidade.
- Faça proxy e inspecione apenas servidores MCP que você possui ou está autorizado a operar.
Contrate-me
Torno backends da era da IA e críticos para dinheiro seguros para produção: autenticação, multi-tenancy, governança e a correção monótona que evita incidentes. Disponível para trabalhos com MCP, cobrança e endurecimento. Portfólio e contato: https://amin-ale.github.io/portfolio-site · amin.ale.business@gmail.com.
Licença
MIT. Veja LICENSE.