This site is being rebuilt and some pages are out of date. For current details, write to reach@inorbit.hr. This notice goes away when the rebuild is done.

No analytics unless you allow it, no tracking. This site keeps in your browser the language you pick, the theme, its colour, which site you chose, the currency on the pricing page and that you closed this notice; signing in adds session cookies. The legal page has the details.

Sign in

← Back to Platform

RFC 0018open2026-10-02

Connections

One place to connect the platform to the outside world, apps, webhooks, MCP servers and blockchain nodes of your own, with credentials the model never sees, actions it may only take within a grant, and node answers checked rather than trusted; the trust boundary between the platform and every system outside it.

Problem

An avatar that does a job needs to reach the job (RFC 0017). The on-call avatar needs the metrics, the alerts, the chat where the incident runs and the place where the fix is deployed. A tutor needs the course. A site's avatar needs its knowledge and its payments. A synthetic user needs the product it is testing. Without a way to connect those, an avatar is a voice with nothing to do.

The platform reaches outside today, but only for itself:

  • Finance links a mailbox and e-invoicing services per person, with credentials sealed in its own store. It is the best pattern we have, and it lives inside one service.
  • Discord, DNS and Radar use tokens that belong to the operator, set once in the cluster's secrets. Nobody else can connect anything.
  • The EVM lab reads five public chains through upstream nodes the operator chose. You cannot point it at your own node.
  • Agents' tools are a fixed list in a file (RFC 0011), and every tool calls one of our own services.

Meanwhile the rest of the industry has settled on a shape. Zapier connects about 9,000 apps and now offers them to any agent over MCP, keeping the app credentials in its own layer so they never reach the model (zapier.com/mcp). Workday agreed to buy Pipedream and its 3,000 connectors in November 2025 (Pipedream); Arcade raised $60M in June 2026 to do one thing, sign agents in to apps on a person's behalf (Arcade). The common design: the person signs in to an app once, a broker keeps and refreshes the token, and the agent gets actions, never the credential.

The failures have a shape too:

  • Data flows where it should not. A malicious public GitHub issue made an agent with the GitHub MCP server copy private repository data into a public pull request (Invariant Labs). Private data, untrusted input and a way out, in one agent, is enough.
  • Connectors leak across customers. A logic flaw in Asana's MCP server exposed data between organisations for about a month in 2025 (BleepingComputer).
  • Connectors change under you. The first malicious MCP server found in the wild was a mail package that, from one version on, quietly copied every mail it sent to an outside address (The Hacker News).
  • A URL you are given is an attack. Any feature that fetches a user-supplied URL can be turned against the network it runs in; an OAuth token URL in Budibase reached cloud metadata this way (GHSA-4q6h-8p4v-67vq).
  • A node can lie. In April 2026 attackers poisoned the nodes a bridge's single verifier read from, while knocking out the honest ones, and the verifier accepted a burn that never happened: about $292M (Chainalysis). Asking one node whether something happened is asking to be told what someone wants you to believe.

So the question is how to let people connect anything, including nodes of their own, without making the platform the weakest link of everything they connect.

Proposal

A connection is a link to one outside system, owned by an account or a team. It has a kind, the credentials or address it needs, the permissions it was granted, a health status and a history of every use. You make it in the console under a new Connections section, test it, rename it, pause it and delete it there, or over the API. A new service holds connections; other services ask it to act, they never hold credentials themselves.

Where a connection runs is part of it. Every connection names its executor: our cloud, for apps and public endpoints, or later a data plane, a component a customer runs inside their own network that dials out to the platform and performs actions there. The connection, its grants and its audit trail are the same object either way; only the place the call starts from differs. That is how one design serves a Slack workspace and a metrics API that exists only inside a bank's network.

The address rules below are the cloud executor's. On a data plane, private addresses are exactly what a connection is for, so the rule there is the customer's own allowlist of networks, enforced by the data plane and shown in its local admin, not ours.

On a data plane the credential can stay in the company too: the connection holds a reference to the company's own secret store, which the data plane resolves at the moment of the call, and the secret never reaches us (RFC 0029). That is the default for connections a data plane runs; the vault below is for those our cloud runs.

A diagram is drawn here in the RFCs product; this page does not show diagrams yet.

Kinds as data

