Перейти к основному содержимому

qf Control Plane API (0.20.0)

Download OpenAPI specification:Download

REST API for the qf host-based firewall control plane.

Authentication: Most endpoints require either a JWT cookie (qf_token, set by POST /auth/login) or an Authorization: Bearer <token> header (JWT or opaque API token).

Tenant: Protected endpoints require the X-Tenant-ID header (UUID of the tenant).

Auth

Authentication and session management

Health check

Responses

Response samples

Content type
application/json
{
  • "status": "ok"
}

Application version

Responses

Response samples

Content type
application/json
{
  • "version": "string"
}

Prometheus metrics

Responses

Log in with email and password

Request Body schema: application/json
required
email
required
string <email>
password
required
string <password>

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "password": "pa$$word"
}

Response samples

Content type
application/json
{
  • "error": "string",
  • "request_id": "string"
}

Clear session cookies

Responses

Refresh access token using refresh cookie

Responses

Get current user identity

Authorizations:
cookieAuthbearerAuth

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "email": "string",
  • "role": "string",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0"
}

Check if OIDC login is enabled

Responses

Response samples

Content type
application/json
{
  • "enabled": true
}

Initiate OIDC login flow (redirect to provider)

Responses

OIDC callback — exchange code for tokens

query Parameters
code
string
state
string

Responses

OpenAPI 3.0 spec (this file)

Responses

Swagger UI

Responses

Hosts

Managed firewall hosts

List hosts (cursor-paginated)

Authorizations:
cookieAuthbearerAuth
query Parameters
changed_since
string <date-time>

Reconnect-backfill delta cursor (UI live-sync). When present, the endpoint returns ONLY rows changed at or after changed_since - OVERLAP (a small server-applied safety window; client dedups by id), tenant-scoped exactly as the full list. Omit for the normal full-list response (unchanged). Format is RFC3339 with nanosecond precision (RFC3339Nano) so same-second bulk-enroll ties are preserved. For hosts, archived (soft-deleted) rows are surfaced as tombstones (archived_at set) so clients reconcile deletes. For tokens the filter is insert-only (bootstrap_tokens key on created_at).

limit
integer <= 1000
Default: 500
before
string <date-time>

Cursor — return hosts with created_at strictly before this RFC3339 timestamp (newest first).

cap
string
Enum: "32" "2048" "other"

VIZ-02 rule-cap drill-down filter — return only hosts whose resolved rule-cap tier equals this value. The resolved cap is metrics.rules_cap, falling back to capabilities.ruleCap; a host with no resolvable used+cap is excluded when this filter is set.

rules_min
integer

VIZ-02 drill-down filter — only hosts whose metrics.rules_used is ≥ this value (inclusive).

rules_max
integer

VIZ-02 drill-down filter — only hosts whose metrics.rules_used is ≤ this value (inclusive).

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Rule-cap cohort distribution (tenant-scoped)

VIZ-02 fleet rule-cap pressure, aggregated server-side so the dashboard widget does not fetch the whole fleet. Hosts are grouped by resolved rule-cap tier (2048 bpf_loop / other), then bucketed into utilization cohorts (over/saturated/near/mid/low). Scoped to the caller's tenant.

Authorizations:
cookieAuthbearerAuth
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "tiers": [
    ],
  • "no_metrics": 0
}

Create a host

Authorizations:
cookieAuthbearerAuth
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
hostname
required
string
object
status
string
Default: "enrolling"

Responses

Request samples

