Skip to content

REST API

All REST endpoints live under /api/v1/. Base URL: https://<server>:7701.

Authentication

Most endpoints require a JWT in the Authorization header:

Authorization: Bearer <jwt>

Get one via POST /api/v1/auth/login. Tokens are HS256, 24-hour TTL.

Roles

  • viewer — read-only access to agents, policies, events.
  • admin — everything, including policy mutation and approvals.

Setup-flow creates the first admin; subsequent users are created by admins.

Public endpoints (no auth)

MethodPathPurpose
GET/healthLiveness + DB check
GET/api/v1/auth/statusIs setup complete? Returns {configured: bool}
POST/api/v1/auth/setupCreate initial admin (one-time)
POST/api/v1/auth/loginExchange username/password for JWT
GET/api/v1/ca.pemServer CA certificate (for agents)

Viewer endpoints (JWT required)

Agents

MethodPathPurpose
GET/api/v1/agentsList connected daemons
GET/api/v1/daemons?include_archived=boolList daemons with archive filter
GET/api/v1/daemons/{id}Daemon detail
GET/api/v1/discovered-agentsList AI processes observed across fleet
GET/api/v1/discovered-agents/{id}Discovered agent detail

Policies

MethodPathPurpose
GET/api/v1/policiesList all policy versions
GET/api/v1/policies/{version}Single version (YAML + Cedar)
GET/api/v1/policy-assignmentsList assignments
GET/api/v1/policy-assignments/{id}One assignment
GET/api/v1/daemons/{id}/effective-policyMerged effective policy for a daemon

Events

MethodPathPurpose
GET/api/v1/eventsPaginated event query
GET/api/v1/events/streamServer-sent events (live tail)

Query params for /api/v1/events:

  • agent_id — filter by daemon
  • kind — filter by event kind
  • verdictallow/deny/alert
  • drift_detected=true
  • limit (default 100, max 1000)
  • before_ts — pagination cursor

Approvals (roadmap)

MethodPathPurpose
GET/api/v1/approvalsList pending approval requests

Admin endpoints

Policies

MethodPathPurpose
POST/api/v1/policiesApply new policy version (body: {yaml: "..."})
DELETE/api/v1/policies/{version}Delete a policy version

Assignments

MethodPathPurpose
POST/api/v1/policy-assignmentsCreate assignment
DELETE/api/v1/policy-assignments/{id}Delete assignment

Body for POST:

{
"policy_version": 3,
"target_type": "daemon",
"target_id": "4f27e3c1-..."
}

target_type: "daemon" or "agent_type".

Discovered-agent management

MethodPathPurpose
PATCH/api/v1/discovered-agents/{id}Update display name
DELETE/api/v1/daemons/{id}Delete daemon + its discovered agents

Event injection

MethodPathPurpose
POST/api/v1/events/injectInject a synthetic event (testing/bridging)

Body is an Event JSON — see events.proto.

Approvals (roadmap)

MethodPathPurpose
POST/api/v1/approvals/{id}/approveApprove
POST/api/v1/approvals/{id}/denyDeny

Enrollment tokens

MethodPathPurpose
POST/api/v1/enrollment-tokensCreate a new token
GET/api/v1/enrollment-tokensList (metadata only)
DELETE/api/v1/enrollment-tokens/{id}Revoke

Examples

Login

Terminal window
curl -sS -X POST https://tyr.example.com:7701/api/v1/auth/login \
-H "content-type: application/json" \
-d '{"username":"admin","password":"..."}' | jq -r .token

Apply a policy

Terminal window
curl -sS -X POST https://tyr.example.com:7701/api/v1/policies \
-H "Authorization: Bearer $JWT" \
-H "content-type: application/json" \
-d "$(jq -Rs '{yaml: .}' < policy.yaml)"

Live-tail events

Terminal window
curl -sS -N -H "Authorization: Bearer $JWT" \
https://tyr.example.com:7701/api/v1/events/stream

Each message is an SSE data: line with a JSON event.

Errors

Errors return HTTP 4xx/5xx with {"error": "<message>"}.

CodeWhen
400Bad request / invalid YAML / validation failure
401Missing or invalid JWT
403Role insufficient
404Resource not found
409Conflict (e.g. setup already completed)
500Server error