POST /v1/heartbeat

PEP liveness over the authenticated channel. Uninstalling or silencing a PEP is the cheapest bypass of an altitude, and without a beat the runtime cannot distinguish "agent idle" (fine) from "PEP went dark" (a coverage loss). The heartbeat keeps those two facts apart.

A heartbeat is transport-level: it is not a GuardEvent, has no kind, and carries no guarded action. It authenticates like any request on the PEP's channel.

POST {base_url}/v1/heartbeat
Authorization: Bearer ogr_<key>
Content-Type: application/json

Request

At least one of sensor.id / subject.agent_id must be present.

{
  "sensor": {"id": "ogr.higress", "class": "proxy", "version": "0.3.1"},
  "subject": {"agent_id": "build-agent-3"},
  "interval_s": 30,
  "counters": {"events_sent": 120, "evaluate_errors": 0}
}
FieldTypeRequiredDescription
sensorobjectone-ofThe PEP identifying itself — same id/class/version its events carry
subjectobjectone-ofThe agent whose liveness rides this beat (agent_id)
interval_snumberoptionalDeclared cadence; lets the runtime compute "missed beats"
countersobjectoptionalFree-form counters (e.g. events_sent, evaluate_errors) — the runtime reconciles them against delivered events to catch selective suppression

Who a heartbeat speaks for. The sender is the PEP — sensor.id. An instrumentation fronting exactly one agent may additionally name it in subject.agent_id, so the agent's liveness rides the same beat. A gateway or proxy fronting many agents must not: its liveness is not any one agent's, and attributing it would report agents as covered by a sensor that never spoke for them.

Response — 200

{ "ok": true }

A heartbeat registers a live-but-idle agent: fleet coverage reflects enrolled PEPs that have not yet emitted a single event. Deploy the PEP, start the beat, and the runtime knows the altitude is covered before the first guarded action arrives.

Example

curl -s $OGR_RUNTIME/v1/heartbeat \
  -H "Authorization: Bearer $OGR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"sensor": {"id": "ogr.higress", "class": "proxy"}, "interval_s": 30}'

Python

from openguardrails import RuntimeClient

client = RuntimeClient()
client.heartbeat(
    sensor={"id": "ogr.higress", "class": "proxy", "version": "0.3.1"},
    interval_s=30,
    counters={"events_sent": 120, "evaluate_errors": 0},
)

JavaScript

import { RuntimeClient } from "@openguardrails/core"

const client = new RuntimeClient()
await client.heartbeat({
  sensor: { id: "ogr.higress", class: "proxy", version: "0.3.1" },
  interval_s: 30,
  counters: { events_sent: 120, evaluate_errors: 0 },
})

Operational semantics

  • A runtime alerts when a PEP misses beats beyond a tolerance, and treats the gap as a coverage loss — never as "no risk".
  • counters, combined with reconnect replay of degraded-mode buffers, is what makes selective event suppression detectable: a PEP reporting N emitted while N−k arrived is a finding, not noise.