Content type
application/json
{
  • "hostname": "string",
  • "labels": {
    },
  • "status": "enrolling"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "hostname": "string",
  • "labels": {
    },
  • "effective_labels": {
    },
  • "status": "enrolling",
  • "current_generation": 0,
  • "desired_generation": 0,
  • "config_version": 0,
  • "flow_events_enabled": true,
  • "last_heartbeat_at": "2019-08-24T14:15:22Z",
  • "agent_version": "string",
  • "kernel_version": "string",
  • "last_seen_ip": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get a host by ID

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "hostname": "string",
  • "labels": {
    },
  • "effective_labels": {
    },
  • "status": "enrolling",
  • "current_generation": 0,
  • "desired_generation": 0,
  • "config_version": 0,
  • "flow_events_enabled": true,
  • "last_heartbeat_at": "2019-08-24T14:15:22Z",
  • "agent_version": "string",
  • "kernel_version": "string",
  • "last_seen_ip": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update host labels, status, or flow_events_enabled

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
object
status
string
flow_events_enabled
boolean

Responses

Request samples

Content type
application/json
{
  • "labels": {
    },
  • "status": "string",
  • "flow_events_enabled": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "hostname": "string",
  • "labels": {
    },
  • "effective_labels": {
    },
  • "status": "enrolling",
  • "current_generation": 0,
  • "desired_generation": 0,
  • "config_version": 0,
  • "flow_events_enabled": true,
  • "last_heartbeat_at": "2019-08-24T14:15:22Z",
  • "agent_version": "string",
  • "kernel_version": "string",
  • "last_seen_ip": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete a host

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "request_id": "string"
}

List host groups the host belongs to

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get the effective compiled ruleset for a host

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "host_id": "eb4e20fc-2b4a-4d0c-811f-48abcf12b89b",
  • "default_ingress": "allow",
  • "default_egress": "allow",
  • "rules": [
    ]
}

Re-apply the current policy bundle to a host

Bumps desired_generation and re-pushes the host's current bundle, overwriting any manual datapath drift. Requires admin or editor.

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "request_id": "string"
}

HostGroups

Named host groups with shared labels

List host groups

Authorizations:
cookieAuthbearerAuth
query Parameters
changed_since
string <date-time>

Reconnect-backfill delta cursor (UI live-sync). When present, the endpoint returns ONLY rows changed at or after changed_since - OVERLAP (a small server-applied safety window; client dedups by id), tenant-scoped exactly as the full list. Omit for the normal full-list response (unchanged). Format is RFC3339 with nanosecond precision (RFC3339Nano) so same-second bulk-enroll ties are preserved. For hosts, archived (soft-deleted) rows are surfaced as tombstones (archived_at set) so clients reconcile deletes. For tokens the filter is insert-only (bootstrap_tokens key on created_at).

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a host group

Authorizations:
cookieAuthbearerAuth
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
name
required
string
object
priority
integer
Default: 100

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "labels": {
    },
  • "priority": 100
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "name": "string",
  • "labels": {
    },
  • "priority": 0,
  • "member_count": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get a host group

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "name": "string",
  • "labels": {
    },
  • "priority": 0,
  • "member_count": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update a host group

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
name
string
object
priority
integer

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "labels": {
    },
  • "priority": 0
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "name": "string",
  • "labels": {
    },
  • "priority": 0,
  • "member_count": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete a host group

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "request_id": "string"
}

List hosts in a group

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Add a host to a group

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
host_id
required
string <uuid>

Responses

Request samples

Content type
application/json
{
  • "host_id": "eb4e20fc-2b4a-4d0c-811f-48abcf12b89b"
}

Response samples

Content type
application/json
{
  • "error": "string",
  • "request_id": "string"
}

Remove a host from a group

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
host_id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "request_id": "string"
}

Events

Log events, flow events, and counters per host

List system events for a host (datapath_drift, host_unreachable, …)

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
query Parameters
limit
integer <= 1000
Default: 500
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

List log events for a host

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
query Parameters
start
string <date-time>
end
string <date-time>
limit
integer <= 1000
Default: 500
rule_id
string <uuid>
action
string
Enum: "allow" "deny" "log"
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

SSE live tail of log events

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Last-Event-ID
string

Resume from this RFC3339Nano timestamp

Responses

List flow events for a host

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
query Parameters
start
string <date-time>
end
string <date-time>
limit
integer <= 1000
Default: 500
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

