Docs/What the agent sends
What the agent sends
Before you helm install an agent inside your cluster, you
deserve to know exactly what crosses the wire. Here it is. Every
field, every endpoint, no surprises.
The agent's source is public:
github.com/statusharbor/lighthouse.
You can read the transmit code yourself in
internal/transport/
to verify everything below.
Network shape
- One destination:
https://lighthouse.statusharbor.io. The hostname is hardcoded at compile time. The agent never resolves any other host. - Outbound HTTPS only. No inbound ports, no UPnP, no reverse tunnels.
- Bearer-token auth on every request. The token is the one shown once in the dashboard when the Lighthouse is created. Lost? Mint a new one — old tokens stop working immediately.
- TLS-only. HTTP/1.1 + HTTP/2, modern cipher suites, no
fallback to HTTP. The hardcoded URL has the
https://scheme. - No third-party requests. The agent doesn't call analytics, telemetry, error reporting, or any other vendor.
Endpoints
The agent talks to four endpoints. Five, counting graceful shutdown.
POST /api/lighthouse/v1/register
Called once on agent start. Body:
{
"agent_version": "1.4.2",
"agent_hostname": "prod-01"
}That's the entire payload. The hostname is captured from
os.Hostname() (or container hostname inside Docker / k8s); we
use it as the display label until you set one in the UI.
The response contains your Lighthouse's ID, paused state, heartbeat interval, flap protection threshold, and the list of checks the agent should run.
POST /api/lighthouse/v1/heartbeat
Called every 60 seconds (configurable in admin config; default 60s). Body:
{
"agent_version": "1.4.2",
"config_etag": "etag-abc123",
"check_latencies": {
"<check-uuid>": {
"last_observed_latency_ms": 78,
"last_observed_at": "2026-05-09T16:00:00Z"
}
}
}agent_version— for your visibility in the dashboard ("Update available" hints).config_etag— the agent's cached config tag. If it doesn't match the server's, the response includes a fresh check list.check_latencies— sparse map of recent latency observations keyed by check UUID. Only round-trip times, no payload, no response bodies, no headers.
POST /api/lighthouse/v1/events
Called when a check changes state (passing → failing or vice versa). Body:
{
"sync_kind": "ongoing",
"events": [
{
"check_id": "<uuid>",
"prev_state": "ok",
"new_state": "down",
"response_time_ms": 320,
"status_code": 503,
"error_message": "expected status 200, got 503",
"agent_observed_at": "2026-05-09T16:00:14Z"
}
]
}prev_state/new_state— pass/fail strings.response_time_ms— total round-trip the agent observed.status_code— HTTP status, if applicable.error_message— humanized error string. For HTTP checks: status mismatches, keyword mismatches, header mismatches, TLS/handshake errors, DNS errors, timeouts. The agent does not transmit response bodies, custom headers, or any data the probed service emits beyond the assertion outcome.agent_observed_at— RFC3339 timestamp from the agent.
POST /api/lighthouse/v1/discoveries
Sent only if Kubernetes auto-discovery is enabled
(discovery.enabled = true in the Helm values). The agent watches
Ingress and Service resources in the namespaces you allowed
and posts a snapshot. Each entry is metadata only:
{
"discoveries": [
{
"kind": "ingress",
"namespace": "prod",
"resource_name": "web",
"host": "app.example.com",
"path": "/",
"port": 443,
"protocol": "https"
}
]
}The agent never sends pod logs, secrets, environment variables, configmaps, or anything other than the discovery metadata listed above. Discovery is opt-in; if you don't enable it, nothing ships.
POST /api/lighthouse/v1/shutdown
Best-effort, sent on graceful shutdown (SIGTERM). Empty body. Lets the dashboard distinguish "agent stopped on purpose" from "agent died." If the request fails the agent doesn't retry — shutdown proceeds either way.
What the agent does not send
Explicitly, none of this leaves your network:
- HTTP response bodies from the services the agent probes.
- Request bodies (POST/PUT/PATCH bodies you configure on a monitor are stored in the dashboard, not echoed back through the agent).
- Response headers beyond the pass/fail outcome of
expected headersrules. - TLS certificate chains beyond expiry-day calculations.
- DNS query results beyond the assertion outcome.
- Pod logs, ConfigMaps, Secrets, Events, Deployments, or any other Kubernetes resource outside the Ingress / Service metadata listed above.
- Host metrics — CPU, memory, disk, network counters. The agent doesn't collect any of these today.
- Process lists, environment variables, or anything from
/proc. - Files from disk beyond the agent's own config and event
buffer at
/var/lib/lighthouse.
Buffering during outages
The agent maintains an on-disk event buffer at
/var/lib/lighthouse (override with LIGHTHOUSE_DATA_DIR). Today
the buffer is flushed on graceful shutdown — when the agent
receives SIGTERM it drains pending events to Status Harbor before
exiting, so a planned restart doesn't lose state.
Transient send failures during normal operation are not
buffered today; an event that fails to ship is logged and dropped.
On the next state change the agent emits the new value as usual,
so the dashboard converges as soon as the network recovers — but
the brief gap between "old state failed to send" and "new state
sends successfully" can land in a recovery resync rather than as
a real-time transition. Wiring the buffer into the runtime path
is on the roadmap.
Heartbeats and discoveries are best-effort by design — the most recent value is always re-derived on the next call, so there's nothing to buffer.
Verifying
The numbered claims above match the wire types in the agent's
internal/transport/
package. To audit the actual bytes:
# 1. Read the source.
git clone https://github.com/statusharbor/lighthouse
grep -r "json:" lighthouse/internal/transport/
# 2. Run with debug logging — prints request bodies before sending.
LIGHTHOUSE_LOG_LEVEL=debug ./lighthouse run
# 3. Or capture traffic at the network layer.
mitmproxy --mode reverse:https://lighthouse.statusharbor.ioContainer images on ghcr.io/statusharbor/lighthouse are signed
with cosign + Sigstore. Verify provenance before pulling:
cosign verify ghcr.io/statusharbor/lighthouse:latest \
--certificate-identity-regexp 'https://github.com/statusharbor/lighthouse/.*' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com'