Metadata-Version: 2.4
Name: mcpsentinel-gateway
Version: 1.1.0
Summary: Prover acesso seguro a ferramentas de infraestrutura (AWS, Gitlab, Azure) via protocolo MCP
License: MIT
Requires-Python: >=3.12
Description-Content-Type: text/markdown
Requires-Dist: fastmcp>=0.4.0
Requires-Dist: fastapi>=0.110.0
Requires-Dist: uvicorn>=0.30.0
Requires-Dist: pydantic>=2.7.0
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: boto3>=1.34.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: platformdirs>=4.2.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Requires-Dist: mypy>=1.10.0; extra == "dev"

# McpSentinel — Secure Infrastructure Edge Gateway para Model Context Protocol

[![Application Development Harness](https://img.shields.io/badge/Harness-Active-success)](./AGENTS.md)
[![PyPI Version](https://img.shields.io/pypi/v/mcpsentinel-gateway.svg)](https://pypi.org/project/mcpsentinel-gateway/)
[![Version](https://img.shields.io/badge/version-1.1.0-blue.svg)](./pyproject.toml)
[![Python Version](https://img.shields.io/badge/Python-3.12%2B-blue.svg)](./pyproject.toml)
[![Test Suite](https://img.shields.io/badge/Tests-471%20Passed-brightgreen.svg)](./tests/)
[![Test Coverage](https://img.shields.io/badge/Coverage-90%25%20Hermetic-brightgreen.svg)](./tests/)
[![Security](https://img.shields.io/badge/Security-Fail--Secure-red.svg)](./config/security.yaml)
[![Architecture](https://img.shields.io/badge/Architecture-Modular%20Gateway-purple.svg)](./docs/trd.md)
[![License](https://img.shields.io/badge/License-MIT-green.svg)](./pyproject.toml)

**McpSentinel** é um **Secure Infrastructure Edge Gateway** de nível corporativo projetado para o ecossistema do **Model Context Protocol (MCP)**. Sua missão primordial é atuar como uma barreira de proteção de borda (*security edge proxy* e mediador de controle de acesso), viabilizando que agentes autônomos de Inteligência Artificial e LLMs interajam de forma governada, segura e auditável com ferramentas operacionais de infraestrutura de nuvem (**Amazon Web Services**), gestão de código/DevOps (**GitLab** e **Azure Repos**) e orquestração de automações (**Ansible AWX / Tower**).

Ao isolar completamente o cliente IA do plano direto de execução de comandos, o McpSentinel intercepta todas as requisições em tempo real, aplica controle de acesso baseado em papéis (**RBAC Declarativo GitOps**), valida salvaguardas para ações de alto impacto (**Tríade de Confirmação**), impõe filtragem de tráfego de rede (Allowlist CIDR) e gera uma trilha forense síncrona sob a política estrita de **Fail-Secure**.

---

## 📑 Sumário

- [🏗️ Arquitetura e Fluxo de Borda](#️-arquitetura-e-fluxo-de-borda)
- [🛡️ Pilares Fundamentais de Segurança](#️-pilares-fundamentais-de-segurança)
- [⚙️ Inventário Completo de Configurações](#️-inventário-completo-de-configurações)
  - [Precedência Canônica de Configurações](#precedência-canônica-de-configurações)
  - [Arquivo Canônico de Configuração: mcpsentinel.conf](#arquivo-canônico-de-configuração-mcpsentinelconf)
  - [Variáveis de Ambiente e Suporte a .env](#variáveis-de-ambiente-e-suporte-a-env)
  - [Arquivo Declarativo GitOps: config/security.yaml](#arquivo-declarativo-gitops-configsecurityyaml)
- [🔐 Resolução Dinâmica de Segredos via Vaultwarden / Bitwarden Secrets Manager](#-resolução-dinâmica-de-segredos-via-vaultwarden--bitwarden-secrets-manager)
  - [Como Funciona o Esquema de URI vaultwarden://](#como-funciona-o-esquema-de-uri-vaultwarden)
  - [Pré-requisitos Operacionais](#pré-requisitos-operacionais)
  - [Exemplos Práticos de Configuração](#exemplos-práticos-de-configuração)
  - [Tratamento de Falhas, Timeouts e Fail-Secure](#tratamento-de-falhas-timeouts-e-fail-secure)
- [⚡ Guia de Instalação e Uso (Quickstart)](#-guia-de-instalação-e-uso-quickstart)
  - [Instalação e Uso Direto via PyPI (`pip` / `uv tool` / `pipx` / `uvx`)](#instalação-e-uso-direto-via-pypi-pip--uv-tool--pipx--uvx)
  - [Desenvolvimento Local e Contribuição (Repositório Git)](#desenvolvimento-local-e-contribuição-repositório-git)
  - [Inicialização do Ambiente de Configuração (`mcpsentinel init`)](#inicialização-do-ambiente-de-configuração-mcpsentinel-init)
  - [Comandos da CLI do Gateway (`mcpsentinel`)](#comandos-da-cli-do-gateway-mcpsentinel)
- [🔌 Guia de Integração com Clientes MCP](#-guia-de-integração-com-clientes-mcp)
- [🐳 Implantação em Produção e Contêineres](#-implantação-em-produção-e-contêineres)
  - [Dockerfile Multi-Stage com CLI bws](#dockerfile-multi-stage-de-exemplo)
  - [Execução via Docker Compose](#execução-via-docker-compose-docker-composeyml)
  - [Execução Nativa como Serviço Systemd](#execução-nativa-como-serviço-systemd)
- [🧪 Testes Herméticos e Quality Gates](#-testes-herméticos-e-quality-gates)
- [📚 Documentação Complementar do Harness](#-documentação-complementar-do-harness)
- [📄 Licença e Governança](#-licença-e-governança)

---

## 🏗️ Arquitetura e Fluxo de Borda

O fluxo de dados e execução do McpSentinel é estruturado em pipeline estrito de interceptores assíncronos (ASGI / Starlette / FastMCP), garantindo que nenhuma requisição não autorizada ou maliciosa atinja os provedores de infraestrutura:

```mermaid
flowchart TD
    subgraph Client["Camada de Agente IA / Cliente MCP"]
        IA["Agente Autônomo / Claude Desktop / IDE"]
    end

    subgraph Edge["McpSentinel Edge Gateway"]
        direction TB
        IPFilter["1. Interceptor de Rede<br/>(Allowlist CIDR & Bind Filter)"]
        AuthMid["2. Interceptor de Autenticação<br/>(Bearer Token Validation & Vaultwarden)"]
        RBACMid["3. RBAC & Guardrail Multi-Tenant<br/>(Dynamic Tool Catalog & Scope Check)"]
        AuditStart["4. Trilha de Auditoria Síncrona<br/>(Status: PENDING / Fail-Secure Lock)"]
        ExecEngine["5. Motor de Execução de Ferramentas<br/>(FastMCP Dispatcher)"]
        SanitizeMid["6. Sanitização Recursiva<br/>(Regex Masking -> [REDACTED])"]
        AuditEnd["7. Conclusão da Auditoria Síncrona<br/>(Status: SUCCESS / FAILED / BLOCKED)"]
    end

    subgraph Providers["Provedores de Infraestrutura e Serviços"]
        AWS["AWS API (STS AssumeRole / Boto3)"]
        GitLab["GitLab REST API v4"]
        Azure["Azure DevOps REST API"]
        AWX["Ansible AWX / Tower API"]
    end

    IA -->|HTTP / Server-Sent Events (SSE)| IPFilter
    IPFilter -->|IP Autorizado| AuthMid
    IPFilter -.->|IP Não Autorizado| BlockIP["HTTP 403 Forbidden"]
    
    AuthMid -->|Token Válido| RBACMid
    AuthMid -.->|Token Inválido / Ausente| BlockAuth["HTTP 401 Unauthorized"]
    
    RBACMid -->|Permitido & Confirmado| AuditStart
    RBACMid -.->|Negado / Falha de Tríade| BlockRBAC["Audit BLOCKED & Tool Error"]
    
    AuditStart -->|Audit Escrito em Disco| ExecEngine
    AuditStart -.->|Falha de I/O em Audit| FailSecure["Fail-Secure: Aborta Execução"]
    
    ExecEngine --> AWS
    ExecEngine --> GitLab
    ExecEngine --> Azure
    ExecEngine --> AWX
    
    AWS --> SanitizeMid
    GitLab --> SanitizeMid
    Azure --> SanitizeMid
    AWX --> SanitizeMid
    
    SanitizeMid --> AuditEnd
    AuditEnd -->|JSON Estruturado & Sanitizado| IA
```

---

## 🛡️ Pilares Fundamentais de Segurança

1. **Zero Credential Leakage (Vazamento Zero de Credenciais):**
   - Agentes de IA **jamais** recebem ou manipulam tokens de longa duração, chaves secretas AWS (`AWS_SECRET_ACCESS_KEY`), Personal Access Tokens (PATs) de GitLab/Azure DevOps ou tokens de automação do AWX.
   - O gateway gerencia as sessões com menor privilégio estrito, recorrendo a credenciais temporárias do AWS STS via `AssumeRole` ou injeção segura de segredos em tempo de execução.
   - Resoluções dinâmicas de credenciais suportam cofres corporativos através do esquema `vaultwarden://<item_id>/<campo>`.

2. **Trilha de Auditoria Síncrona Fail-Secure:**
   - Cada chamada de ferramenta gera eventos forenses obrigatórios em formato estruturado JSONLines (`audit.log`).
   - Ciclo de vida determinístico: evento de entrada (`PENDING`) gravado e descarregado em disco antes do despacho, seguido do evento de desfecho (`SUCCESS`, `FAILED` ou `BLOCKED`).
   - Sob a diretriz estrita de **Fail-Secure**: se houver qualquer indisponibilidade de I/O, disco cheio ou erro de gravação do log de auditoria, a execução da ferramenta é abortada imediatamente. Nenhuma ação operacional ocorre às cegas.

3. **GitOps RBAC Declarativo & Isolamento Multi-Tenant:**
   - A configuração de identidades, escopos e perfis reside integralmente no arquivo versionado [`config/security.yaml`](file:///mnt/home/alexandre/Projetos/McpSentinel/config/security.yaml).
   - Sem dependência de bancos relacionais dinâmicos ou interfaces web mutáveis sujeitas a adulteração externa. Toda alteração passa por revisão de código (Pull Request / Merge Request).
   - **Filtragem Dinâmica de Catálogo (`tools/list`):** Cada agente só visualiza as ferramentas atribuídas ao seu perfil.
   - **Isolamento de Tenant (`tools/call`):** Validação em tempo de execução garante que o agente opere estritamente dentro das contas AWS, projetos de repositório e organizações de automação declaradas para ele.

4. **Tríade de Confirmação para Ações Destrutivas (Guardrails Operacionais):**
   - Operações classificadas como destrutivas (ex: `aws_ec2_terminate_instances`, `aws_s3_delete_bucket`, `gitlab_delete_branch`, `azure_delete_branch`, ou templates críticos de AWX como `teardown-*`) exigem o cumprimento simultâneo de três condições obrigatórias:
     1. **Habilitação em Perfil:** O perfil RBAC deve possuir a flag `destructive_actions_allowed: true`.
     2. **Flag Explícita de Confirmação:** O parâmetro `confirm_action=true` deve ser enviado na chamada.
     3. **Justificativa Operacional:** Um argumento `justification` não vazio (mínimo de caracteres exigido) deve ser fornecido para registro em auditoria.
   - Caso qualquer condição falhe, a ação é bloqueada com status `BLOCKED` e auditada imediatamente.

5. **Sanitização e Mascaramento Recursivo Automático:**
   - Todos os payloads de entrada, saídas brutas de ferramentas, payloads de erro e rastros de pilha (*tracebacks*) são processados por rotinas recursivas de sanitização antes de serem transmitidos ao cliente IA ou gravados em log.
   - Padrões sensíveis (senhas, cabeçalhos `Authorization`, chaves privadas, tokens JWT/PAT, hashes de credenciais) são substituídos pelo token padronizado `[REDACTED]`.

6. **Defesa em Profundidade de Rede (Network Allowlist):**
   - Interceptor de borda integrado na camada ASGI valida a origem das requisições contra regras de IP individuais ou blocos CIDR autorizados (`allowed_origins`), bloqueando tráfego não confiável antes de qualquer processamento HTTP/SSE.

---

## ⚙️ Inventário Completo de Configurações

O McpSentinel adota o padrão de configuração em camadas, permitindo flexibilidade sem comprometer a previsibilidade da segurança.

### Precedência Canônica de Configurações

O McpSentinel adota uma precedência determinística em camadas para resolução de parâmetros operacionais:

1. **Argumentos de Linha de Comando (CLI):** Flags explícitas passadas na invocação (`--port`, `--bind`, `--conf-file`, etc.) têm prioridade máxima.
2. **Variável de Ambiente `SENTINEL_CONF_FILE`:** Permite apontar um caminho arbitrário de arquivo `.conf` ou `.env`.
3. **Arquivo de Configuração Canônico do Usuário (`mcpsentinel.conf`):** Localizado no diretório padrão de configurações do sistema operacional via `platformdirs`:
   - **Linux:** `~/.config/mcpsentinel/mcpsentinel.conf` (conforme especificação XDG).
   - **macOS:** `~/Library/Application Support/mcpsentinel/mcpsentinel.conf`.
   - **Windows:** `%APPDATA%\mcpsentinel\mcpsentinel.conf`.
4. **Retrocompatibilidade Local (Fallback CWD `.env`):** Caso o arquivo canônico do usuário não exista, o gateway busca automaticamente por um arquivo `.env` no diretório de execução atual (*Current Working Directory*).
5. **Variáveis de Ambiente do Sistema Operacional (Shell OS):** Valores exportados diretamente no ambiente com prefixo `SENTINEL_`.
6. **Valores Padrão (*Defaults* da Aplicação):** Definidos nas classes de configuração do gateway.
7. **Arquivo Declarativo GitOps (`config/security.yaml`):** Matriz base estruturada de segurança (RBAC, tenants e perfis).

---

### Arquivo Canônico de Configuração: `mcpsentinel.conf`

A partir da versão **1.1.0**, o McpSentinel adota `mcpsentinel.conf` como o arquivo canônico de configuração do usuário, substituindo a dependência obrigatória de arquivos `.env` soltos no diretório do projeto.

O arquivo pode ser gerado automaticamente com permissões restritas através do subcomando:
```bash
mcpsentinel init
```

Por padrão, em sistemas POSIX (Linux/macOS), o utilitário assegura permissão `0700` (`rwx------`) no diretório de configuração e `0600` (`rw-------`) no arquivo `mcpsentinel.conf`, prevenindo leitura não autorizada de tokens e segredos por outros usuários do sistema operacional.

Caso deseje sobrescrever o arquivo padrão durante a execução do gateway, utilize a flag `--conf-file <caminho>` disponível nos subcomandos `start` e `restart`:
```bash
# Iniciar utilizando um arquivo de configuração específico
mcpsentinel start --conf-file /etc/mcpsentinel/producao.conf

# Reiniciar o serviço apontando para nova configuração
mcpsentinel restart -d --conf-file /etc/mcpsentinel/producao.conf
```

---

### Variáveis de Ambiente e Suporte a `.env`

As configurações definidas em `mcpsentinel.conf` ou `.env` utilizam sintaxe padrão chave-valor (`KEY=VALUE`) e são mapeadas para os parâmetros internos via `pydantic-settings`:

| Variável | Padrão | Descrição Didática |
|---|---|---|
| `SENTINEL_AUTH_TOKEN` | `sentinel-secret-token` | Bearer token estático de fallback utilizado em testes ou inicializações básicas. |
| `SENTINEL_CONF_FILE` | *(nenhum)* | Caminho customizado para sobrescrever o arquivo de configuração (.conf ou .env). |
| `SENTINEL_SECURITY_CONFIG` | `config/security.yaml` | Caminho do arquivo declarativo GitOps com os perfis RBAC, tenants e agentes. |
| `SENTINEL_AUDIT_LOG_PATH` | `logs/audit.log` | Destino do arquivo síncrono de trilha forense JSONLines. |
| `SENTINEL_HOST` | `0.0.0.0` | Endereço IP padrão para escuta do servidor ASGI Starlette/FastMCP. |
| `SENTINEL_PORT` | `8000` | Porta TCP para escuta das requisições MCP/SSE. |
| `SENTINEL_ENVIRONMENT` | `development` | Identificador de ambiente operacional (`development`, `staging`, `production`). |
| `SENTINEL_LOG_LEVEL` | `INFO` | Granularidade dos logs operacionais (`DEBUG`, `INFO`, `WARNING`, `ERROR`). |
| `SENTINEL_PID_FILE` | `~/.mcpsentinel/mcpsentinel.pid` | Caminho do arquivo de trava (lockfile) e PID para o daemon de segundo plano. |
| `SENTINEL_LOG_FILE` | `~/.mcpsentinel/logs/mcpsentinel.log` | Caminho do arquivo de log dedicado das operações do daemon. |
| `SENTINEL_ALLOWED_IPS` | `*` (ou vazio) | Lista de IPs ou blocos CIDR autorizados separados por vírgula (ex: `127.0.0.1,10.0.0.0/24`). |
| `SENTINEL_BIND_INTERFACES` | `127.0.0.1` | Interfaces de rede permitidas para ligação do socket local. |

#### Variáveis de Provedores de Nuvem e DevOps (Interpolação no `security.yaml`)

| Variável | Finalidade |
|---|---|
| `BWS_ACCESS_TOKEN` | Token de serviço (Service Account Token) para autenticação da CLI `bws` com o Vaultwarden / Bitwarden Secrets Manager. Obrigatório caso utilize o esquema `vaultwarden://`. |
| `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` | Credenciais básicas AWS da máquina host para permitir o início de sessões STS. |
| `AWS_DEFAULT_REGION` | Região AWS padrão (ex: `us-east-1`, `sa-east-1`). |
| `GITLAB_BASE_URL` | URL base do GitLab (padrão: `https://gitlab.com` ou instância self-hosted). |
| `GITLAB_TOKEN` | Token com permissões de API para interagir com o GitLab (ou URI `vaultwarden://<item_id>/<campo>`). |
| `AZURE_DEVOPS_BASE_URL` | URL base do Azure DevOps (padrão: `https://dev.azure.com`). |
| `AZURE_DEVOPS_TOKEN` | Personal Access Token (PAT) corporativo com escopo de leitura/escrita em repositórios (ou URI `vaultwarden://<item_id>/<campo>`). |
| `AWX_BASE_URL` | Endereço do cluster Ansible AWX / Automation Platform. |
| `AWX_TOKEN` | Token de autenticação Bearer para lançamento e monitoramento de Job Templates (ou URI `vaultwarden://<item_id>/<campo>`). |

---

### Arquivo Declarativo GitOps: `config/security.yaml`

O arquivo [`config/security.yaml`](file:///mnt/home/alexandre/Projetos/McpSentinel/config/security.yaml) é o coração da segurança do gateway. É dividido em 4 seções principais:

```yaml
version: "1.0"

# 1. Filtros de Rede (Opcional no YAML, pode ser sobrescrito por CLI)
network_filter:
  bind_addresses:
    - "127.0.0.1"
  allowed_origins:
    - "127.0.0.1"
    - "192.168.1.0/24"

# 2. Tenants Corporativos Autorizados
tenants:
  aws_accounts:
    - id: "dev-account"
      account_id: "111122223333"
      name: "Ambiente de Desenvolvimento"
      allowed_regions: ["us-east-1", "sa-east-1"]
    - id: "prod-account"
      account_id: "444455556666"
      name: "Ambiente de Produção"
      allowed_regions: ["us-east-1"]

  gitlab_organizations:
    - id: "gitlab-corp"
      name: "GitLab Corporativo"
      base_url: "${GITLAB_BASE_URL:-https://gitlab.com}"
      token: "${GITLAB_TOKEN}"
      allowed_projects: ["infra/*", "apps/*"]

  azure_organizations:
    - id: "azure-corp"
      name: "Azure DevOps Corp"
      organization: "mycorp"
      base_url: "${AZURE_DEVOPS_BASE_URL:-https://dev.azure.com}"
      token: "${AZURE_DEVOPS_TOKEN}"
      allowed_projects: ["InfraCore", "Apps-*"]

  awx_organizations:
    - id: "awx-corp"
      name: "Cluster AWX Principal"
      base_url: "${AWX_BASE_URL:-https://awx.corp.internal}"
      token: "${AWX_TOKEN}"
      allowed_templates: ["deploy-app", "backup-database", "teardown-cluster"]
      destructive_templates: ["teardown-cluster"]

# 3. Perfis RBAC (Matriz de Autorização)
profiles:
  sre_operations:
    description: "Perfil operacional SRE com permissão de alto risco"
    destructive_actions_allowed: true
    tools:
      - "aws_get_caller_identity"
      - "aws_ec2_describe_instances"
      - "aws_ec2_terminate_instances"
      - "gitlab_get_project"
      - "gitlab_delete_branch"
      - "awx_launch_job_template"
    allowed_tenants:
      aws_accounts: ["dev-account", "prod-account"]
      gitlab_organizations: ["gitlab-corp"]
      awx_organizations: ["awx-corp"]

  developer_iac:
    description: "Perfil restrito a ambientes de desenvolvimento sem ações destrutivas"
    destructive_actions_allowed: false
    tools:
      - "aws_get_caller_identity"
      - "aws_ec2_describe_instances"
      - "gitlab_get_project"
      - "gitlab_create_branch"
    allowed_tenants:
      aws_accounts: ["dev-account"]
      gitlab_organizations: ["gitlab-corp"]

# 4. Agentes e Identidades (Vinculação de Token -> Perfil)
agents:
  - agent_id: "agent-sre-01"
    name: "Agente SRE Principal"
    token: "${SENTINEL_TOKEN_SRE:-token-sre-01-secret}"
    profile: "sre_operations"

  - agent_id: "agent-dev-01"
    name: "Agente IaC Dev"
    token: "${SENTINEL_TOKEN_DEV:-token-dev-01-secret}"
    profile: "developer_iac"
```

---

## 🔐 Resolução Dinâmica de Segredos via Vaultwarden / Bitwarden Secrets Manager

Em ambientes corporativos com requisitos estritos de segurança, tokens de longa duração e chaves de API não devem ser gravados em texto plano dentro de arquivos de configuração versionados (`security.yaml`) ou arquivos locais (`.env`), eliminando os riscos de vazamento acidental em commits de Git ou extração por processos locais (*Zero Credential Leakage*).

O **McpSentinel** implementa nativamente a arquitetura definida na [**ADR 004**](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/adrs/004-resolucao-de-tokens-via-vaultwarden.md) e na especificação [**OpenSPEC MCP-38**](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/specs/MCP-38-vault-tokens.md), integrando o módulo [`mcpsentinel.security.secrets`](file:///mnt/home/alexandre/Projetos/McpSentinel/src/mcpsentinel/security/secrets/) (`SecretsManager` e `VaultwardenResolver`).

### Como Funciona o Esquema de URI `vaultwarden://`

Qualquer campo de token configurado para provedores (GitLab, Azure DevOps, AWX) ou agentes pode ser declarado com a URI canônica:

```
vaultwarden://<item_id>/<campo>
```

- `<item_id>`: Identificador único universal (UUID) do segredo armazenado no cofre (ex: `b4a2c1d0-1234-5678-90ab-cdef12345678`).
- `<campo>`: Propriedade do segredo a ser extraída do JSON retornado pelo cofre (geralmente `value`, `note` ou campos customizados).

Exemplo de URI válida:
```yaml
vaultwarden://b4a2c1d0-1234-5678-90ab-cdef12345678/value
```

```mermaid
sequenceDiagram
    autonumber
    participant Gateway as McpSentinel Gateway
    participant SM as SecretsManager
    participant Resolver as VaultwardenResolver
    participant CLI as Bitwarden CLI (bws)
    participant Vault as Vaultwarden / Bitwarden SM

    Gateway->>SM: resolve("vaultwarden://<item_id>/value")
    SM->>Resolver: resolve(uri)
    Resolver->>CLI: bws secret get <item_id> (via Subprocess)
    Note over Resolver,CLI: Injeta BWS_ACCESS_TOKEN do ambiente<br/>Timeout estrito: 10 segundos
    CLI->>Vault: Requisição mTLS / HTTPS autenticada
    Vault-->>CLI: JSON com dados do segredo
    CLI-->>Resolver: Payload JSON via stdout
    Resolver->>Resolver: Parse JSON e extração da chave 'value'
    Note over Resolver: Segredo mantido apenas em RAM.<br/>Em caso de erro/log: mascarado com [REDACTED].
    Resolver-->>SM: Retorna segredo decifrado
    SM-->>Gateway: Retorna segredo para inicialização do client
```

### Pré-requisitos Operacionais

Para utilizar a resolução dinâmica via Vaultwarden / Bitwarden Secrets Manager em runtime, o ambiente host ou contêiner deve atender a dois pré-requisitos:

1. **Binário CLI `bws` Disponível no `PATH`:**
   - Instale a CLI oficial do Bitwarden Secrets Manager (`bws`) disponibilizada nos releases do repositório oficial [`bitwarden/sdk-sm`](https://github.com/bitwarden/sdk-sm/releases):
     ```bash
     # Exemplo de instalação manual no Linux x86_64:
     curl -fsSL -o /tmp/bws.zip "https://github.com/bitwarden/sdk-sm/releases/download/bws-v1.0.0/bws-x86_64-unknown-linux-gnu-1.0.0.zip"
     unzip /tmp/bws.zip -d /usr/local/bin/
     chmod +x /usr/local/bin/bws
     rm -f /tmp/bws.zip
     ```
   - Caso o binário `bws` não seja encontrado no `PATH`, o gateway aborta a inicialização levantando `DependencyNotFoundError`.

2. **Variável de Ambiente `BWS_ACCESS_TOKEN`:**
   - Crie um *Service Account* no cofre corporativo com permissão de leitura nos projetos desejados e exporte o token gerado:
     ```bash
     export BWS_ACCESS_TOKEN="0.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
     ```

### Exemplos Práticos de Configuração

#### 1. Declaração Direta no `config/security.yaml`

Você pode referenciar a URI do cofre diretamente nos tenants corporativos:

```yaml
version: "1.0"

tenants:
  gitlab_organizations:
    - id: "gitlab-corp"
      name: "GitLab Corporativo"
      base_url: "https://gitlab.com"
      # O McpSentinel resolverá o segredo em runtime chamando 'bws secret get'
      token: "vaultwarden://4a72d3e1-8842-4f39-9d7a-112233445566/value"
      allowed_projects: ["infra/*", "apps/*"]

  azure_organizations:
    - id: "azure-corp"
      name: "Azure DevOps Corp"
      organization: "mycorp"
      base_url: "https://dev.azure.com"
      token: "vaultwarden://9f8e7d6c-5b4a-3210-fedc-ba9876543210/value"
      allowed_projects: ["InfraCore", "Apps-*"]

  awx_organizations:
    - id: "awx-corp"
      name: "Cluster Ansible AWX"
      base_url: "https://awx.corp.internal"
      token: "vaultwarden://11223344-5566-7788-99aa-bbccddeeff00/value"
      allowed_templates: ["deploy-app", "backup-database"]

agents:
  - agent_id: "agent-sre-01"
    name: "Agente SRE Principal"
    token: "vaultwarden://aa11bb22-cc33-dd44-ee55-ff6677889900/value"
    profile: "sre_operations"
```

#### 2. Interpolação Segura via `.env`

Também é possível combinar variáveis de ambiente com as URIs de cofre:

```bash
# Arquivo .env
BWS_ACCESS_TOKEN="0.seu_token_de_service_account"
GITLAB_TOKEN="vaultwarden://4a72d3e1-8842-4f39-9d7a-112233445566/value"
AZURE_DEVOPS_TOKEN="vaultwarden://9f8e7d6c-5b4a-3210-fedc-ba9876543210/value"
AWX_TOKEN="vaultwarden://11223344-5566-7788-99aa-bbccddeeff00/value"
```

No `security.yaml`, os valores são interpolados normalmente:
```yaml
token: "${GITLAB_TOKEN}"
```

#### 3. Retrocompatibilidade (Valores Literais)

Se a string de token **não contiver** o separador de protocolo `://` (por exemplo, `glpat-abcdef123456`), o `SecretsManager` adota comportamento transparente e utiliza o valor como literal sem executar nenhum processo externo.

### Tratamento de Falhas, Timeouts e Fail-Secure

O `VaultwardenResolver` opera sob os mais rigorosos princípios de **Fail-Secure**:

- **Hard-Timeout de 10 Segundos:** Se a CLI `bws` não responder em até 10 segundos (devido a instabilidades de rede ou bloqueio de DNS), o processo filho é encerrado forçadamente (`kill`) e uma exceção `SecretTimeoutError` é levantada, abortando a inicialização do provedor correspondente.
- **Sanitização Recursiva de Logs (`[REDACTED]`):** Nenhuma mensagem de erro, rastro de pilha (*traceback*) ou saída padrão (`stdout`/`stderr`) expõe o conteúdo do segredo ou do token de acesso do cofre. Mensagens de erro de autenticação ou chaves inexistentes são registradas com a máscara `[REDACTED]`.
- **Validação de Esquema:** Esquemas não registrados (ex: `unsupportedvault://`) resultam em `UnknownResolverSchemeError` imediato, impedindo execuções em estado inconsistente.

---

## ⚡ Guia de Instalação e Uso (Quickstart)

### Pré-requisitos
- **Linux** (Debian, Ubuntu, RHEL, Fedora, Arch) ou **macOS**.
- **Python 3.12+**.
- [`uv`](https://github.com/astral-sh/uv) (recomendado) ou `pip` / `pipx`.

---

### Instalação e Uso Direto via PyPI (`pip` / `uv tool` / `pipx` / `uvx`)

O McpSentinel é publicado oficialmente no PyPI sob o nome de pacote [**`mcpsentinel-gateway`**](https://pypi.org/project/mcpsentinel-gateway/).

Ele expõe dois pontos de entrada equivalentes de linha de comando no seu `PATH`:
- `mcpsentinel` (comando principal canônico)
- `mcpsentinel-gateway` (alias correspondente ao nome do pacote)

#### 1. Instalação Isolada para Usuários Finais (Recomendado)

Para utilizar o gateway como utilitário de sistema sem poluir o ambiente Python global:

```bash
# Com uv tool (ultra-rápido)
uv tool install mcpsentinel-gateway

# Ou com pipx
pipx install mcpsentinel-gateway
```

#### 2. Instalação via `pip` tradicional

Em um ambiente virtual dedicado ou contêiner:

```bash
pip install mcpsentinel-gateway
```

#### 3. Execução Imediata sem Instalação Prévia via `uvx`

Para testar ou executar o gateway sob demanda sem instalar previamente no sistema:

```bash
uvx --from mcpsentinel-gateway mcpsentinel start --port 8000
```

#### 4. Uso Imediato dos Comandos CLI

Após a instalação, os comandos já estarão disponíveis no terminal:

```bash
# Iniciar em primeiro plano (porta padrão 8000)
mcpsentinel start

# Iniciar em segundo plano como Daemon POSIX
mcpsentinel start -d --port 8000

# Consultar status do processo em execução
mcpsentinel status

# Parar o serviço em background
mcpsentinel stop
```

---

### Desenvolvimento Local e Contribuição (Repositório Git)

Para desenvolvedores que desejam contribuir com o código, rodar os testes herméticos ou customizar o McpSentinel:

```bash
# 1. Clone o repositório
git clone https://github.com/Defendi/McpSentinel.git
cd McpSentinel

# 2. Crie o ambiente virtual e sincronize dependências
uv sync

# 3. Execute a CLI usando o ambiente sincronizado
uv run mcpsentinel start --port 8000
```

---

### Inicialização do Ambiente de Configuração (`mcpsentinel init`)

O McpSentinel provê o subcomando `init` para gerar de forma automatizada o arquivo de configuração canônico `mcpsentinel.conf` com permissões seguras:

```bash
# Inicialização canônica no diretório do usuário (~/.config/mcpsentinel/mcpsentinel.conf no Linux)
mcpsentinel init

# Forçar a sobrescrita caso o arquivo já exista
mcpsentinel init --force

# Gerar em um caminho customizado
mcpsentinel init --path /etc/mcpsentinel/mcpsentinel.conf
```

> [!TIP]
> Em plataformas POSIX (Linux e macOS), o subcomando `init` aplica automaticamente `chmod 0700` (`rwx------`) no diretório de destino e `chmod 0600` (`rw-------`) no arquivo `mcpsentinel.conf`, garantindo que apenas o usuário proprietário possa ler os tokens e credenciais.

#### Conteúdo Gerado no `mcpsentinel.conf`

O arquivo de configuração aceita todas as variáveis do gateway no formato `KEY=VALUE`:

```ini
# Interface e porta de escuta do servidor HTTP/SSE
SENTINEL_HOST=0.0.0.0
SENTINEL_PORT=8000

# Nível de log operacional (DEBUG, INFO, WARNING, ERROR)
SENTINEL_LOG_LEVEL=INFO

# Ambiente de execução (development, staging, production)
SENTINEL_ENVIRONMENT=development

# Token estático de autenticação Bearer para clientes MCP
SENTINEL_AUTH_TOKEN=troque-este-token-por-um-segredo-forte

# Caminho para arquivo de auditoria síncrona JSONLines
SENTINEL_AUDIT_LOG_PATH=~/.mcpsentinel/logs/audit.log

# Token de serviço do Bitwarden Secrets Manager / Vaultwarden (opcional, para URIs vaultwarden://)
BWS_ACCESS_TOKEN=""

# Tokens de agentes para RBAC multi-tenant
SENTINEL_TOKEN_SRE=token-sre-01-secret
SENTINEL_TOKEN_DEV=token-dev-01-secret
```

#### Retrocompatibilidade com Arquivos `.env`

Para preservar o fluxo de trabalho de deploys legados ou repositórios locais, se o arquivo `mcpsentinel.conf` do usuário **não existir**, o McpSentinel busca de forma transparente o arquivo `.env` localizado no diretório atual de execução (`CWD`).

---

### Comandos da CLI do Gateway (`mcpsentinel`)

O McpSentinel provê uma CLI robusta (`mcpsentinel` ou `mcpsentinel-gateway`), compatível com códigos de saída padrão **LSB** (0=RUNNING, 3=STOPPED, 1=ERROR).

#### Resumo de Subcomandos

| Subcomando | Finalidade | Principais Flags |
|---|---|---|
| `init` | Gera template canônico `mcpsentinel.conf` com permissões restritas | `--force`, `--path <caminho>` |
| `start` | Inicia o gateway em primeiro plano ou como daemon de fundo | `-d` (`--daemon`), `--port`, `--bind`, `--allow-ip`, `--conf-file <caminho>`, `--config` |
| `restart` | Reinicia a instância ativa do daemon | `-d` (`--daemon`), `--conf-file <caminho>`, `--timeout <segundos>` |
| `status` | Inspeciona estado e processo em execução (código LSB) | `--pid-file <caminho>` |
| `reload` | Envia sinal `SIGHUP` para recarregar políticas e logs | `--pid-file <caminho>` |
| `stop` | Interrompe o daemon de forma graciosa ou forçada | `--force`, `--timeout <segundos>` |

#### Modo Interativo (Primeiro Plano / Foreground)
Ideal para desenvolvimento, testes e inspeção de logs em tempo real:

```bash
# Iniciar utilizando a configuração padrão resolvida
mcpsentinel start --port 8000

# Iniciar apontando para um arquivo de configuração explícito
mcpsentinel start --conf-file /etc/mcpsentinel/mcpsentinel.conf

# (Se estiver no ambiente do repositório: uv run mcpsentinel start --port 8000)
```

#### Modo Daemon POSIX (Segundo Plano / Background)
Executa em segundo plano com desacoplamento canônico (*double-fork*, trava exclusiva por lockfile de PID):

```bash
# Iniciar o daemon
mcpsentinel start --daemon

# Iniciar com restrição de origens, porta e arquivo de configuração customizado
mcpsentinel start -d --port 8000 --bind 127.0.0.1 --allow-ip 127.0.0.1 --conf-file ~/.config/mcpsentinel/mcpsentinel.conf

# Verificar o status atual (PID e uptime)
mcpsentinel status

# Recarregar configurações e arquivos de log (envia sinal SIGHUP sem derrubar conexões)
mcpsentinel reload

# Reiniciar o serviço (suporta sobrescrever conf-file)
mcpsentinel restart --daemon --conf-file ~/.config/mcpsentinel/mcpsentinel.conf

# Interromper o serviço graciosamente
mcpsentinel stop

# Interrupção forçada (caso exceda o timeout gracioso)
mcpsentinel stop --force --timeout 15
```

---

## 🔌 Guia de Integração com Clientes MCP

Todos os clientes autenticam-se via cabeçalho HTTP padrão `Authorization: Bearer <TOKEN_DO_AGENTE>`.

### 1. Claude Desktop

Abra o arquivo de configuração do seu Claude Desktop:
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Linux:** `~/.config/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

Adicione o McpSentinel na seção `mcpServers`:

```json
{
  "mcpServers": {
    "mcpsentinel": {
      "url": "http://localhost:8000/sse",
      "headers": {
        "Authorization": "Bearer token-sre-01-secret"
      }
    }
  }
}
```

> [!NOTE]
> Quando o Claude Desktop se conectar, ele enviará a requisição `tools/list`. O McpSentinel responderá **apenas** com as ferramentas vinculadas ao perfil do token (`sre_operations`), ocultando todas as outras.

---

### 2. Validação Rápida via cURL

Você pode inspecionar o handshake SSE diretamente no terminal:

```bash
# Conexão válida (Stream aberto aguardando eventos)
curl -N -H "Authorization: Bearer token-sre-01-secret" \
  http://localhost:8000/sse

# Tentativa não autenticada (Bloqueio 401 imediato)
curl -i http://localhost:8000/sse
# HTTP/1.1 401 Unauthorized
# {"error": "Unauthorized", "code": "AUTHENTICATION_ERROR", "detail": "Missing Authorization header"}
```

---

## 🐳 Implantação em Produção e Contêineres

Para ambientes de produção orquestrados (Kubernetes, AWS ECS, Docker Compose), o McpSentinel deve ser empacotado em contêineres mínimos, não-root e isolados.

### Dockerfile Multi-Stage de Exemplo

Crie um arquivo `Dockerfile` na raiz do projeto:

```dockerfile
# ----------------------------------------------------
# Estágio 1: Build & Dependências com uv e CLI bws
# ----------------------------------------------------
FROM python:3.12-slim-bookworm AS builder

WORKDIR /app

ENV UV_COMPILE_BYTECODE=1 \
    UV_LINK_MODE=copy

RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    curl \
    unzip \
    && rm -rf /var/lib/apt/lists/*

# Instalar uv
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv

# Instalar Bitwarden Secrets Manager CLI (bws) para resolução de segredos em runtime
ARG BWS_VERSION=1.0.0
RUN curl -fsSL -o /tmp/bws.zip "https://github.com/bitwarden/sdk-sm/releases/download/bws-v${BWS_VERSION}/bws-x86_64-unknown-linux-gnu-${BWS_VERSION}.zip" \
    && unzip /tmp/bws.zip -d /usr/local/bin/ \
    && chmod +x /usr/local/bin/bws \
    && rm -f /tmp/bws.zip

# Instalação das dependências do projeto
COPY pyproject.toml ./
RUN uv venv /opt/venv && uv pip install --prefix /opt/venv .

# ----------------------------------------------------
# Estágio 2: Imagem Final de Execução (Hardened)
# ----------------------------------------------------
FROM python:3.12-slim-bookworm AS runtime

WORKDIR /app

# Usuário não privilegiado para segurança do contêiner
RUN groupadd -g 10001 sentinel && \
    useradd -u 10001 -g sentinel -m -s /bin/bash sentinel && \
    mkdir -p /app/logs /app/config && \
    chown -R sentinel:sentinel /app

COPY --from=builder /usr/local/bin/bws /usr/local/bin/bws
COPY --from=builder --chown=sentinel:sentinel /opt/venv /opt/venv
COPY --chown=sentinel:sentinel src/ /app/src/
COPY --chown=sentinel:sentinel config/ /app/config/

USER sentinel

ENV PATH="/opt/venv/bin:$PATH" \
    PYTHONPATH="/app/src" \
    PYTHONUNBUFFERED=1 \
    SENTINEL_HOST="0.0.0.0" \
    SENTINEL_PORT="8000"

EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
  CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()" || exit 1

ENTRYPOINT ["mcpsentinel"]
CMD ["start", "--port", "8000"]
```

---

### Execução via Docker Compose (`docker-compose.yml`)

```yaml
version: "3.8"

services:
  mcpsentinel:
    build: .
    container_name: mcpsentinel-gateway
    restart: unless-stopped
    ports:
      - "8000:8000"
    environment:
      - SENTINEL_PORT=8000
      - SENTINEL_ENVIRONMENT=production
      - SENTINEL_LOG_LEVEL=INFO
      - SENTINEL_SECURITY_CONFIG=/app/config/security.yaml
      - SENTINEL_AUDIT_LOG_PATH=/app/logs/audit.log
      - SENTINEL_TOKEN_SRE=${SENTINEL_TOKEN_SRE}
      - BWS_ACCESS_TOKEN=${BWS_ACCESS_TOKEN}
      - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
      - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
      - AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION:-us-east-1}
    volumes:
      - ./config/security.yaml:/app/config/security.yaml:ro
      - sentinel-logs:/app/logs
    read_only: false
    security_opt:
      - no-new-privileges:true

volumes:
  sentinel-logs:
    driver: local
```

Suba o serviço de produção com:
```bash
docker compose up -d
docker compose logs -f
```

---

### Execução Nativa como Serviço Systemd

Para instalações diretamente em instâncias Linux dedicadas, o repositório disponibiliza um template pronto em [`deploy/systemd/mcpsentinel.service`](file:///mnt/home/alexandre/Projetos/McpSentinel/deploy/systemd/mcpsentinel.service):

```bash
# Como serviço de usuário (sem privilégios de root)
mkdir -p ~/.config/systemd/user/
cp deploy/systemd/mcpsentinel.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now mcpsentinel.service

# Verificar status
systemctl --user status mcpsentinel.service
```

Para detalhes adicionais sobre permissões em `/var/log` e integração com `logrotate`, consulte a documentação detalhada em [`docs/daemon-systemd.md`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/daemon-systemd.md).

---

## 🧪 Testes Herméticos e Quality Gates

O projeto possui rigorosa disciplina de engenharia de software garantida por uma suíte de testes totalmente hermética — o que significa que nenhum teste realiza chamadas reais de rede a provedores de nuvem ou depende de bancos de dados externos.

### Executando os Testes e Cobertura

```bash
# Execução da suíte completa de testes com relatório de cobertura
uv run pytest --cov=src/mcpsentinel --cov-report=term-missing
```

- **Total de testes:** **471 testes automatizados** (unidade, integração, guardrails, daemon, e2e blackbox).
- **Cobertura Hermética Global:** **90%**.
- **Módulos Centrais:**
  - Audit Trail & Fail-Secure: **97%**
  - Autenticação & Contexto: **97% - 100%**
  - CLI & Daemon POSIX: **83% - 100%**
  - Guardrails Destrutivos & Secrets: **93% - 100%**

### Inspeção Estática de Código e Tipagem

```bash
# Verificação de padrões de código com Ruff (linter)
uv run ruff check .

# Verificação estrita de tipagem estática com Mypy
uv run mypy src
```

---

## 📚 Documentação Complementar do Harness

Este repositório adota a disciplina canônica do **Application Development Harness**. Consulte a documentação técnica para aprofundamento:

- **Manual de Operação e Governança:** [`docs/manual-de-operacao.md`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/manual-de-operacao.md) — Guia detalhado para Administradores de Segurança e Auditores.
- **Operação de Daemon e Systemd:** [`docs/daemon-systemd.md`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/daemon-systemd.md) — Especificação técnica do ciclo de vida em background e códigos LSB.
- **Technical Requirements Document (TRD):** [`docs/trd.md`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/trd.md) — Limites globais de latência, tolerância e componentes.
- **Registros de Decisões Arquiteturais (ADRs):**
  - [`ADR 001: Transporte Remoto HTTP para Servidor MCP Centralizado`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/adrs/001-transporte-remoto-http-mcp.md)
  - [`ADR 002: Modelo de Segurança Declarativo GitOps, RBAC e Guardrails Operacionais`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/adrs/002-seguranca-rbac-gitops-e-guardrails.md)
  - [`ADR 003: Trilha de Auditoria Síncrona Estruturada sob Paradigma Fail-Secure`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/adrs/003-auditoria-sincrona-fail-secure.md)
  - [`ADR 004: Resolução de Tokens via Vaultwarden / Bitwarden Secrets Manager`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/adrs/004-resolucao-de-tokens-via-vaultwarden.md)
  - [`ADR 005: Restrição de Rede via Allowlist de IPs e CIDR`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/adrs/005-ip-filtering-allowlist.md)
  - [`ADR 006: Background Daemon Service POSIX e Gerenciamento LSB`](file:///mnt/home/alexandre/Projetos/McpSentinel/docs/adrs/006-background-daemon-service.md)

---

## 📄 Licença e Governança

Distribuído sob a licença **MIT**. Veja o arquivo [`pyproject.toml`](file:///mnt/home/alexandre/Projetos/McpSentinel/pyproject.toml) para mais informações.

Contribuições devem seguir estritamente o padrão do **Application Development Harness** e o fluxo de trabalho orientado a especificações OpenSPEC. Todas as modificações em ferramentas ou políticas de segurança devem ser acompanhadas de testes herméticos e documentação atualizada.