List counter snapshots for a host

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
query Parameters
start
string <date-time>
end
string <date-time>
limit
integer <= 1000
Default: 500
rule_id
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Latest counter snapshot per rule for a host

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Verdicts log-event aggregate (top denying rules/hosts, deny timeline)

Tenant-scoped rollup over the partitioned log_events table. group_by selects one closed preset (by-rule / by-host / timeline) — the string only SELECTS a static named query and is NEVER interpolated into SQL; an unknown non-empty value → 400. by-rule and timeline are host-scoped (host_id required); by-host aggregates top denying hosts across the whole tenant. The [from,to) window defaults to 24h and is capped 7d server-side so the scan stays partition-pruned. Read tier.

Authorizations:
cookieAuthbearerAuth
query Parameters
group_by
string
Enum: "by-rule" "by-host" "timeline"

Aggregate preset; omitted = by-rule. Unknown value → 400.

host_id
string <uuid>

Required for by-rule/timeline; ignored for by-host.

from
string <date-time>

Inclusive lower bound on created_at (RFC3339); default now-24h.

to
string <date-time>

Exclusive upper bound on created_at (RFC3339); default now.

limit
integer

Max rows for by-rule/by-host (default 500, capped 10000). Ignored by timeline.

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "group_by": "string",
  • "window": {
    },
  • "rows": [
    ]
}

Policies

Firewall policies and rules

List policies

Authorizations:
cookieAuthbearerAuth
query Parameters
changed_since
string <date-time>

Reconnect-backfill delta cursor (UI live-sync). When present, the endpoint returns ONLY rows changed at or after changed_since - OVERLAP (a small server-applied safety window; client dedups by id), tenant-scoped exactly as the full list. Omit for the normal full-list response (unchanged). Format is RFC3339 with nanosecond precision (RFC3339Nano) so same-second bulk-enroll ties are preserved. For hosts, archived (soft-deleted) rows are surfaced as tombstones (archived_at set) so clients reconcile deletes. For tokens the filter is insert-only (bootstrap_tokens key on created_at).

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a policy

Authorizations:
cookieAuthbearerAuth
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
name
required
string
description
string
priority
integer
Default: 0
selector
object

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "priority": 0,
  • "selector": { }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "name": "string",
  • "description": "string",
  • "priority": 0,
  • "selector": { },
  • "confirm_match_all": true,
  • "current_version": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Policy coverage graph (bucket-aggregated)

Returns a bucket-aggregated view of which hosts each policy currently reaches, so the node count is bounded by policy×bucket instead of policy×host. Every edge carries a matched_hosts coverage count and every bucket a total_hosts denominator, both computed over the same active-host set (revoked and enrolling hosts are excluded), so matched_hosts is always less than or equal to total_hosts. The group_by parameter selects the bucket dimension.

Authorizations:
cookieAuthbearerAuth
query Parameters
group_by
string
Default: "hostgroup"
Example: group_by=label:env

Bucket dimension. hostgroup (default) buckets by host group — a host that belongs to several groups counts in each of them, and active hosts in no group fall into a synthetic (ungrouped) bucket. label:<key> buckets by the value of the given effective-label key, with hosts missing the key in an (unset) bucket. none returns one bucket per host (per-host shape). Unrecognised values fall back to hostgroup.

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "policies": [
    ],
  • "buckets": [
    ],
  • "edges": [
    ],
  • "meta": {
    }
}

Per-policy host reach summary (list columns)

Returns one row per policy with its active-host reach split by HOW a host is targeted, plus its rule count — the data behind the policies-list columns and the derived active/inert status. direct_hosts counts hosts matched by a direct block (a pinned host or a bare label/expression block); group_hosts counts hosts matched by a host-group block; total_hosts is the distinct hosts matched either way. A host can match both ways, so direct_hosts + group_hosts can exceed total_hoststotal_hosts is the true blast radius. Counts are over the active-host set (revoked and enrolling hosts excluded). rules_count is the policy's live rule count; a policy is considered inert when it reaches no host or carries no rule.

