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/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/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 /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) 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 } responses: '200': description: OK components: parameters: Id: name: id in: path required: true schema: { type: string } 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