What a connection can be is a registry of kinds, each one a file and one line, as finance's connectors are already. A kind declares how it authenticates, what it can read, what it can do and what each action risks. Five shapes cover almost everything:

Shape For How it authenticates
An app Slack, GitHub, Google Calendar, a mailbox, an incident tool OAuth 2.1 with PKCE, refresh tokens rotated; or an API key the app issues
A webhook in anything that can send an event: alerts, payments, deploys, forms a signing secret we issue, verified per the Standard Webhooks spec
An endpoint a metrics or logs API, a feed, any HTTP API a key or none, with the address checked before every call
An MCP server the long tail of tools, Zapier's 9,000 apps among them OAuth as the MCP authorization spec requires
A blockchain node the chains we support, or your own node by its RPC URL the URL itself, often carrying a key, kept as a secret

The credential never leaves the vault

  • Credentials are sealed with a key per connection, which is itself sealed with a key only the connections service holds; the sealed blob is bound to its connection, so a copy moved to another row does not open. This is finance's pattern, widened.
  • Only the connections service opens a credential, for one call, and never returns it. An avatar, an agent, a flow or a person's API call asks for an action; the service performs it. The model never sees a token, and no token appears in a log, a trace, a URL or an error.
  • Tokens are refreshed as the app's rules allow and a refused refresh marks the connection for re-linking rather than retrying forever. Following the OAuth security best current practice (RFC 9700), we ask for the narrowest scopes and ask again, with the person's consent, only when an action needs more.
  • Exported connections list what is connected and how it is configured, never a secret. On the new platform a person signs in to each app again. That is also what the EU Data Act expects of switching between cloud services.

Using a connection is granted, one action at a time

A connection does nothing by itself. Its owner grants a consumer (an avatar, an agent, a flow, an API token) a named subset of its actions. Every action has a class:

Class Example Rule
Read list alerts, read a channel, eth_getBalance granted per action
Write, reversible post a message, open an issue, scale a deployment back granted per action; an avatar uses it only at the rung that allows it (RFC 0017)
Write, irreversible send mail to a stranger, delete, pay needs a person's approval for every use

The default is nothing. A grant names the connection, the actions and an expiry; it can be revoked in a click and the revocation holds within seconds, as tokens do (RFC 0016). Every use is recorded as who, which connection, which action and the outcome, never the content.

One rule against the trifecta. A consumer that reads untrusted input (a webhook payload, a public issue, a log line, an outside web page) and reads private data may not also hold an action that sends data out without approval. The platform enforces it when a grant is made, not when an incident is written up. Everything a connection brings in is untrusted, and passes through the shield (RFC 0003) before a model reads it.

Actions become tools, everywhere at once

Each granted action is a typed tool with a schema, the same definition that validates the model's arguments, as our own tools are. An avatar or agent sees exactly its granted actions; the same actions appear over the API and over our MCP server (RFC 0005) for the same caller, with the same grants. Calling one spends units from the account's one budget (RFC 0015).

Outside MCP servers, pinned

An outside MCP server is a connection like any other, with three additions:

  • We follow the current MCP authorization spec, revised on 2026-07-28: OAuth 2.1 with PKCE, the token bound to the it was issued for, client identity by a metadata document rather than dynamic registration, and never passing a token received for one service on to another (MCP blog, authorization).
  • When a person connects a server, we record each tool's name, description and schema. If the server later changes any of them, the changed tools are switched off until the owner reviews the difference. A tool cannot quietly become a different tool.
  • The server's address passes the same checks as an endpoint's.

Zapier's MCP server is the pragmatic answer to the long tail: one connection, thousands of apps, each tool still pinned and granted. It is also a third party holding the app credentials, so it is the person's choice and is named as such.

Webhooks in, and triggers

A webhook connection gives a URL and a signing secret. We verify the signature in constant time, refuse old timestamps, drop duplicates by event id and accept several signatures at once so the secret can rotate without a gap, as the Standard Webhooks spec describes (spec). The payload is untrusted input.

A trigger turns an event into work: a webhook, a schedule, a poll, or a chain event wakes an avatar with the event attached. That is the part of Zapier we need first. Multi-step flows (when this, do that, then that) come later and only as far as avatars need them; a general workflow builder is a product of its own.

Blockchain nodes, your own included