Authorizations:
cookieAuthbearerAuth
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get a policy

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "name": "string",
  • "description": "string",
  • "priority": 0,
  • "selector": { },
  • "confirm_match_all": true,
  • "current_version": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update a policy (creates a version snapshot)

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
name
required
string
description
string
priority
integer
selector
object
Array of objects (CreateRuleRequest)
confirm_match_all
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "description": "string",
  • "priority": 0,
  • "selector": { },
  • "rules": [
    ],
  • "confirm_match_all": true
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "name": "string",
  • "description": "string",
  • "priority": 0,
  • "selector": { },
  • "confirm_match_all": true,
  • "current_version": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete a policy

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "request_id": "string"
}

List rules for a policy

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a rule

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
name
required
string
priority
integer
Default: 0
direction
string
Default: "ingress"
Enum: "ingress" "egress"
object (RuleMatch)

BPF match criteria. Object-group references use arrays so every reference is stored in policy versions and restored atomically. Legacy singular *_set_id keys are accepted and returned as canonical one-element arrays.

state
string or null
Deprecated
states
Array of strings
Items Enum: "new" "established" "related" "invalid"

Set of conntrack states this rule matches (any of). Empty = stateless.

action
string
Default: "deny"
Enum: "allow" "deny" "log"
log
boolean
Default: false
silent
boolean
notrack
boolean
Default: false

Skip conntrack insert for flows this rule ALLOWs (saves LRU slots on high-volume stateless traffic). Does not change the verdict.

log_rate_limit_per_sec
integer <int32>
Default: 0

Per-rule log token bucket, events/sec. 0 means "use the fleet default" (AgentConfig.default_log_rate_limit_per_sec, 100/s) — NOT "no logging". The datapath field is 16-bit, so values above 65535 truncate.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "priority": 0,
  • "direction": "ingress",
  • "match": {
    },
  • "state": "string",
  • "states": [
    ],
  • "action": "allow",
  • "log": false,
  • "silent": true,
  • "notrack": false,
  • "log_rate_limit_per_sec": 0
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "ee9b03e0-6495-427a-85a5-34444d24ae04",
  • "name": "string",
  • "priority": 0,
  • "direction": "ingress",
  • "match": {
    },
  • "state": "string",
  • "states": [
    ],
  • "action": "allow",
  • "log": true,
  • "silent": true,
  • "notrack": true,
  • "log_rate_limit_per_sec": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get a rule

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
ruleID
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "ee9b03e0-6495-427a-85a5-34444d24ae04",
  • "name": "string",
  • "priority": 0,
  • "direction": "ingress",
  • "match": {
    },
  • "state": "string",
  • "states": [
    ],
  • "action": "allow",
  • "log": true,
  • "silent": true,
  • "notrack": true,
  • "log_rate_limit_per_sec": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update a rule

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
ruleID
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
name
required
string
priority
integer
Default: 0
direction
string
Default: "ingress"
Enum: "ingress" "egress"
object (RuleMatch)

BPF match criteria. Object-group references use arrays so every reference is stored in policy versions and restored atomically. Legacy singular *_set_id keys are accepted and returned as canonical one-element arrays.

state
string or null
Deprecated
states
Array of strings
Items Enum: "new" "established" "related" "invalid"

Set of conntrack states this rule matches (any of). Empty = stateless.

action
string
Default: "deny"
Enum: "allow" "deny" "log"
log
boolean
Default: false
silent
boolean
notrack
boolean
Default: false

Skip conntrack insert for flows this rule ALLOWs (saves LRU slots on high-volume stateless traffic). Does not change the verdict.

log_rate_limit_per_sec
integer <int32>
Default: 0

