{"id":"a8c4e2dd-1d64-418c-9f3b-aec7e612f158","slug":"akaitigo-secure-mcp-gateway","kind":"mcp","name":"secure-mcp-gateway","summary":"OAuth2認証と監査ログを提供するMCPゲートウェイ（ツール単位認可はPhase 2）","owner":"akaitigo","repoUrl":"https://github.com/akaitigo/secure-mcp-gateway","license":"MIT","licenseTier":"permissive","trust":"community","stars":0,"match":null,"fewStars":true,"format":"mcp","createdAt":"2026-03-30T02:14:31.000Z","addedAt":"2026-10-29T03:27:36.912Z","logoUrl":"https://avatars.githubusercontent.com/u/84075783?v=4","linkOnly":false,"collection":null,"skillPath":null,"categories":["utilities"],"tags":["audit-logging","go","grpc","oauth2","opa","security"],"runtime":"go","local":true,"cloudCapable":false,"cloudCapability":"unknown","cloudReadyOnPlatform":false,"needsApiKey":false,"reviewed":false,"syncedAt":"2026-10-29T03:27:46.323Z","sample":false,"url":"https://conduits.dev/tools/akaitigo-secure-mcp-gateway","language":"Go","transports":["stdio"],"install":{},"requirements":{"env":[],"upstreamMayCharge":false},"tools":null,"readme":"# secure-mcp-gateway\n\n企業内MCPサーバーの手前でOAuth2認証・OPAによるツール粒度の認可・監査ログを提供するModel Context Protocol (MCP) ゲートウェイ。ポリシー評価はfail-close（OPA障害時はデフォルト拒否）で動作します。\n\n## Features\n\n- **MCP Proxy**: MCP over HTTP/SSE リクエストの透過的な中継\n- **OAuth2 Token Validation**: ORY Hydra 連携による Bearer トークン検証\n- **Tool-level Authorization**: OPA によるツール呼び出し粒度の認可ポリシー評価（fail-close: OPA到達不能時はデフォルト拒否）\n- **Audit Logging**: 全アクセスの構造化ログ出力（ALLOW/DENY 両方を記録）\n\n## Architecture\n\n```\n[AI Agent] → [secure-mcp-gateway] → [MCP Server] → [Data Sources]\n                    ├── Token Validation (ORY Hydra)\n                    ├── Policy Evaluation (OPA)\n                    └── Audit Logging\n```\n\n## Tech Stack\n\n- Go (proxy layer, ORY Go SDK)\n- gRPC / Protocol Buffers (internal communication)\n- ORY Hydra (OAuth2/OIDC)\n- OPA (policy engine)\n\n## Quick Start\n\n### Prerequisites\n\n- Go 1.24+\n- Docker & Docker Compose\n- (Optional) [golangci-lint](https://golangci-lint.run/), [gofumpt](https://github.com/mvdan/gofumpt)\n\n### 1. Clone & Setup\n\n```bash\ngit clone https://github.com/akaitigo/secure-mcp-gateway.git\ncd secure-mcp-gateway\ncp .env.example .env\n```\n\n### 2. Start Dependencies\n\nDocker Compose starts ORY Hydra (OAuth2), OPA (policy engine), and a mock MCP server:\n\n```bash\ndocker compose up -d\n\n# Verify all services are healthy\ndocker compose ps\n# Expected: hydra, opa, mock-mcp all \"running\"\n```\n\n| Service | Port | Purpose |\n|---------|------|---------|\n| ORY Hydra (Public) | `4444` | OAuth2 token endpoint |\n| ORY Hydra (Admin) | `4445` | Token introspection |\n| OPA | `8181` | Policy evaluation (tool-level authorization) |\n| Mock MCP Server | `3001` | Upstream MCP (dev only) |\n\n### 3. Build & Run\n\n```bash\n# Build\nmake build\n\n# Run the gateway\n./secure-mcp-gateway\n# Proxy listens on :8080, gRPC on :9090\n```\n\n### 4. Create a Test Token & Send a Request\n\n```bash\n# Create an OAuth2 client in Hydra\ndocker compose exec hydra hydra create oauth2-client \\\n  --endpoint http://localhost:4445 \\\n  --grant-type client_credentials \\\n  --scope tools:read,tools:call \\\n  --format json\n\n# Request a token (replace CLIENT_ID and CLIENT_SECRET from the output above)\nTOKEN=$(curl -s -X POST http://localhost:4444/oauth2/token \\\n  -u \"$CLIENT_ID:$CLIENT_SECRET\" \\\n  -d grant_type=client_credentials \\\n  -d scope=\"tools:read tools:call\" | jq -r .access_token)\n\n# Call the gateway with the token\ncurl -s -X POST http://localhost:8080/ \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/list\"}' | jq\n```\n\n### 5. Try Tool-level Authorization\n\nツール呼び出し（`tools/call`）はOPAポリシーで許可されたクライアント×ツールの組み合わせのみ通過します。許可リストは [`policies/data.json`](policies/data.json) で管理します:\n\n```json\n{\n  \"gateway\": {\n    \"permissions\": {\n      \"demo-agent\": [\"mock-tool\"]\n    }\n  }\n}\n```\n\n```bash\n# 許可されたツール（data.jsonでclient_idに付与済み）→ 200 OK\ncurl -s -X POST http://localhost:8080/ \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"mock-tool\"}}' | jq\n\n# 許可されていないツール → 403 Forbidden (\"denied by policy\")\ncurl -s -X POST http://localhost:8080/ \\\n  -H \"Content-Type: application/json\" \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"secret-tool\"}}' | jq\n```\n\nポリシーの変更は `policies/` のRego/JSONを編集してOPAを再起動（`docker compose restart opa`）するだけで反映され、ゲートウェイの再デプロイは不要です。\n\n### 6. Run Tests\n\n```bash\n# Unit + integration tests with race detector\nmake test\n\n# Rego policy unit tests (Docker)\nmake policy-test\n\n# Full check (format -> tidy -> lint -> test -> build)\nmake check\n```\n\n## Policy Configuration\n\n- [`policies/default.rego`](policies/default.rego) — 認可ルール本体。デフォルト拒否で、`initialize` / `tools/list` などのディスカバリ系メソッドは認証済みクライアントに許可、`tools/call` は `data.json` の許可リストに一致した場合のみ許可\n- [`policies/data.json`](policies/data.json) — クライアントID→許可ツール名のマッピング。`\"*\"` で全ツール許可\n- [`policies/default_test.rego`](policies/default_test.rego) — ポリシーのユニットテスト（`make policy-test`）\n\n**Fail-close**: OPAが停止・到達不能・ポリシー未ロードの場合、ゲートウェイは全リクエストを `403 Forbidden` で拒否します。セキュリティゲートウェイとしてfail-openにはなりません。\n\n## Environment Variables\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `HYDRA_ADMIN_URL` | Yes | - | ORY Hydra Admin API URL |\n| `OPA_URL` | Yes | - | OPA server base URL for policy evaluation |\n| `UPSTREAM_MCP_URL` | Yes | - | Upstream MCP server URL |\n| `PROXY_LISTEN_ADDR` | No | `:8080` | HTTP proxy listen address |\n| `AUDIT_LOG_PATH` | No | `stdout` | Audit log output path (file path or `stdout`) |\n| `GRPC_LISTEN_ADDR` | No | `:9090` | gRPC management API listen address |\n\n> **NOTE**: Authentication, authorization, and audit logging must be properly configured before production use.\n\n## Architecture Decision Records\n\nKey design decisions are documented in [`docs/adr/`](docs/adr/):\n\n- [ADR-001: MCP Transport Layer](docs/adr/0001-mcp-transport-layer.md) — HTTP/SSE を採用した理由\n- [ADR-002: Policy Engine](docs/adr/0002-policy-engine-opa.md) — OPA を採用した理由\n- [ADR-003: MVP OPA Deferred](docs/adr/0003-mvp-opa-deferred.md) — MVPではOPAポリシー評価を未実装とした決定（Superseded: Phase 2で実装済み）\n\n## Development\n\n```bash\n# Install tools\nbash .claude/startup.sh\n\n# Lint\nmake lint\n\n# Format\nmake format\n\n# Quality gate (before ship)\nmake quality\n```\n\n## License\n\nMIT\n"}