The EVM lab already reads Ethereum, Base, Optimism and Arbitrum through two upstreams per network, tried in order, checking the chain id. A node connection opens that to everyone, and to your own nodes:

  • Pick one of ours, or bring your own URL. Yours can be a provider's endpoint with its key in the path, or a node you run.
  • The address is checked before every call, exactly as the browsing tool checks a page (RFC 0014): HTTPS only, no private, loopback, link-local or metadata addresses, the name resolved once and the connection held to the checked address, so a rebinding name cannot point us inward. A URL with a key in it is a secret and treated as one.
  • The node must be the chain it claims. We ask for the chain id when you connect and on every reconnect, and refuse a mismatch.
  • Read-only, by a method allowlist. Reading state, logs, blocks and receipts; no signing methods, no account methods. Sending a transaction someone else signed is a later, separate grant.
  • Bounded: timeouts, response size caps, requests in flight and a daily allowance, as the lab has now.

How much to believe a node is a setting, and the default is not "fully". Three levels:

Trust What we check Good for
Single the chain id; the answer is what this node says watching your own node, development
Cross-checked the head block and the answer compared against a second source, ours or another of yours; a disagreement is reported, not resolved silently anything an avatar acts on
Proven account and storage reads verified with Merkle proofs (EIP-1186) against a state root from a light client (Helios) anything with money attached

The bridge loss above came from trusting one source of truth about the chain. An avatar never acts on the Single level, and the level is shown next to every answer.

What node connections are for. Watching contracts and events as triggers; simulating a transaction in the lab against the state your node sees; and the case we care about most: putting the on-call avatar on your own nodes. Block height behind the network, peers dropping, a reorg deeper than usual, sync stalled, the RPC slower than its neighbours: a node operator's three-in-the-morning list, which an avatar can watch with a cross-checked view of the chain to compare against.

We never hold keys. Signing stays in the person's wallet. At most the platform prepares an unsigned transaction for the wallet to sign. Holding or controlling someone's private keys is custody, which in the EU needs a licence under MiCA, and which this platform will not do.

Which kinds first

The avatars decide the order:

  1. Webhook in and endpoint: alerts from any monitoring system, any HTTP API.
  2. Blockchain nodes, ours and your own, with the Single and Cross-checked levels.
  3. Chat: Slack and Discord, where an incident runs.
  4. Code and deploys: GitHub.
  5. Outside MCP servers, pinned, which covers the long tail through Zapier and others.
  6. Mail and calendars, sending only at first. Google classes sending mail as a sensitive scope but reading it as restricted, and restricted scopes need a yearly security assessment (Google).

Finance's mailbox and e-invoicing links move onto connections once the service has proven itself, so there is one vault, not two.

Rules in the platform

  • Deny by default: a connection grants nothing until its owner grants an action, and a grant expires.
  • Credentials only in the vault; never in a model's context, a log, a URL or an error.
  • Every use audited as who, what and outcome, never content; a person sees their connections' history in the console.
  • Deleting an account deletes its connections and revokes their tokens at the app where the app allows it; erasure reaches every copy.
  • Every outside service a person connects through us, and every provider we use to serve connections, is listed as a sub-processor where it processes their data. Banks among our customers must list them in their own registers of ICT providers, so the list is public and current.
  • No card data passes through a connection we offer, and no connection kind is built for health records.

The order of work

  1. The connections service: the vault, the kinds registry, grants, the audit trail, the console's Connections section and the API, with new token scopes for reading and using connections.
  2. Webhooks in and endpoints, with triggers that wake an avatar.
  3. Blockchain nodes: ours and yours, Single and Cross-checked, the lab reading through them.
  4. Apps over OAuth: chat and code first.
  5. Outside MCP servers with pinning.
  6. The Proven level for node reads, once the light client reaches a stable release.
  7. Flows, only as far as avatars need them; finance's links move over.

Alternatives considered

Use a hosted integration platform. Zapier, Composio or Arcade would give us thousands of apps tomorrow. Each would hold our customers' tokens and see their data, making it a sub-processor in every customer's records and a dependency banks must plan an exit from. We offer Zapier's MCP server as one kind a person may choose, not as the foundation.