Per-rule log token bucket, events/sec. 0 means "use the fleet default" (AgentConfig.default_log_rate_limit_per_sec, 100/s) — NOT "no logging". The datapath field is 16-bit, so values above 65535 truncate.

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "priority": 0,
  • "direction": "ingress",
  • "match": {
    },
  • "state": "string",
  • "states": [
    ],
  • "action": "allow",
  • "log": false,
  • "silent": true,
  • "notrack": false,
  • "log_rate_limit_per_sec": 0
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "policy_id": "ee9b03e0-6495-427a-85a5-34444d24ae04",
  • "name": "string",
  • "priority": 0,
  • "direction": "ingress",
  • "match": {
    },
  • "state": "string",
  • "states": [
    ],
  • "action": "allow",
  • "log": true,
  • "silent": true,
  • "notrack": true,
  • "log_rate_limit_per_sec": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete a rule

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
ruleID
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Dry-run preview — compute host impact without applying

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
required
Array of objects (DryRunRuleSpec)
Array
id
string <uuid>

Existing rule UUID; omit for new rules

name
string
priority
integer
direction
string
Enum: "ingress" "egress"
object (RuleMatch)

BPF match criteria. Object-group references use arrays so every reference is stored in policy versions and restored atomically. Legacy singular *_set_id keys are accepted and returned as canonical one-element arrays.

state
string or null
Deprecated
states
Array of strings
Items Enum: "new" "established" "related" "invalid"

Set of conntrack states this rule matches (any of). Empty = stateless.

action
string
Enum: "allow" "deny" "log"
log
boolean
silent
boolean
notrack
boolean

Skip conntrack insert for flows this rule ALLOWs (saves LRU slots on high-volume stateless traffic). Does not change the verdict.

log_rate_limit_per_sec
integer <int32>

Per-rule log token bucket, events/sec. 0 means "use the fleet default" (AgentConfig.default_log_rate_limit_per_sec, 100/s) — NOT "no logging".

Responses

Request samples

Content type
application/json
{
  • "rules": [
    ]
}

Response samples

Content type
application/json
{
  • "affected_count": 0,
  • "hosts": [
    ]
}

List version snapshots for a policy

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Write-free blast preview of a staged draft (B-12)

Computes the affected-host impact of a staged draft WITHOUT writing, enriched with the observed traffic (decisions) for the affected before-side rules over a bounded window. Read tier (writes nothing) — POST because it echoes the projected draft content. The identical route is mounted on object_groups and host_groups (shared version registrar). Optional from/to bound the traffic window (default 24h, capped 7d server-side, partition-pruned).

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
draftId
required
string <uuid>
query Parameters
from
string <date-time>

Traffic window start (RFC3339); defaulted/capped server-side.

to
string <date-time>

Traffic window end (RFC3339); defaults to now.

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "blast": {
    },
  • "traffic": [
    ],
  • "window": {
    }
}

Revert policy to a previous version

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
v
required
integer
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "name": "string",
  • "description": "string",
  • "priority": 0,
  • "selector": { },
  • "confirm_match_all": true,
  • "current_version": 0,
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Versions

Cross-entity config-version browser and impact preview

List applied config versions across all entity types (VERLIVE-03)

Tenant-scoped cross-entity browse of applied config_versions (policy, objectgroup, host_group, host_labels). Filter by optional entity type + created_at range; newest-first, LIMIT-capped. The display name is resolved from the version's content snapshot as-of that version (no JOIN). Read tier.

Authorizations:
cookieAuthbearerAuth
query Parameters
type
string
Enum: "policy" "objectgroup" "host_group" "host_labels"

Filter by entity type; omitted = all types. Unknown value → 400.

from
string <date-time>

Inclusive lower bound on created_at (RFC3339).

to
string <date-time>

Exclusive upper bound on created_at (RFC3339).

limit
integer

Max rows (default 200, capped 1000).

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Preview the COMBINED impact of a set of applied versions (B-11)

Read-only combined impact preview for a SET of selected applied versions, in a single round-trip. Runs the per-host match-aware blast once per version and returns ONE observed-traffic aggregate over the UNION of their before-side rule ids over a bounded window (default 24h, capped 7d server-side, partition-pruned) — so a rule observed by two selected versions over the shared window is counted exactly once (no cross-version double-count) and N HTTP round-trips collapse to one. Preview-only — stages/applies/signs nothing. Repeated ids param (NOT comma-joined). A cross-tenant/missing/malformed id is silently OMITTED from the batch (partial results are valid), never a 404. An absent ids param is a 400.

