QONTO-WP-0003-T03: MCP client auth + shared multi-harness config snippet
Gate /mcp with a shared-secret bearer token (QONTO_ASSISTANT_MCP_TOKEN,
mcp_auth.py::BearerTokenAuthMiddleware, constant-time compare, REST
untouched) since no OIDC issuer exists in this fleet yet -- pointing
FastMCP's OAuth Protected Resource flow at a non-existent issuer would be
worse than not having it. This token is a service credential, never a bank
credential; per-actor identity stays the existing X-Actor-* convention.
Add docs/mcp-integration.md: tool catalog, the two-layer auth model (workload
auth today vs. deferred OIDC target), and one shared {"mcpServers": {...}}
client config snippet (url + headers) usable across Claude Code, Claude
Desktop, Cursor, and Codex/Grok-style harnesses.
Verified live using only that snippet: unauthenticated and wrong-token
requests get 401 before reaching any tool; a request built from the
snippet's URL + headers lists tools and calls qonto_org_summary
successfully against the fixture-backed server.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e1e47ae304
commit
d2ffd372b5
9 changed files with 259 additions and 5 deletions
|
|
@ -122,7 +122,7 @@ REST. `pytest` → `25 passed`; `python3 -m compileall src tests scripts`.
|
|||
|
||||
```task
|
||||
id: QONTO-WP-0003-T03
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "ad43b09a-ffa5-4df0-8999-bfcef1f11732"
|
||||
```
|
||||
|
|
@ -137,6 +137,40 @@ Done when: the snippet is in `docs/operator-runbook.md` (or a new
|
|||
`docs/mcp-integration.md`), and a local smoke connects a real MCP client
|
||||
against the running adapter using only that snippet.
|
||||
|
||||
**Done 2026-07-23 — with a scoped gap, called out explicitly:** No OIDC
|
||||
issuer exists anywhere in this fleet yet, so standing up real
|
||||
OIDC/workload-identity federation isn't something this repo can do alone —
|
||||
implementing it would mean pointing `FastMCP`'s OAuth Protected Resource
|
||||
flow at an issuer URL that doesn't serve real metadata, which is worse than
|
||||
not having it. Shipped the deployable primitive instead: a shared-secret
|
||||
bearer token (`QONTO_ASSISTANT_MCP_TOKEN`), enforced by
|
||||
`src/qonto_assistant/mcp_auth.py::BearerTokenAuthMiddleware` in front of
|
||||
`/mcp` only (REST untouched). Unset by default (fixture/local smoke stays
|
||||
credential-free); when set, every non-matching or missing
|
||||
`Authorization: Bearer <token>` gets `401 {"error_code": "unauthorized"}`
|
||||
before reaching any tool or the policy kernel. Constant-time comparison
|
||||
(`hmac.compare_digest`). This token is a **service credential, not a bank
|
||||
credential** — never logged, never reaches Qonto. Per-actor identity is
|
||||
still the self-asserted `X-Actor-*` header convention (not yet
|
||||
cryptographically bound to the bearer token — that binding is Phase 3's
|
||||
flex-auth resource `finance.qonto.read`, not this task).
|
||||
|
||||
Added `docs/mcp-integration.md`: tool table, the two-layer auth model
|
||||
explained (workload auth today vs. the OIDC target and why it's deferred),
|
||||
and the one shared `{"mcpServers": {...}}` config snippet (`url` + `headers`
|
||||
— the convention shared by Claude Code, Claude Desktop, Cursor, and
|
||||
Codex/Grok-style harnesses for remote streamable-HTTP MCP servers).
|
||||
|
||||
Verified live, exactly as the doc's smoke section describes: started the
|
||||
service with `QONTO_ASSISTANT_MCP_TOKEN` set and `QONTO_FIXTURE_DIR` (no
|
||||
real Qonto credentials); a request with no `Authorization` header never
|
||||
reached a tool; a request with the wrong token got `401 Unauthorized` in the
|
||||
server log; a request built from *only* the doc's snippet (URL + the two
|
||||
headers) listed tools and called `qonto_org_summary` successfully, with
|
||||
`X-Actor-ID` flowing into the audit event as before. New
|
||||
`tests/test_mcp_auth.py` covers missing/wrong/matching token cases directly.
|
||||
`pytest` → `28 passed`; `python3 -m compileall src tests scripts`.
|
||||
|
||||
## Task: agent-harness tool profile `finance-qonto-read`
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue