{
  "//": "──────────────────────────────────────────────────────────────────────",
  "//desc": "Centralized MCP gateway — allowlist config stub  ·  QRefAI Field Guide Part 4 (Q4.x, supply-chain)",
  "//why": "MCP servers are an UNTRUSTED supply chain. Rather than let each developer add arbitrary servers, route ALL agent→MCP traffic through one gateway you control. The gateway is the single choke point where you allowlist servers, pin versions, scope tools, strip secrets, and log every call. (Vendor-native allowlists help but can be name-matched/bypassed — a real gateway is the defense in depth.)",
  "//pair": "Enforce use of THIS gateway from the policy plane: managed-settings.json → allowManagedMcpServersOnly:true + point clients at the gateway endpoint. Then this file is the source of truth for what's reachable.",
  "//cve": "Treat every server as hostile until vetted. Pin by version/digest; an unpinned server is a live remote-code path into your agents (cf. MCP server CVEs through 2025–2026).",
  "//note": "JSON has no comments; \"//\"-prefixed keys are inert documentation — delete in production. Field names below are illustrative; map them to your actual gateway product's schema.",
  "//────": "──────────────────────────────────────────────────────────────────────",

  "gateway": {
    "endpoint": "https://mcp-gateway.acme.internal",
    "defaultPolicy": "deny",
    "logging": {
      "destination": "siem",
      "logToolCalls": true,
      "logArguments": false,
      "//logArguments": "Keep false unless you've classified what flows through — arguments can carry secrets/PII."
    },
    "secretsInjection": {
      "//": "Inject credentials at the gateway so they never live in client config or reach the model.",
      "mode": "gateway-managed",
      "source": "vault://acme/mcp"
    }
  },

  "allowlist": [
    {
      "name": "acme-code-intel",
      "//purpose": "Internal AST/graph code-intelligence server.",
      "url": "https://code-intel.acme.internal/mcp",
      "pin": "sha256:<image-or-release-digest>",
      "transport": "http",
      "allowedTools": ["search_symbols", "find_callers", "get_call_graph"],
      "deniedTools": ["*write*", "*delete*"],
      "scopes": ["read:repo"],
      "networkEgress": "internal-only"
    },
    {
      "name": "jira",
      "//purpose": "Issue tracking — read + comment only.",
      "url": "https://mcp.atlassian.example/sse",
      "pin": "vendor-version:2026.5",
      "transport": "sse",
      "allowedTools": ["search_issues", "get_issue", "add_comment"],
      "deniedTools": ["delete_issue", "transition_issue"],
      "scopes": ["read:jira", "write:comment"],
      "networkEgress": "allowlist",
      "egressAllowlist": ["mcp.atlassian.example"]
    },
    {
      "name": "datadog",
      "//purpose": "Observability — read-only.",
      "url": "https://mcp.datadoghq.example/mcp",
      "pin": "vendor-version:2026.4",
      "transport": "http",
      "allowedTools": ["query_metrics", "get_monitor", "search_logs"],
      "deniedTools": ["*"],
      "//deniedTools": "deny-all baseline; allowedTools is the only way in",
      "scopes": ["read:telemetry"],
      "networkEgress": "allowlist",
      "egressAllowlist": ["mcp.datadoghq.example"]
    }
  ],

  "denylistExamples": [
    {
      "//": "Anything not in the allowlist is denied by defaultPolicy:deny. These are",
      "//2": "explicit reminders of categories to NEVER allow through the gateway.",
      "patterns": [
        "unpinned servers (no digest/version)",
        "servers requesting filesystem or shell tools",
        "servers with wildcard egress to the public internet",
        "developer-added local servers bypassing the gateway"
      ]
    }
  ]
}