Authorizations:
cookieAuthbearerAuth
query Parameters
ids
required
Array of strings <uuid> [ items <uuid > ]

Applied-version ids to combine — repeated once per version (?ids=A&ids=B), NOT comma-joined. Absent → 400.

from
string <date-time>

Traffic window start (RFC3339); defaulted/capped server-side.

to
string <date-time>

Traffic window end (RFC3339); defaults to now.

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "versions": [
    ],
  • "traffic": [
    ],
  • "window": {
    }
}

Preview the impact of an applied version (VERLIVE-04/05)

Read-only impact preview for a selected applied version. Computes the per-host match-aware before/after ruleset diff (before = current effective ruleset, after = the version's snapshot) and attaches observed log_events traffic (decisions) for the affected BEFORE-side rule ids over a bounded window (default 24h, capped 7d server-side, partition-pruned). Preview-only — it stages/applies/signs nothing. A cross-tenant/missing id returns 404.

Authorizations:
cookieAuthbearerAuth
path Parameters
versionID
required
string <uuid>
query Parameters
from
string <date-time>

Traffic window start (RFC3339); defaulted/capped server-side.

to
string <date-time>

Traffic window end (RFC3339); defaults to now.

breakdown_by
string
Default: "port"
Enum: "port" "peer" "port_peer"

B-09 traffic breakdown preset. Whitelisted; default port ((rule, protocol, dst_port)). peer groups by (rule, src_ip); port_peer by (rule, protocol, dst_port, src_ip). An unknown value is a 400.

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "version_id": "9e94c502-ca41-4342-a7f7-af96b444512c",
  • "entity_type": "string",
  • "entity_id": "8161163a-f227-466f-bc01-090a01e80165",
  • "version": 0,
  • "blast": { },
  • "traffic": [
    ],
  • "breakdown": [
    ],
  • "window": {
    }
}

Compare two versions of the same entity (B-10, past → future diff)

Read-only TWO-POINT comparison of versions A (past) and B (future) of the SAME entity. Unlike /versions/{id}/impact (which always diffs against the current live ruleset), compare diffs two arbitrary snapshots directly. For a policy it returns the OG-AWARE spec-level field diff (added/removed/changed with per-field before→after on resolved src/dst CIDRs, ports, protocol, tcp_flags, state, action) — object-group references are expanded so a rule differing only in a referenced group's membership classifies changed, not "No changes". For object_group/host_group/host_labels it returns the member set-diff (members_added/members_removed) with an empty diff. Both snapshots are upgraded via ToCurrent before diffing so an older content_version on A is not mis-diffed against a newer B. Side semantics: added = present in B not A; removed = in A not B; compare(A,B) and compare(B,A) are mirror images. Traffic (decisions) is attached for the A-SIDE rule ids over a bounded window and is empty when snapshot A carries no stable rule ids. Preview-only — it stages/applies/signs nothing. A and B MUST belong to the same entity (else 400); a missing/cross-tenant version returns 404.

Authorizations:
cookieAuthbearerAuth
query Parameters
a
required
string <uuid>

Version id of side A (the "past" snapshot).

b
required
string <uuid>

Version id of side B (the "future"/other snapshot).

from
string <date-time>

Traffic window start (RFC3339); defaulted/capped server-side.

to
string <date-time>

Traffic window end (RFC3339); defaults to now.

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "entity_type": "string",
  • "entity_id": "8161163a-f227-466f-bc01-090a01e80165",
  • "a": {
    },
  • "b": {
    },
  • "diff": { },
  • "members_added": [
    ],
  • "members_removed": [
    ],
  • "traffic": [
    ],
  • "window": {
    }
}

ObjectGroups

Named IP/port/host sets for use in rules

