5.6 KiB
INTENT
This file explains why qonto-assistant exists — the problem it solves, the principle that governs its boundaries, and what it must never become. Blueprint:
specs/ArchitectureBlueprint.md. Origin: binky-control BINKY-WP-0005 (Qonto custody + first read-only pull) and the multi-harness policy-drift problem (2026-07-21).
Why it exists
Binky (and later other tenants) need agents to see bank reality —
balances, transactions, cost-run-rate signals — so the company control plane
can operate without founder spreadsheet archaeology. Credentials already live
in OpenBao (tenants/binky/qonto-api); the thirdparty REST API works.
What fails as scale:
- Wiring vendor MCP or bank keys into every coding agent / harness (Claude, Codex, Cursor, Grok, agent-harness, …) creates policy drift.
- Qonto API keys are not scope-limited server-side: there is no “read-only key.” Spend and volume-cost actions must be blocked before the vendor sees them.
- Agent-harness is the session policy shell, not the place to reimplement bank rules per runtime. llm-connect is LLM routing, not domain tools.
qonto-assistant exists so that one governed domain service is the only component allowed to hold the bank credential and speak Qonto’s protocol. All harnesses are clients of that service. Policy is code + tests in one place.
Purpose
qonto-assistant is a policy-governed Qonto domain assistant: a dual
surface (REST + MCP) for agentic and scripted finance awareness under a
hard no spend / no volume-cost policy (v1).
Core principle:
Harnesses never hold the bank key. The assistant is the choke point. Default deny. Reads for control-plane awareness; payments stay Red lane (human in the Qonto app).
Primary utility
As a multi-harness finance tool
- Streamable-HTTP MCP for interactive agents (one client config, no secrets in MCP configs).
- Stable REST for rhythm sessions, CostRunRate refresh, CI smoke, and non-MCP clients.
- Shared policy kernel on every call (tool id + arguments + actor claims) — not connect-time allow-lists alone.
As a custody-aware connector
- Fetches secrets only via the sanctioned OpenBao path (ops-warden catalog
binky-qonto-api/ CCR-2026-0008 pattern). - Optional flex-auth gate:
finance.qonto.read(and later finer scopes). - Audit metadata (who/what/decision) without logging secret material.
As dogfood for Operational Knowledge
- Internal use on Binky is product evidence (governed bank access for agent
fleets). May graduate to multi-tenant
tenants/<slug>/qonto-apilater.
Strategic role
OpenBao custody (existing)
+ sole Qonto client identity
+ default-deny tool catalog
+ dual MCP + REST
= consistent finance awareness across every harness
It sits below agent-harness (session runtime) and beside other domain connectors (email-connect). It does not replace DATEV/StB/DUO; it complements them with operational bank visibility.
Governing principles
- One policy, many clients — never reimplement bank rules per harness.
- Default deny — only explicitly allowed read capabilities exist in v1.
- No token passthrough — clients authenticate to the assistant; the assistant alone authenticates to Qonto.
- Semantic policy, not vendor dump — we design a safe catalog; we do not auto-mirror vendor write tools.
- Platform fit — flex-auth, OpenBao, ops-warden, State Hub evidence; no parallel IAM.
- Autonomy lanes — map to binky-control AutonomyPolicy: reads Green/Blue; plan change / transfers / API key minting remain Red.
What it must never become
- Not a payments engine. No transfers, SEPA, card issuance, or fee-bearing create operations in v1 (and only via explicit future DEC + Red/Yellow gates thereafter).
- Not a full accounting system. DATEV / StB / DUO stay authoritative for books.
- Not a generic MCP gateway. Fleet gateways may sit in front later; domain policy lives here.
- Not an LLM router. Provider selection stays in llm-connect.
- Not a scheduler. Cadence stays in activity-core / agent-harness.
- Not a secret store. OpenBao remains custody; this service is a short-lived consumer.
- Not a per-harness plugin bag. Client integration is thin: URL + workload identity + tool profile name.
Relationship to other repos
| Repo | Relationship |
|---|---|
binky-control |
First tenant / consumer; CostRunRate, AutonomyPolicy, business policy source |
ops-warden / railiance-platform |
Credential front door and CCR/policy for tenants/…/qonto-api |
agent-harness |
Grants profile finance-qonto-read pointing at this service only |
llm-connect |
Models that talk; this service acts on bank data |
flex-auth |
Authorization decisions for who may call |
email-connect |
Sibling pattern: purpose-built connector, not raw vendor wiring |
Success looks like
- Every agent that needs Qonto data uses only this service.
- A single policy change (e.g. tighten export) applies fleet-wide.
- No bank API key appears in harness env, MCP client configs, or chat.
- Deny decisions are tested and audited; spend tools are not registered.
- CostRunRate and Finance Steward can refresh from REST without ad-hoc scripts holding secrets.
Normative references
specs/ArchitectureBlueprint.md— architecture and phased deliveryresearch/2026-07-21-mcp-gateway-and-governed-domain-assistant.md— external pattern research- binky-control
integrations/qonto-mcp.md— custody and first-pull evidence - agent-harness ADR-001 / INTENT — session runtime boundaries