Self-host an open broker. Nango is the closest fit: self-hostable, unified OAuth. Its licence (Elastic 2.0) forbids offering it as a service, and its free self-hosted edition covers authentication and a proxy, not syncs or webhooks (Nango). We already run the hard part, sealed per-person credentials with refresh, in finance. Widening that is less work than adopting a broker whose licence limits what we may sell.

n8n as the flow engine. Popular and capable. Its licence forbids offering it hosted to others, which is exactly what we would be doing.

Keep connectors per service. It is what we have. Every new service would build a vault, and every vault is one more place a key can leak.

Trust whatever node a person gives us. Simplest, and what most tools do. Harmless for reading your own node; dangerous the moment an avatar acts on the answer.

Let agents hold credentials directly. It is what most early agent tools did, and the reason for the production deletions in RFC 0017. A credential in a model's context can be talked out of it.

Decision

Open. The direction proposed: one connections service with a vault the model never sees, actions granted one at a time with classes that decide approval, outside MCP servers pinned, webhooks verified, and blockchain nodes, our own and yours, checked for what chain they are and cross-checked before anything acts on them. It is the prerequisite for avatars that do a job (RFC 0017), and its first two steps come before the on-call avatar reads anything that is not ours.

Publication

When connections open, the console gains a Connections section, the developer docs a page per kind with what it can read and do and what each action risks, and the API reference the connection endpoints and their scopes. The sub-processor list is published with the first kind that needs one.

Status log

  • 2026-10-02: opened as the prerequisite for avatars, after research into integration platforms, the current MCP authorization spec, connector incidents of 2025 and 2026, and how much a blockchain node can be trusted.
  • 2026-10-02: a connection names its executor, our cloud or a customer's data plane, so private networks are reachable later without a second design; reframed as the trust boundary between the platform and the outside, which avatars need but do not own. Outbound events are RFC 0022.
  • 2026-10-03: the data plane is the agent (RFC 0029); connections it runs hold a reference to the company's own secret store instead of a sealed secret, and services under test are connections whose actions are checks, load and faults (RFC 0031).
  • 2026-10-03: the first step is built. A connections service holds connections owned by an account, with kinds as data. The first two kinds are an HTTPS endpoint (a check with an expectation, and a bounded read) and a webhook in (Standard Webhooks signatures, each message kept as a trigger id, never its body).
    • The vault. Each connection's credential is sealed under a key of its own, and that key is sealed under a service key that lives only in the cluster's secrets. Both are bound to the connection.
    • Agent connections. A connection an agent runs holds only a reference to the company's own secret store.
    • Grants. A grant names a consumer, the actions and an expiry. Deny by default. The rule against the trifecta is checked when the grant is made. Revoking holds at the next call.
    • Cloud calls. The cloud calls only public addresses, pinned and without redirects, and only hosts inside a domain the account has verified (RFC 0030).
    • Every use is a history row and one audit line: who, which action, the outcome.
    • Around it: three new scopes (connections:read, :write, :use), events for every change and trigger, granted actions as typed tools over the API and MCP, and a Connections section in the console.
    • Not yet: approvals for irreversible actions.
    • Agents. A connection can name an agent of the account as its executor (RFC 0029). Its checks then run there, with the credential's reference passed through unread.
  • 2026-10-03: the public writes honour Idempotency-Key (RFC 0033). Creating a connection or a grant, testing, and calling an action or a tool happen once per key, so a retried action never reaches the outside system twice. The stored answer is sealed with the vault's service key, because it can hold a secret or a third party's data.
  • 2026-10-03: a connection's check can be kept running as a monitor (RFC 0037): a shared scheduler runs it through the same executor, keeps each run's outcome 90 days (never a body), and pauses the monitor when the setup goes wrong.
  • 2026-10-04: connections become a product with a connector catalogue (RFC 0044). Apps are described as data and reached only at their own declared hosts, so incident.io, PagerDuty, Datadog, Cloud and Discord can be connected with a key; a provider that refuses a key marks the connection for reconnecting; products of the platform can be granted a connection's actions. OAuth, the GitHub App and triggers follow there.
  • 2026-10-07: Checked: the connections service (#146) and the connector catalogue (RFC 0044: #226, #246) run in connections at dab02d1a. Approvals by action class, which RFC 0074.5 waits on, are not built. Open.

← Back to Platform