List object groups

Authorizations:
cookieAuthbearerAuth
query Parameters
changed_since
string <date-time>

Reconnect-backfill delta cursor (UI live-sync). When present, the endpoint returns ONLY rows changed at or after changed_since - OVERLAP (a small server-applied safety window; client dedups by id), tenant-scoped exactly as the full list. Omit for the normal full-list response (unchanged). Format is RFC3339 with nanosecond precision (RFC3339Nano) so same-second bulk-enroll ties are preserved. For hosts, archived (soft-deleted) rows are surfaced as tombstones (archived_at set) so clients reconcile deletes. For tokens the filter is insert-only (bootstrap_tokens key on created_at).

type
string
Enum: "ipset" "portset" "hostset"
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an object group

Authorizations:
cookieAuthbearerAuth
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
type
required
string
Enum: "ipset" "portset" "hostset"
name
required
string
spec
object

Responses

Request samples

Content type
application/json
{
  • "type": "ipset",
  • "name": "string",
  • "spec": { }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "type": "ipset",
  • "name": "string",
  • "spec": { },
  • "resolved_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Get an object group

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "type": "ipset",
  • "name": "string",
  • "spec": { },
  • "resolved_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Update object group spec

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
spec
required
object

Responses

Request samples

Content type
application/json
{
  • "spec": { }
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "type": "ipset",
  • "name": "string",
  • "spec": { },
  • "resolved_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Delete an object group

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Tokens

Agent enrollment tokens

List enrollment tokens

Authorizations:
cookieAuthbearerAuth
query Parameters
changed_since
string <date-time>

Reconnect-backfill delta cursor (UI live-sync). When present, the endpoint returns ONLY rows changed at or after changed_since - OVERLAP (a small server-applied safety window; client dedups by id), tenant-scoped exactly as the full list. Omit for the normal full-list response (unchanged). Format is RFC3339 with nanosecond precision (RFC3339Nano) so same-second bulk-enroll ties are preserved. For hosts, archived (soft-deleted) rows are surfaced as tombstones (archived_at set) so clients reconcile deletes. For tokens the filter is insert-only (bootstrap_tokens key on created_at).

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an enrollment token

Authorizations:
cookieAuthbearerAuth
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Request Body schema: application/json
required
type
required
string
Enum: "single_host" "bulk"
target_host_id
string <uuid>

Required when type=single_host

target_group_id
string <uuid>

bulk only — auto-add the enrolling host to this host-group (must be in tenant)

object
ttl_seconds
integer
Default: 3600
max_uses
integer
Default: 1

Responses

Request samples

Content type
application/json
{
  • "type": "single_host",
  • "target_host_id": "5fa08e70-cef9-414c-b387-7bde7b6f4011",
  • "target_group_id": "efc47beb-e46d-465e-921d-3e02578ccf22",
  • "label_template": {
    },
  • "ttl_seconds": 3600,
  • "max_uses": 1
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "type": "single_host",
  • "target_host_id": "5fa08e70-cef9-414c-b387-7bde7b6f4011",
  • "target_group_id": "efc47beb-e46d-465e-921d-3e02578ccf22",
  • "label_template": {
    },
  • "max_uses": 0,
  • "uses_count": 0,
  • "expires_at": "2019-08-24T14:15:22Z",
  • "token": "string"
}

Revoke an enrollment token

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

DefaultPolicy

Tenant-level default allow/deny actions

AuditLog

API audit trail

List audit log entries

Authorizations:
cookieAuthbearerAuth
query Parameters
start
string <date-time>
end
string <date-time>
limit
integer <= 1000
Default: 500
actor_type
Array of strings
Items Enum: "user" "api_token" "system" "agent"

Actor kind(s) to include. Repeatable (?actor_type=user&actor_type=agent) — values are unioned server-side (OR). A single value stays valid.

actor_id
Array of strings <uuid> [ items <uuid > ]

Actor UUID(s) to include. Repeatable (?actor_id=a&actor_id=b) — values are unioned server-side (OR). A single value stays valid (backward-compatible).

object_type
string
object_id
string <uuid>
q
string

Free-text filter — case-insensitive substring match over the action string.

header Parameters
X-Tenant-ID
required
string <uuid>

Tenant UUID

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Users

User management (Admin role required for mutations)

List users

Authorizations:
cookieAuthbearerAuth
query Parameters
changed_since
string <date-time>

Reconnect-backfill delta cursor (UI live-sync). When present, the endpoint returns ONLY rows changed at or after changed_since - OVERLAP (a small server-applied safety window; client dedups by id), tenant-scoped exactly as the full list. Omit for the normal full-list response (unchanged). Format is RFC3339 with nanosecond precision (RFC3339Nano) so same-second bulk-enroll ties are preserved. For hosts, archived (soft-deleted) rows are surfaced as tombstones (archived_at set) so clients reconcile deletes. For tokens the filter is insert-only (bootstrap_tokens key on created_at).

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create a user (Admin only)

Authorizations:
cookieAuthbearerAuth
Request Body schema: application/json
required
email
required
string <email>
password
required
string <password>
role
required
string
Enum: "admin" "editor" "auditor"

Responses

Request samples

Content type
application/json
{
  • "email": "user@example.com",
  • "password": "pa$$word",
  • "role": "admin"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "email": "string",
  • "status": "active",
  • "role": "admin",
  • "is_oidc": true,
  • "last_login_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Get a user

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "email": "string",
  • "status": "active",
  • "role": "admin",
  • "is_oidc": true,
  • "last_login_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Update user status or password (Admin only)

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
required
status
string
Enum: "active" "suspended"
password
string <password>

Responses

Request samples

Content type
application/json
{
  • "status": "active",
  • "password": "pa$$word"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "username": "string",
  • "email": "string",
  • "status": "active",
  • "role": "admin",
  • "is_oidc": true,
  • "last_login_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z"
}

Delete a user (Admin only)

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "error": "string",
  • "request_id": "string"
}

Get user role

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
  • "role": "admin"
}

Set user role (Admin only)

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>
Request Body schema: application/json
required
role
required
string
Enum: "admin" "editor" "auditor"

Responses

Request samples

Content type
application/json
{
  • "role": "admin"
}

Response samples

Content type
application/json
{
  • "user_id": "a169451c-8525-4352-b8ca-070dd449a1a5",
  • "role": "admin"
}

APITokens

Long-lived API tokens for automation

List API tokens

Authorizations:
cookieAuthbearerAuth
query Parameters
changed_since
string <date-time>

Reconnect-backfill delta cursor (UI live-sync). When present, the endpoint returns ONLY rows changed at or after changed_since - OVERLAP (a small server-applied safety window; client dedups by id), tenant-scoped exactly as the full list. Omit for the normal full-list response (unchanged). Format is RFC3339 with nanosecond precision (RFC3339Nano) so same-second bulk-enroll ties are preserved. For hosts, archived (soft-deleted) rows are surfaced as tombstones (archived_at set) so clients reconcile deletes. For tokens the filter is insert-only (bootstrap_tokens key on created_at).

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Create an API token

Authorizations:
cookieAuthbearerAuth
Request Body schema: application/json
required
name
required
string
role
required
string
Enum: "admin" "editor" "auditor"
expires_at
string or null <date-time>

Responses

Request samples

Content type
application/json
{
  • "name": "string",
  • "role": "admin",
  • "expires_at": "2019-08-24T14:15:22Z"
}

Response samples

Content type
application/json
{
  • "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
  • "tenant_id": "34f5c98e-f430-457b-a812-92637d0c6fd0",
  • "name": "string",
  • "role": "admin",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "last_used_at": "2019-08-24T14:15:22Z",
  • "created_at": "2019-08-24T14:15:22Z",
  • "token": "string"
}

Revoke an API token

Authorizations:
cookieAuthbearerAuth
path Parameters
id
required
string <uuid>

Responses