Bootstrap qonto-assistant: intent, blueprint, research, workplans

Author INTENT and SCOPE; persist ArchitectureBlueprint under specs/ and MCP
gateway research under research/. Register with State Hub (QONTO-WP- prefix);
seed QONTO-WP-0001 (bootstrap, finished) and QONTO-WP-0002 (Phase 1 REST
policy kernel, ready).
This commit is contained in:
tegwick 2026-07-21 23:32:24 +02:00
parent bae0734564
commit e1ab23f83e
10 changed files with 1330 additions and 1 deletions

View file

@ -0,0 +1,172 @@
# Research: MCP gateways and governed domain assistants for bank access
> Date: 2026-07-21
> Purpose: Capture external and internal research that informed
> `specs/ArchitectureBlueprint.md` and `INTENT.md`.
> Not a product spec — evidence and pattern notes.
---
## 1. Question under investigation
How should multiple coding agents and harnesses interact with Qonto
**conveniently and under one policy**, without wiring vendor MCP into each
client (policy drift) and without relying on Qonto to enforce
read-only / no-spend rules at the API key layer?
---
## 2. Internal facts already established (BINKY-WP-0005)
| Fact | Evidence |
| --- | --- |
| Credentials live at `tenants/binky/qonto-api` | OpenBao; fields `API_KEY`, `API_USER` |
| Thirdparty REST works | First pull 2026-07-21; 122 txs; CostRunRate v2 |
| Auth shape | `Authorization: <API_USER>:<API_KEY>` |
| Self-hosted MCP env map | `API_KEY``QONTO_API_KEY`, `API_USER``QONTO_ORGANIZATION_ID` |
| API keys not scope-limited | Design note in binky-control `integrations/qonto-mcp.md` |
| Hosted OAuth MCP rejected | Corporate access policy: no native connector custody |
| Catalog / CCR | ops-warden `binky-qonto-api` active; CCR-2026-0008 active |
| Founder policy intent | No spend / no volume-cost actions for agents; payments Red lane |
---
## 3. External pattern research (20252026 MCP ecosystem)
### 3.1 MCP gateway / proxy as control plane
Industry deployments place a **gateway between untrusted MCP clients and
tools**:
| Source | Relevant capability |
| --- | --- |
| **Envoy AI Gateway MCPRoute** | Multiplex backends; `toolSelector` include/regex; upstream API-key injection so clients never hold vendor secrets; OAuth on gateway; CEL on `tools/call` params (`request.mcp.tool`, `request.mcp.params`) |
| **Kong AI Gateway MCP Tool ACLs** | Default-deny; per-consumer tool subsets at gateway (solves all-or-nothing MCP) |
| **Portkey / Speakeasy / Permit MCP Gateway** framing | Authn, RBAC, audit every tool call; policy on each call not only at connect time |
| **Harness MCP server docs** | Compatible with MCP gateways: centralized credentials, governance, audit, single endpoint |
**Lesson:** Clients connect to one governed endpoint; the gateway owns
credentials, published tool inventory, and policy.
### 3.2 MCP security best practices
Synthesized from MCP security best-practice docs and industry guides
(confused-deputy / token passthrough / OAuth proxy guidance):
| Practice | Application |
| --- | --- |
| No token passthrough | Clients must not present the bank key; assistant is sole Qonto client |
| Tool-level scopes | “Access to Qonto” too coarse; allow list_transactions, never create_transfer |
| Default deny | Unknown tools fail closed |
| JIT escalation for high privilege | Future spend only with explicit re-auth; never session-global write mode |
| Audit end-to-end | Actor + tool + decision; no secrets in logs |
| Inventory of MCP servers | Fleet must know what is connected (anti shadow-MCP) |
### 3.3 Gateway vs domain assistant
| Approach | Strength | Weakness for bank access |
| --- | --- | --- |
| Generic MCP gateway in front of **vendor** MCP | Fast tool filtering | Vendor catalog still includes write tools; weak **semantic** spend rules; unmaintained self-hosted Qonto MCP |
| **Domain assistant** (own MCP + REST, policy inside) | Safe catalog we design; dual protocol; productizable | Build cost |
| Per-client allow-lists only | Zero new service | Guaranteed policy drift |
**Conclusion adopted in blueprint:** build domain assistant; treat generic
gateways as optional later mesh in front of *our* service, not as sole
control in front of vendor MCP.
### 3.4 Anchoring policy at Qonto (API / MCP)
**Not available** for the chosen custody model:
- Self-hosted API keys: no fine-grained scopes from Qonto.
- Hosted OAuth MCP: write tools + credentials outside OpenBao = rejected
by corporate access policy.
Defense-in-depth still belongs in our choke point even if Qonto later adds
scopes.
---
## 4. Internal platform fit
| Component | Boundary (from INTENT/ADR) | Role for Qonto access |
| --- | --- | --- |
| **agent-harness** | Sole session credential holder / policy shell for *sessions*; not domain logic | Grant profile pointing at qonto-assistant only |
| **llm-connect** | Multi-provider LLM adapters | Models only — not bank tools |
| **flex-auth** | Authorization from identity claims | `finance.qonto.read` (etc.) |
| **OpenBao + ops-warden** | Custody + routing | Existing `binky-qonto-api` lane |
| **email-connect** | Purpose-built connector | Sibling pattern to copy |
| **binky-control** | Company brain / AutonomyPolicy | Policy source + CostRunRate consumer |
| **activity-core** | Schedule, not execute | When Finance Steward runs |
ADR-001 (agent-harness) implies: instances declare profiles; harness
enforces. Domain bank rules must live **below** the harness so interactive
IDE agents and unattended sessions share one policy.
---
## 5. Founder constraints captured in research session
1. Multiple coding agents and harnesses already in use; agent-harness +
llm-connect exist.
2. Desired policy: **no spending**, **no actions with volume cost**.
3. Direct per-harness MCP wiring is suboptimal (policy drift).
4. Preference to explore **qonto-proxy / governed API+MCP service**.
5. Interest in known agentic patterns — research above.
---
## 6. Architectural recommendation (outcome)
See `specs/ArchitectureBlueprint.md` in full. Summary:
```text
Many harnesses
→ authenticate to qonto-assistant (MCP and/or REST)
→ policy kernel (default-deny, no spend / no volume-cost)
→ sole OpenBao consumer of tenants/.../qonto-api
→ Qonto thirdparty API
```
Phased delivery:
0. Custody + first REST pull (done in binky-control)
1. Policy kernel + REST
2. MCP surface for all harnesses
3. flex-auth + rate limits
4. Multi-tenant / productization
---
## 7. Open questions carried into work planning
1. Repo runtime stack (Python FastAPI vs other) — decide in first
implementation workplan, not in research.
2. Whether vendor MCP is ever an internal backend (default: **no**; prefer
direct REST client).
3. AppRole for assistant-only secret fetch vs OIDC role only.
4. IBAN / PII redaction levels for agent channels.
---
## 8. Source index (non-exhaustive)
### Internal paths
- `binky-control/integrations/qonto-mcp.md`
- `binky-control/integrations/qonto-governed-assistant/ArchitectureBlueprint.md` (origin copy)
- `binky-control/finance/CostRunRate.md`, `finance/qonto-first-pull-2026-07-21.json`
- `agent-harness/INTENT.md`, `docs/adr/ADR-001-agent-harness-architecture.md`
- `llm-connect/ARCHITECTURE-LAYERS.md`
- `flex-auth/INTENT.md`
- ops-warden catalog entry `binky-qonto-api`; railiance-platform CCR-2026-0008
### External (retrieved 2026-07-21)
- Envoy AI Gateway MCP documentation (MCPRoute, toolSelector, authorization CEL)
- Kong AI Gateway MCP Tool ACLs product notes
- MCP gateway explainers (Speakeasy, Portkey, Permit, community)
- MCP security best practices (token passthrough, proxy consent, tool-level scopes)
- CSA / industry agentic MCP security maturity notes
- Harness MCP server gateway compatibility notes
- GitHub `qonto/qonto-mcp-server` README (env vars; maintained status warning for local server)