Developer tools
Connections
Connect an account's incident, chat, code, enterprise and AI tools once, with a key or by signing in, and let products and keys act on them through a person's grant.
A connection is an account's link to one outside app: PagerDuty, Slack, Jira, an AI provider. It is made once, from a catalogue of connectors, and every product of the platform acts on it only through a grant a person gives. Design: RFC 0044, on top of RFC 0018. The console's Connections product is admins only while it is built.
The catalogue
GET /v1/connectors lists the connectors with their sign-in modes and fields (secret ones
marked), settings, actions and hosts; GET /v1/connectors/{connector_id} reads one.
| Category | Connectors |
|---|---|
| Incident | incident.io, PagerDuty (API key and routing key, or Scoped OAuth) |
| Chat | Slack, Microsoft Teams, Discord |
| Code | Linear; GitHub is coming |
| Observability | Datadog, Grafana Cloud |
| Enterprise | Jira, Confluence, ServiceNow, Okta (read only) |
| AI | Anthropic, OpenAI, Google Gemini, Mistral, Azure OpenAI, an OpenAI-compatible endpoint; Amazon Bedrock is coming |
A connector whose OAuth app is not set up on the platform yet shows as needs_app.
Connecting with a key
With connections:write, POST /v1/accounts/orgs/{org_id}/connections with the connector as
kind, its auth_mode, the mode's secret fields in credentials and the rest in config.
The connector's test runs first: a refused key stores nothing, and a passing one names the
account at the provider (label). Secrets are sealed and never answered or logged.
Connecting by signing in
For an OAuth mode, the person signs in at the provider and the platform keeps and refreshes the token:
POST /v1/accounts/orgs/{org_id}/connections/connectwithconnectorand, optionally,auth_mode,scopes,config(settings needed before signing in) andname. The answer isauthorize_url,session_idandexpires_at: a single-use session bound to the person, with its state and a PKCE (S256) verifier, valid for ten minutes.- The person opens
authorize_urland signs in. The provider sends them back to the console, which completes the sign-in as the same person. - Anything waiting on the browser reads
GET /v1/accounts/orgs/{org_id}/connections/connect/{session_id}:pending,completed(with the connection),failedorexpired. Only the person who started it may read it.
With connection_id in step 1, the sign-in reconnects that connection. A workspace is connected
once per account: connecting the same one again updates its connection.
The platform renews tokens before they expire, one refresh at a time per connection. A refused
refresh, or a provider's 401 or 403 on a call, marks the connection needs_reauth; sign in
again (or give a new key, tested first) to bring it back. Deleting a connection revokes its
token where the provider has a revocation endpoint.
Grants
A connection does nothing on its own. A person grants named actions on it, until an expiry,
to a consumer: a product of the platform (product:reliability, product:lab,
product:signals, product:llm), an API key or token of the account (key:<id>), one of the
platform's agents or an avatar. Granting is a signed-in person's, in the console or with
iohr connections grant; a token cannot grant. A grant is refused
when the consumer would then read untrusted input, read private data and hold an action that
sends data out without approval. Every use is recorded (who, which action, the outcome, never
the content). GET …/connections/{connection_id}/grants lists them and
DELETE …/grants/{grant_id} revokes one. A key calls a granted action with
connections:use, by connection or as a tool by name, over REST or
MCP.
AI providers: your own key
Anthropic, OpenAI, Google Gemini, Mistral and Azure OpenAI connect with the account's own key, and an OpenAI-compatible endpoint connects a model server the account runs, on a host inside a domain it verified. The catalogue marks them "AI model".
- Prompts go to the provider under the account's own agreement with it. We do not resell or proxy a model account.
- Nothing is sent until someone connects a provider and a person grants its
generateaction. - The answer goes back to the caller only. It is never logged or stored; only the token counts the provider reports are kept, to meter it.
Assistants
Claude Code, Cursor, GitHub Copilot and Gemini CLI use InOrbit through the MCP server with a person's own API token. They are listed in the catalogue as setup sheets, not connections: nothing is connected, the sheet says how to point the assistant at the server. ChatGPT and the custom connectors of claude.ai and Claude Desktop need OAuth sign-in on the MCP server, which is not built yet. Setup: MCP.
Scopes
| Scope | Allows |
|---|---|
connections:read | the catalogue, the account's connections, their grants and history, a sign-in's progress |
connections:write | add, change, pause, test and delete connections, start and complete a sign-in, revoke grants |
connections:use | call the actions a grant gives this key or token |
From the command line
iohr 0.1.0-alpha.7 and later (install):
iohr connectors list --category incident # what can be connected
iohr connectors show pagerduty # its modes, fields, settings and actions
iohr connections add incident-io # asks for the API key without echo
iohr connections add pagerduty --mode api_key --config region=eu.pagerduty.com \
--secret-file api_key=./pd.key # or --secret-stdin api_key < pd.key
iohr connections add slack # opens Slack in a browser, waits until done
iohr connections grant incident-io --to product:reliability --actions create_incident --expires 90d
iohr connections history incident-io --status failed
iohr connections delete incident-io # asks first; --yes in a scriptA secret field is never an argument: iohr asks for it without echo on a terminal, or reads
it from --secret-file FIELD=PATH or --secret-stdin FIELD, and never prints, logs or writes
it. Settings that are not secret go in --config KEY=VALUE. A mode that signs in opens the
provider's page in your browser, or prints the link over SSH and without a display, then asks
the connect session every 2 seconds until it completes, fails or expires.
iohr connections reconnect NAME gives a connection a new credential the same way.
Connecting and deleting need an owner or admin of the account and connections:write; grants
are made by a signed-in person, not by a token.