feat(auth): drop test-client defaults, add ALLOWED_MGMT_CLIENT allowlist

Both auth surfaces now fail-closed by default:

- ALLOWED_MCP_CLIENTS: removed the silent `claude-desktop` and
  `test-mcp-client` fallbacks. Empty/unset env var leaves the registry
  empty so /oauth/authorize rejects every client_id.
- ALLOWED_MGMT_CLIENT (new): comma-separated list of OIDC client_ids
  whose tokens are accepted by /api/management/*. Enforced in
  verify_token_for_management_api on both the cache-hit and cache-miss
  paths against the token's client_id claim. Unset/empty rejects all.

Compose: set ALLOWED_MGMT_CLIENT=nextcloudMcpServerUIPublicClient on
mcp-multi-user-basic so the existing Astrolabe integration test
(test_astrolabe_chunk_context.py) still passes.

env.sample documents both vars and notes they may be consolidated later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Chris Coutinho
2026-04-30 01:20:21 +02:00
co-authored by Claude Opus 4.7
parent 2bd1c18b43
commit bd7702ad12
6 changed files with 207 additions and 53 deletions
+25
View File
@@ -119,6 +119,31 @@ NEXTCLOUD_PASSWORD=
# Optional features (semantic search, document processing):
# See "Optional Features" section below
# ============================================
# OAUTH CLIENT ALLOWLISTS (OAuth modes)
# ============================================
# Both env vars are FAIL-CLOSED: if unset/empty, the corresponding auth route
# rejects every request. There are no built-in defaults.
#
# Note: ALLOWED_MCP_CLIENTS and ALLOWED_MGMT_CLIENT are currently separate to
# keep the MCP-route and management-API auth surfaces independent. They may be
# consolidated into a single env var later.
# ===== ALLOWED_MCP_CLIENTS =====
# Clients allowed to use the OAuth AS proxy (/oauth/authorize, /oauth/token).
# Comma-separated. Each entry is either:
# - "client_id" → loopback redirect URIs (http://localhost:*, http://127.0.0.1:*)
# - "client_id|https://app/cb" → bind to a specific HTTPS callback
# HTTP redirect URIs are rejected unless the host is loopback (localhost/127.0.0.1/::1).
#ALLOWED_MCP_CLIENTS=claude-desktop, zed-editor, cloud-app|https://cloud.example.com/cb
# ===== ALLOWED_MGMT_CLIENT =====
# OIDC client_ids whose tokens are accepted by the management API
# (/api/management/*). Comma-separated. The token's `client_id` claim must
# match one of these entries. Typical value: the Astrolabe NC PHP app's
# OAuth client_id (ADR-018).
#ALLOWED_MGMT_CLIENT=astrolabe
# ============================================
# OPTIONAL FEATURES (All Deployment Modes)
# ============================================