CONNECTOR.md.
You do not choose a tier directly. You author custody, kind, and target, and
ConnectionSnapshot::tier() reads them back — see
Connectors overview for the derivation. The table below tells you
which triple to write.
Governing ADRs: 0020 (three tiers, ConnectorBundle; superseded in part by 0030),
0024 (worker protocol, accepted-not-implemented; parked by ADR-0058), 0030
(federated catalogs as primary coverage, Proposed — but its authoring rules already bind
through AGENTS.md invariant 9 and PRD §6), 0025 (per-source evidence trust,
Proposed).
Gate 0 — risk class, before the table
Run this first. It decides which half of the table you are allowed to land in. Otherwise, for long-tail breadth, prefer federated. ADR-0030 adopts Nango and Composio as v1 brokers and makes federation the primary path to breadth. Building a native or worker connector for a long-tail vendor is the treadmill ADR-0020 and PRD §6 both forbid. Federation is cheap coverage bought with evidence. ADR-0030 states the price exactly: for a purely federated invocation with no asynchronous stage, the fraction of receipts that can ever readverified is exactly zero, enforced at validation time. Do not
federate anything whose value is the receipt.
The decision table
Ordered. First match wins. Answer each row from the vendor brief produced by research, not from memory — walking it from memory is how a form-encoded body or an OAuth-only vendor gets discovered after the tier is recorded.1
Does a third party hold the vendor credential and execute the call?
Nango, Composio, another catalog, or a customer-run server. If yes → federated, stop.Author
custody: federated, kind: catalog_remote, broker_ref set. Obol stores only a
workspace-scoped upstream credential or an account-scoped reference. Pooled broker
accounts and a shared broker OAuth app are forbidden (invariant
8, ADR-0030) — a federated connection uses the customer’s own
OAuth client.2
Is the surface an MCP server rather than an HTTP API?
If yes → federated, stop, even when Obol vaults the MCP bearer token.Author
target: mcp_remote. tier()’s own doc comment puts it plainly: remote MCP is
federated even when Obol vaults the MCP bearer, because the upstream still owns the
vendor connection. RemoteMcpExecutor stamps EvidenceTrust::Untrusted and returns no
numeric vendor status and no upstream id
(apps/gateway/crates/obol-mcp/src/relay/mod.rs).3
Can every tool be one bounded HTTP request mapped by JSON Schema?
One request whose arguments map to path, query, header, or body by JSON Schema, against
a declared host allowlist, with Obol holding the vaulted credential. If yes → native.Author
kind: openapi, target: open_api, custody: obol. This is the strongest
observation boundary: OpenApiExecutor stamps EvidenceTrust::GatewayObserved. See
Native connectors.Fixed GraphQL is native: declare N POST /graphql operations with the query document
pinned in the bundle body and arguments filling variables. It is not a worker reason.4
Otherwise: is it exactly one of these four?
(a) a mandatory 2–4 step sequence, (b) cursor pagination that must be joined server-side
into one result, (c) a response shape needing a stable mapping, or (d) a request shape
OpenAPI genuinely cannot express. If yes → trusted worker.Author
target: worker, custody: obol. Under ADR-0024 the worker would plan and
normalize and the gateway would perform the credentialed HTTP. That protocol is not
implemented and there is no worker deployable, so choosing this tier today means
proposing to build one, not adding to something running. The shipped executor would still pass the credential to the
worker (ADR-0014). See Trusted workers.5
None of the above
Stop. Propose a new ADR. ADR-0024: unsupported signing or native-SDK behavior stays a
reviewed exception requiring a new ADR, not a raw secret hand-off.
What is no longer a reason to write a worker
ADR-0007 and older guidance predate ADRs 0020–0024. Each of the following is gateway-owned by decision; none justifies tier 2.What each tier costs and buys
The trusted-worker column mixes the ADR-0024 target with today’s compiled executor. That protocol is not implemented. On the shipped ADR-0014 pathWorkerExecutor
stamps connector_attested on the whole observation, and there is no worker deployable.
See Trusted workers.
The routing ceiling row is enforced, not advisory:
apps/gateway/crates/obol-types/src/routing.rs computes the maximum trust per tier and
excludes any binding whose declared evidence_ceiling exceeds it, with reason
EvidenceFloor.
Guardrails
- Hand-written workers are capped at five, each with a named reviewer. A sixth proposal is a scope conversation, not an authoring task.
- Federated tools still execute. A remote MCP server can run a destructive tool; its
result is simply never
verified. Gate those with Cedar and approvals, and render them as executed — not verified rather than as a green check. - Freeze federated schemas. Remote MCP tool lists are introspected once and frozen into a reviewed workspace snapshot, never trusted to change during a call (ADR-0020). Re-introspect on a schedule and land drift as a reviewed republication, never a hot swap. New tools arrive invisible until policy names them.
- Revocation is two-step for federated connections and must be disclosed as such: Obol-key revocation covers the Obol hop only; control must call the broker’s disconnect API (ADR-0030).
- Namespacing (ADR-0015):
{connector}.{tool}, split on the first dot. Connector prefixes are validated dot-free and[a-z0-9_-]; upstream names may contain dots (stripe.charges.list→ connectorstripe, upstreamcharges.list). Identities are capped at 256 characters.
Known vendor blockers
- AWS (S3, SQS, SigV4) breaks the ADR-0024 model. SigV4 signs a canonical request
with the secret, which a worker must never receive under ADR-0024. That protocol is
not implemented; on the shipped path the worker would receive the secret (ADR-0014).
Either the gateway gains an
AwsSigV4auth profile — a bounded standard scheme — or AWS is unsupported. Both need a decision on the record; neither is a secret hand-off. - Composio is barred from the destructive path (ADR-0030). Its credential custody is
closed on every tier, so hybrid custody is structurally unavailable, and its normal
execution path returns a computed
successfulboolean with no vendor status and no typed vendor object id. Use it as a read-biased long-tail source only. - Nango requires the
proxy-forward-all-response-headersaccount flag — ADR-0030 calls it a contractual precondition, not a configuration detail: without it the vendor’s request id never reaches a receipt. Use Nango’s raw proxy, never its normalized action endpoint, because the proxy is the only shape that preserves the vendor’s numeric status. - Form-encoded bodies are no longer a native blocker. ADR-0034 added
body_encodingtoTargetSpec::OpenApi, the bundle, and the overlay;obol-httpxwrites bracket-nestedapplication/x-www-form-urlencoded. Stripe and Twilio ship as native packs.