- Added a `maybe_self_update` function in `evofw-firewall.sh` to allow agents to pull the latest version of the sync script from the server, enhancing the agent's ability to stay updated. - Updated the `/v1/agent/sync-script` endpoint to return ETag and script SHA256 headers, enabling efficient caching and conditional requests. - Modified the agent policy response to include `script_sha256`, providing visibility into the current version of the sync script. - Enhanced tests to verify the self-update functionality and ensure correct behavior of the sync script endpoint. These changes improve the maintainability and reliability of Linux agents by enabling automatic updates of critical scripts.
909 lines
25 KiB
YAML
909 lines
25 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:
|
||
/health:
|
||
get:
|
||
summary: Liveness
|
||
tags: [system]
|
||
responses:
|
||
'200':
|
||
description: OK
|
||
|
||
/api/v1/dashboard:
|
||
get:
|
||
summary: Dashboard KPI
|
||
tags: [ops]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Stats
|
||
|
||
/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: [] }]
|
||
responses:
|
||
'200':
|
||
description: Links
|
||
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: [] }]
|
||
responses:
|
||
'200':
|
||
description: Agents
|
||
|
||
/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: [] }]
|
||
responses:
|
||
'200':
|
||
description: Lists
|
||
post:
|
||
summary: Create IP list
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Created
|
||
|
||
/api/v1/lists/{id}:
|
||
get:
|
||
summary: List detail + entries
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
responses:
|
||
'200':
|
||
description: Detail
|
||
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'
|
||
responses:
|
||
'200':
|
||
description: Updated
|
||
delete:
|
||
summary: Delete entry
|
||
tags: [lists]
|
||
security: [{ bearerAuth: [] }]
|
||
parameters:
|
||
- $ref: '#/components/parameters/Id'
|
||
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/rules:
|
||
get:
|
||
summary: List policy rules (optional set filter)
|
||
tags: [policies]
|
||
security: [{ bearerAuth: [] }]
|
||
responses:
|
||
'200':
|
||
description: Rules
|
||
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 agent (X-EvoFW-Seed)
|
||
tags: [agent-public]
|
||
responses:
|
||
'201':
|
||
description: Pending agent
|
||
|
||
/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)
|
||
|
||
/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:
|
||
type: object
|
||
required: [status]
|
||
properties:
|
||
status: { type: string }
|
||
prefix_count: { type: integer }
|
||
packets_dropped: { type: integer }
|
||
packets_accepted: { type: integer }
|
||
kernel_method: { type: string }
|
||
error: { type: string }
|
||
source: { type: string }
|
||
ip_hits:
|
||
type: array
|
||
maxItems: 200
|
||
description: Linux per-element drop counters (packets > 0)
|
||
items:
|
||
type: object
|
||
required: [ip, packets]
|
||
properties:
|
||
ip: { type: string, maxLength: 64 }
|
||
packets: { type: integer, minimum: 0 }
|
||
port_hits:
|
||
type: array
|
||
maxItems: 500
|
||
description: Linux nft deny_port_hits (ip × proto × dport, packets > 0)
|
||
items:
|
||
type: object
|
||
required: [ip, port, protocol, packets]
|
||
properties:
|
||
ip: { type: string, maxLength: 64 }
|
||
port: { type: integer, minimum: 1, maximum: 65535 }
|
||
protocol: { type: string, enum: [tcp, udp] }
|
||
packets: { type: integer, minimum: 0 }
|
||
host_firewall:
|
||
$ref: '#/components/schemas/HostFirewallPayload'
|
||
responses:
|
||
'200':
|
||
description: OK
|
||
|
||
components:
|
||
parameters:
|
||
Id:
|
||
name: id
|
||
in: path
|
||
required: true
|
||
schema: { type: string }
|
||
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
|