Files
EvoFirewall/docs/openapi.yaml
T
Denozordec 9fa6269174
quality / changes (push) Successful in 7s
quality / commitlint (push) Skipped
quality / openapi (push) Successful in 30s
quality / web (push) Successful in 1m3s
quality / api (push) Successful in 1m15s
quality / linux-agent-smoke (push) Failing after 27s
quality / docker-check (push) Failing after 2m28s
CD / quality (push) Failing after 5m52s
CD / publish (push) Skipped
feat: harden firewall policies telemetry and operations
Implement reliable agent apply, telemetry v2, analytics retention, guarded rollouts, enrollment, labels and webhooks. Improve ReUI frontend data safety and bounded list loading, and add Docker smoke, recovery and resource checks. Document local verification and pending native acceptance.
2026-10-26 13:10:58 +07:00

1143 lines
35 KiB
YAML

openapi: 3.0.3
info:
title: EvoFirewall API
version: 0.2.0
description: |
Centralized firewall control plane.
**HTTP SoT:** this OpenAPI document.
**Runtime validation:** Zod schemas in `@evofw/shared` (authoritative for request bodies).
servers:
- url: http://localhost:8080
description: Local API
security: []
paths:
/v1/agent/credentials:
$ref: './openapi.schemas.json#/paths/~1v1~1agent~1credentials'
/v1/agent/token-rotation:
$ref: './openapi.schemas.json#/paths/~1v1~1agent~1token-rotation'
/api/v1/agents/{id}/token-rotation:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1agents~1{id}~1token-rotation'
/api/v1/policies/snapshots:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1policies~1snapshots'
/api/v1/policies/snapshots/{id}:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1policies~1snapshots~1{id}'
/api/v1/policies/snapshots/{id}/diff:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1policies~1snapshots~1{id}~1diff'
/api/v1/policies/rollouts:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1policies~1rollouts'
/api/v1/policies/rollouts/{id}:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1policies~1rollouts~1{id}'
/api/v1/policies/rollouts/{id}/confirm:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1policies~1rollouts~1{id}~1confirm'
/api/v1/policies/rollouts/{id}/rollback:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1policies~1rollouts~1{id}~1rollback'
/api/v1/agents/{id}/policy-pin/release:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1agents~1{id}~1policy-pin~1release'
/api/v1/agent-labels:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1agent-labels'
/api/v1/agent-labels/{id}:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1agent-labels~1{id}'
/api/v1/agents/{id}/labels:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1agents~1{id}~1labels'
/api/v1/agent-labels/preview-assignment:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1agent-labels~1preview-assignment'
/api/v1/agent-labels/assign-policy-sets:
$ref: './openapi.schemas.json#/paths/~1api~1v1~1agent-labels~1assign-policy-sets'
/api/v1/webhooks:
get:
summary: List webhook endpoints and bounded queue counts (settings admin)
tags: [ops]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Endpoint metadata without secrets, configured flag, limits and queue counts
'403':
description: Settings administrator required
post:
summary: Create webhook endpoint (at most 20, settings admin)
tags: [ops]
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema:
$ref: './openapi.schemas.json#/components/schemas/CreateWebhook'
responses:
'201':
description: Endpoint metadata with secret_configured; secret never returned
'503':
description: EVOFW_SECRET_KEY missing or shorter than 32 characters
/api/v1/webhooks/{id}:
parameters:
- $ref: '#/components/parameters/Id'
patch:
summary: Update webhook endpoint; changed destination, signing secret or events cancel pending delivery
tags: [ops]
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema:
$ref: './openapi.schemas.json#/components/schemas/PatchWebhook'
responses:
'200':
description: Updated endpoint metadata without secret
'503':
description: EVOFW_SECRET_KEY unavailable
delete:
summary: Delete endpoint and cancel queued deliveries (settings admin)
tags: [ops]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Deleted
/api/v1/webhooks/{id}/deliveries:
parameters:
- $ref: '#/components/parameters/Id'
get:
summary: Last 100 pending or terminal deliveries, with sanitized error codes (settings admin)
tags: [ops]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Items and total count, excluding payload bytes and signing secrets
/health:
get:
summary: Liveness
tags: [system]
responses:
'200':
description: OK
/ready:
get:
summary: SQLite-backed readiness
tags: [system]
responses:
'200':
description: Ready
'503':
description: Database unavailable
/api/v1/diagnostics:
get:
summary: Bounded runtime and delivery queue diagnostics
description: Requires fw:settings:admin. Returns DB/WAL sizes, filesystem capacity, audit outbox and limiter counters, RSS/heap and uptime. Memory databases and unavailable filesystem metrics return null; no credentials or queued payloads are returned.
tags: [ops]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Runtime diagnostics
content:
application/json:
schema:
type: object
required: [database, audit_outbox, limiter, process]
properties:
database: { type: object, additionalProperties: true }
audit_outbox: { type: object, additionalProperties: true }
limiter: { type: object, additionalProperties: true }
process: { type: object, additionalProperties: true }
'401':
description: Authentication required
'403':
description: Missing settings administrator permission
'429':
description: Authenticated user request limit exceeded
/api/v1/dashboard:
get:
summary: Dashboard KPI
tags: [ops]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Stats
/api/v1/ui/summary:
get:
summary: Permission-filtered navigation and dashboard summary
tags: [ops]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Only sections visible to the authenticated user are included
content:
application/json:
schema:
$ref: './openapi.schemas.json#/components/schemas/UiSummary'
/api/v1/stats/timeseries:
get:
summary: Coverage-aware fleet or agent packet series
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- { name: from, in: query, schema: { type: string, format: date-time } }
- { name: to, in: query, schema: { type: string, format: date-time } }
- { name: resolution, in: query, schema: { type: string, enum: [1m, 1h, 1d] } }
- { name: agent_ids, in: query, description: Comma-separated agent IDs (at most 100), schema: { type: string } }
responses:
'200':
description: At most 1440 points and 100 agents; unknown counters are null
content:
application/json:
schema:
$ref: './openapi.schemas.json#/components/schemas/TimeseriesResponse'
/api/v1/install-context:
get:
summary: Public install base URL + enroll seed hint
tags: [ops]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Install context
/api/v1/install-links:
get:
summary: List install links
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Limit'
- $ref: '#/components/parameters/Offset'
responses:
'200':
description: Links (items + total)
post:
summary: Create install link + invited agent
tags: [agents]
security: [{ bearerAuth: [] }]
responses:
'201':
description: Created
/api/v1/install-links/{id}:
delete:
summary: Revoke install link
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Revoked
/api/v1/agents:
get:
summary: List agents
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Limit'
- $ref: '#/components/parameters/Offset'
responses:
'200':
description: Agents (items + total)
/api/v1/agents/approve-bulk:
post:
summary: Approve many pending/invited agents in one request
tags: [agents]
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [agent_ids]
properties:
agent_ids:
type: array
maxItems: 1000
items: { type: string }
responses:
'200':
description: Approved agents (skips non-pending/invited)
/api/v1/agents/{id}:
get:
summary: Get agent
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Agent
patch:
summary: Update agent
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Updated
delete:
summary: Delete agent
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Deleted
/api/v1/agents/{id}/approve:
post:
summary: Approve pending/invited agent
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Approved
/api/v1/agents/{id}/revoke:
post:
summary: Revoke agent
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Revoked
/api/v1/agents/{id}/preview:
get:
summary: Policy preview (truncated CIDRs)
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
- name: limit_cidrs
in: query
schema: { type: integer, default: 50, maximum: 5000 }
responses:
'200':
description: Preview
/api/v1/agents/{id}/policy-sets:
get:
summary: Assigned policy sets
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Sets
put:
summary: Replace assigned policy sets (order = sort)
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Updated
/api/v1/agents/{id}/overrides:
get:
summary: List IP overrides
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Overrides
post:
summary: Create override
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Created
/api/v1/agents/{id}/overrides/{overrideId}:
delete:
summary: Delete override
tags: [agents]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
- name: overrideId
in: path
required: true
schema: { type: string }
responses:
'200':
description: Deleted
/api/v1/lists:
get:
summary: List IP lists
tags: [lists]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Limit'
- $ref: '#/components/parameters/Offset'
- name: view
in: query
description: Select summary to omit expanded source configuration and entries
schema: { type: string, enum: [summary] }
responses:
'200':
description: Lists (items + total)
post:
summary: Create IP list
tags: [lists]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Created
/api/v1/lists/{id}:
get:
summary: List detail; use view=page for bounded entries and whole-list filtering
tags: [lists]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
- { name: view, in: query, schema: { type: string, enum: [page] } }
- { name: limit, in: query, description: Requires view=page, schema: { type: integer, minimum: 1, maximum: 200, default: 100 } }
- { name: offset, in: query, description: Requires view=page, schema: { type: integer, minimum: 0, maximum: 10000000, default: 0 } }
- { name: q, in: query, description: Whole-list text search before pagination; requires view=page, schema: { type: string, maxLength: 256 } }
- name: filters
in: query
description: >-
JSON array (at most 10 filters), evaluated over the whole list before paging.
Each filter has field value or kind, operator is/is_not/is_any_of/is_not_any_of/
contains/not_contains/starts_with/ends_with/empty/not_empty and values array
(at most 20 strings of at most 256 characters). Requires view=page.
schema: { type: string }
responses:
'200':
description: >-
Default retains full legacy detail. view=page returns metadata plus total,
limit, offset, entries and items (at most limit). Each item has kind,
value, list_name, resolved_count, resolved_cidrs and resolved_truncated;
nested resolved previews are bounded. Invalid page/filter input returns 400.
delete:
summary: Delete list
tags: [lists]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Deleted
/api/v1/lists/{id}/refresh:
post:
summary: Refresh remote/json/evobgp list
tags: [lists]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Refreshed
/api/v1/lists/{id}/entries:
post:
summary: Add manual entries
tags: [lists]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
- name: return
in: query
schema: { type: string, enum: [summary] }
description: Opt in to bounded count/content_hash/changed response instead of expanded detail
responses:
'200':
description: Updated; return=summary uses ListImportSummary from generated contracts
delete:
summary: Delete entry
tags: [lists]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
- name: return
in: query
schema: { type: string, enum: [summary] }
description: Opt in to bounded count/content_hash/changed response instead of expanded detail
responses:
'200':
description: Deleted
/api/v1/policy-sets:
get:
summary: List policy sets
tags: [policies]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Sets
post:
summary: Create policy set
tags: [policies]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Created
/api/v1/policy-sets/{id}:
get:
summary: Get policy set
tags: [policies]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Set
patch:
summary: Patch policy set
tags: [policies]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Updated
delete:
summary: Delete policy set
tags: [policies]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Deleted
/api/v1/policy-sets/{id}/rules:
get:
summary: Rules in set
tags: [policies]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Rules
/api/v1/policy-sets/{id}/rules/reorder:
put:
summary: Reorder rules in a set
tags: [policies]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Reordered
/api/v1/policy-sets/{id}/agents:
put:
summary: Replace which agents have this set assigned
description: >-
Listed agents gain the set (other assignments preserved), unlisted
agents lose it. Body — { agent_ids: string[] } (empty array clears).
tags: [policies]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: '{ agent_ids, added, removed }'
'404':
description: Set or agent not found
/api/v1/rules:
get:
summary: List policy rules (optional set filter)
tags: [policies]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Limit'
- $ref: '#/components/parameters/Offset'
responses:
'200':
description: Rules (items + total)
post:
summary: Create policy rule
tags: [policies]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Created
/api/v1/rules/{id}:
patch:
summary: Patch rule
tags: [policies]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Updated
delete:
summary: Delete rule
tags: [policies]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Deleted
/api/v1/stats/recent:
get:
summary: Recent apply samples
tags: [ops]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Samples
/api/v1/agents/{id}/stats:
get:
summary: Apply samples for one agent
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Samples
/api/v1/agents/{id}/stats/reset:
post:
summary: Reset packet totals, samples, and per-IP block stats
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Agent after reset
/api/v1/agents/{id}/blocked-ips:
get:
summary: Per-IP/CIDR drop counters (Linux nft/ipset; MikroTik HITS)
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Top blocked IPs by accumulated packets (+ optional top ports per IP on Linux)
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
required: [ip, packets, first_seen_at, last_seen_at]
properties:
ip: { type: string }
packets: { type: integer }
first_seen_at: { type: string, format: date-time }
last_seen_at: { type: string, format: date-time }
ports:
type: array
description: Top destination ports for this IP (Linux nft)
items:
type: object
required: [port, protocol, packets]
properties:
port: { type: integer, minimum: 1, maximum: 65535 }
protocol: { type: string, enum: [tcp, udp] }
packets: { type: integer }
/api/v1/agents/{id}/blocked-ports:
get:
summary: Aggregate destination ports hit by denied sources (Linux nft)
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Top ports by accumulated packets across all blocked IPs
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
type: object
required: [port, protocol, packets, last_seen_at]
properties:
port: { type: integer, minimum: 1, maximum: 65535 }
protocol: { type: string, enum: [tcp, udp] }
packets: { type: integer }
last_seen_at: { type: string, format: date-time }
/api/v1/agents/{id}/port-rules:
get:
summary: Desired Port ACL rules (Linux)
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Port ACL rules
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/AgentPortRule'
post:
summary: Create Port ACL rule
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateAgentPortRule'
responses:
'200':
description: Created rule
content:
application/json:
schema:
$ref: '#/components/schemas/AgentPortRule'
'400':
description: Validation / non-linux
/api/v1/agents/{id}/port-rules/import:
post:
summary: Import Port ACL from IP list or policy set sources
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [from, action, ports]
properties:
from: { type: string, enum: [list, set] }
list_id: { type: string }
set_id: { type: string }
action: { type: string, enum: [open, close] }
protocol: { type: string, enum: [tcp, udp, both], default: tcp }
ports:
type: array
minItems: 1
maxItems: 50
items:
type: object
required: [port_start]
properties:
port_start: { type: integer, minimum: 1, maximum: 65535 }
port_end: { type: integer, minimum: 1, maximum: 65535 }
enabled: { type: boolean, default: true }
comment: { type: string, maxLength: 500 }
responses:
'200':
description: Created rules
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/AgentPortRule'
/api/v1/agents/{id}/port-rules/{ruleId}:
patch:
summary: Update Port ACL rule
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
- name: ruleId
in: path
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateAgentPortRule'
responses:
'200':
description: Updated rule
content:
application/json:
schema:
$ref: '#/components/schemas/AgentPortRule'
delete:
summary: Delete Port ACL rule
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
- name: ruleId
in: path
required: true
schema: { type: string }
responses:
'200':
description: Deleted
/api/v1/agents/{id}/host-firewall:
get:
summary: Last observed host firewall snapshot (Linux)
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- $ref: '#/components/parameters/Id'
responses:
'200':
description: Snapshot (empty if never reported)
content:
application/json:
schema:
type: object
properties:
collected_at:
type: string
format: date-time
nullable: true
raw_digest:
type: string
nullable: true
rules:
type: array
items:
$ref: '#/components/schemas/HostFwRule'
listeners:
type: array
items:
$ref: '#/components/schemas/HostListener'
/api/v1/integrations/evobgp/communities:
get:
summary: Proxy EvoBGP communities
tags: [integrations]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Communities
/api/v1/settings:
get:
summary: Settings map (token masked)
tags: [settings]
security: [{ bearerAuth: [] }]
responses:
'200':
description: Settings
put:
summary: Update whitelisted settings keys
tags: [settings]
security: [{ bearerAuth: [] }]
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties:
type: string
description: Keys — enroll_seed, evobgp_api_url, evobgp_api_token, agent_sync_interval_sec, show_quick_actions
responses:
'200':
description: Saved
'400':
description: Unknown key / validation
/api/v1/audit:
get:
summary: Local audit log
tags: [ops]
security: [{ bearerAuth: [] }]
parameters:
- name: action
in: query
schema: { type: string }
- name: severity
in: query
schema: { type: string, enum: [info, warning, critical] }
- name: limit
in: query
schema: { type: integer, default: 200 }
responses:
'200':
description: Audit entries
/v1/agent/install.sh:
get:
summary: Agent install script
tags: [agent-public]
responses:
'200':
description: Shell script
/v1/agent/sync-script:
get:
summary: Linux sync agent (evofw-firewall.sh)
tags: [agent-public]
parameters:
- name: If-None-Match
in: header
schema: { type: string }
description: ETag from a previous GET (`"<sha256>"`)
responses:
'200':
description: Shell script
headers:
ETag:
schema: { type: string }
description: '"<sha256 of file bytes>"'
X-Evofw-Script-Sha256:
schema: { type: string }
description: Hex sha256 of the script body
'304':
description: Script unchanged
/v1/agent/enroll:
post:
summary: Enroll with single-use install-link credential (legacy global seed refused)
tags: [agent-public]
parameters:
- name: X-EvoFW-Enrollment-Credential
in: header
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema:
$ref: './openapi.schemas.json#/components/schemas/EnrollWithCredential'
responses:
'200':
description: Exact consumed enrollment retry; same client; no-store
'201':
description: Newly enrolled pending agent; no-store
'401':
description: Scoped enrollment credential required
'409':
description: Credential already consumed with different enrollment
/v1/agent/policy:
get:
summary: Evaluated policy for agent
tags: [agent]
security: [{ agentToken: [] }]
responses:
'200':
description: Policy (includes script_sha256 for Linux self-update; not part of policy.hash)
content:
application/json:
schema:
$ref: './openapi.schemas.json#/components/schemas/AgentPolicy'
/v1/agent/policy.rsc:
get:
summary: MikroTik RSC policy
tags: [agent]
security: [{ agentToken: [] }]
responses:
'200':
description: RSC text
/v1/agent/heartbeat:
post:
summary: Agent heartbeat
tags: [agent]
security: [{ agentToken: [] }]
responses:
'200':
description: OK
/v1/agent/apply-report:
post:
summary: Apply report + packet stats (+ optional ip_hits / port_hits / host_firewall)
tags: [agent]
security: [{ agentToken: [] }]
requestBody:
required: true
content:
application/json:
schema:
$ref: './openapi.schemas.json#/components/schemas/ApplyReport'
responses:
'200':
description: OK
components:
parameters:
Id:
name: id
in: path
required: true
schema: { type: string }
Limit:
name: limit
in: query
schema: { type: integer, minimum: 1, maximum: 1000 }
description: Page size (without limit/offset the full list is returned)
Offset:
name: offset
in: query
schema: { type: integer, minimum: 0 }
description: Page offset (response includes total)
schemas:
AgentPortRule:
type: object
required:
[
id,
agent_id,
action,
protocol,
port_start,
port_end,
src_kind,
enabled,
priority,
created_at,
updated_at,
]
properties:
id: { type: string }
agent_id: { type: string }
action: { type: string, enum: [open, close] }
protocol: { type: string, enum: [tcp, udp, both] }
port_start: { type: integer, minimum: 1, maximum: 65535 }
port_end: { type: integer, minimum: 1, maximum: 65535 }
src_kind: { type: string, enum: [all, cidr, list] }
src_cidr: { type: string, nullable: true }
list_id: { type: string, nullable: true }
list_name: { type: string, nullable: true }
enabled: { type: boolean }
comment: { type: string, nullable: true }
priority: { type: integer }
created_at: { type: string, format: date-time }
updated_at: { type: string, format: date-time }
CreateAgentPortRule:
type: object
required: [action, port_start]
properties:
action: { type: string, enum: [open, close] }
protocol: { type: string, enum: [tcp, udp, both], default: tcp }
port_start: { type: integer, minimum: 1, maximum: 65535 }
port_end: { type: integer, minimum: 1, maximum: 65535 }
src_kind: { type: string, enum: [all, cidr, list], default: all }
src_cidr: { type: string }
list_id: { type: string }
enabled: { type: boolean, default: true }
comment: { type: string, maxLength: 500 }
priority: { type: integer, default: 100 }
UpdateAgentPortRule:
type: object
properties:
action: { type: string, enum: [open, close] }
protocol: { type: string, enum: [tcp, udp, both] }
port_start: { type: integer, minimum: 1, maximum: 65535 }
port_end: { type: integer, minimum: 1, maximum: 65535 }
src_kind: { type: string, enum: [all, cidr, list] }
src_cidr: { type: string, nullable: true }
list_id: { type: string, nullable: true }
enabled: { type: boolean }
comment: { type: string, maxLength: 500, nullable: true }
priority: { type: integer }
HostFwRule:
type: object
required: [ownership, backend, raw]
properties:
ownership: { type: string, enum: [evofw, foreign] }
backend:
type: string
enum: [nft, iptables, ufw, firewalld, listener]
table: { type: string }
chain: { type: string }
action: { type: string }
protocol: { type: string }
dport: { type: string }
sport: { type: string }
saddr: { type: string }
daddr: { type: string }
comment: { type: string }
raw: { type: string, maxLength: 512 }
HostListener:
type: object
required: [protocol, port, address]
properties:
protocol: { type: string }
port: { type: integer, minimum: 0, maximum: 65535 }
address: { type: string }
process: { type: string }
HostFirewallPayload:
type: object
properties:
rules:
type: array
maxItems: 500
items:
$ref: '#/components/schemas/HostFwRule'
listeners:
type: array
maxItems: 200
items:
$ref: '#/components/schemas/HostListener'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: Portal JWT (app id fw)
agentToken:
type: http
scheme: bearer
description: Agent enroll token
tags:
- name: system
- name: ops
- name: agents
- name: lists
- name: policies
- name: settings
- name: integrations
- name: agent-public
- name: agent