Concepts
Installing an agent
Run the agent in your own network, enroll it with a one-time token, and run checks on what our cloud cannot reach.
Pre-release
Agents are in development (RFC 0029). The routes below are stable; the agent's own releases are announced in the changelog.
What it is
The agent, iohr-agent, is a program you run inside your network: a container in your cluster, a service on a
machine, or iohr agent on a laptop. It opens one connection out to the API host and keeps it open. The
platform sends work down that connection and the agent sends results back. Nothing on your side listens for
the internet, so there is no inbound firewall rule to ask for.
Three rules hold for every agent:
- Your local policy wins. The agent reads a policy file on its own machine that names the networks and hosts it may reach and the work it may do. Anything outside it is refused by the agent, and the refusal is what you see.
- Bound to verified domains. An agent is enrolled for domains your account has verified. The platform
sends a check on a named host only when the host is inside one of them and the domain is still verified. A
private address or an internal name such as
db.internalcannot be proved by DNS; it goes to the agent, and its policy decides. - Results, never content. The agent reports a check's outcome: passed or failed, the latency, the HTTP
status and an error class. Never a request or response body. Credentials stay in your own secret store: a
check names a reference (
vault:<path>#<key>,k8s:<namespace>/<name>#<key>,env:<NAME>,file:<path>) that the agent resolves at the moment of the call.
Enroll
Make an enrollment token
In the console, open Agents and choose Enroll an agent, or call the API with a key that holds
agents:write:
curl -X POST https://api.inorbit.hr/v1/accounts/orgs/$ORG_ID/agents/enrollments \
-H "Authorization: Bearer $INORBIT_KEY" \
-H "Content-Type: application/json" \
-d '{"environment":"staging","domains":["example.com"],"name":"edge-1"}'The answer carries token (ioe_…). It enrolls one agent, once, within the hour, and is shown only in this
answer: the platform keeps its hash. Every domain must be verified for the account.
Install and enroll the agent
The console offers the token as a file to download (and as an .env file and Helm values).
Keep it out of the command line, where shell history and the process list would keep it.
On a machine with the command line, with the token file next to you:
iohr ext install agent
iohr agent enroll --token-file ./inorbit-agent-staging.tokenThe agent deletes the file once it has enrolled.
In a Kubernetes cluster, the token becomes a Secret and the values only name it:
kubectl create namespace inorbit-agent
kubectl -n inorbit-agent create secret generic iohr-agent-enrollment \
--from-file=token=./inorbit-agent-staging.token
helm install iohr-agent oci://ghcr.io/inorbithr/charts/iohr-agent \
--namespace inorbit-agent \
-f ./inorbit-agent-staging-values.yamlimage:
repository: ghcr.io/inorbithr/iohr-agent
environment: staging
enrollment:
existingSecret: iohr-agent-enrollment
key: tokenThe Secret is read on the first start only and may be deleted once the agent shows as online.
What enrolling does
The agent makes an EC P-256 key pair on its machine; the private key stays in a file only it reads. It
presents the token and the public key once at POST /v1/agents/enroll, the one route that takes no bearer
token: the enrollment token is the credential, and the route is rate limited per address. The answer names the
agent's agent_id and client_id, the token endpoint, the audience iohr-api and the scope
agents:session.
From then on the agent signs a short assertion with its key (ES256, RFC 7523) and trades it at the token
endpoint for a 15-minute access token. No long-lived secret sits on disk.
The session
The agent connects to wss://api.inorbit.hr/v1/agents/session with its own access token; no other token
opens it, and its token opens nothing else. Frames are JSON text:
| From | Frame | When |
|---|---|---|
| agent | hello | first: its version, the hash of its policy, its capabilities |
| platform | welcome | the agent's id and heartbeat_secs (15) |
| agent | heartbeat | every 15 seconds; three missed and the session closes |
| platform | job | a check: surface (http, tcp, tls, grpc_health), target, expect, a deadline |
| agent | result | ok, failed or refused, with the detail or the policy's reason |
| platform | cancel, revoked | a job no longer awaited; the agent was revoked and the session ends |
The agent shows as online in the console while its session is open.
Run a check
With agents:write, POST /v1/accounts/orgs/{org_id}/agents/{agent_id}/checks sends one check to an online
agent and waits up to 30 seconds for its result:
{ "target": { "url": "https://api.example.com/healthz" }, "surface": "http", "expect": { "status": 200 } }A target outside the agent's domains, or a public address with no name, is refused with 403 before
anything is sent. An offline agent answers 400 failed_precondition at once.
Revoke
POST …/agents/{agent_id}/revoke, or Revoke in the console, closes the session within seconds and deletes
the agent's identity, so it cannot get another token. To run an agent there again, enroll a new one.
Scopes
| Scope | Allows |
|---|---|
agents:read | list the account's agents and read one |
agents:write | make enrollment tokens, revoke and delete agents, run a check |