Rules
API: rules
Admin: AdminAuth() + RoleAuth("admin"). Enterprise create/update/assign may pass license gates.
Hosting observation Agents cannot receive rules. POST /api/v1/rules/:id/assign returns HTTP 409:
{"error": "Hosting observation Agents cannot receive rules"}Candidate validation uses hosting observation Agent %d cannot receive rules. Restart uses a different 409 string. See Hosting purpose.
UID/GID subgroup is not a stable customer contract. DNS rules are hostname→IP resolution for firewall matching, not a hosted DNS WAF.
POST /api/v1/rules
Purpose. Create a firewall rule.
Authentication. Admin.
Parameters. None.
Request (CreateRuleRequest via createRuleRequestPayload):
Scroll sideways to see the full table. Use the arrow keys when focused.
| Field | Type | Notes |
|---|---|---|
rule_type | string | required in practice; dedicated cgroup types rejected |
parameters | JSON object | typically {"ip":"203.0.113.10"} for IP rules |
description | string | |
priority | int | optional; default from GetDefaultPriority |
scope | string | zwallctl uses global, agent, group |
agent_ids | int array | assigned after create |
Documented rule_type values from GetDefaultPriority / parameter builders include: BLOCK_BPDU, DHCP_GUARD, BLOCK_MAC, DETECT_PORT_SCAN, DETECT_PORT_SCAN_OUTBOUND, BLOCK_IP_INBOUND, BLOCK_IP_OUTBOUND, BLOCK_PROTOCOL_INBOUND, BLOCK_PROTOCOL_OUTBOUND. Additional types exist in Agent/CLI (ALLOW_IP). If a type is rejected, trust the 400 body.
Dedicated cgroup types return 400 with cgroupdomain.ErrDedicatedPathRequired.
Example request (aligns with zwallctl deny):
{
"rule_type": "BLOCK_IP_INBOUND",
"parameters": {"ip": "203.0.113.10"},
"description": "Deny 203.0.113.10",
"priority": 100,
"scope": "global"
}zwallctl allow may send extra keys name, action, direction, enabled. Standard Go JSON ignores unknown fields. Those extras are not the Manager contract.
Response (201/200). Rule object (Rule): id, rule_type, parameters, description, is_enabled, priority, scope, created_at, updated_at, optional ip_version, is_cidr, expires_at, TTL/packet/ToS/TCP/ICMP filter fields.
Errors. 400 bind/validation (Invalid request format or validator text); 401/403 auth or license; 500 create/assign failure (assign failure rolls the rule back).
Edition. SHARED.
GET /api/v1/rules
Purpose. List rules with Agent assignments.
Authentication. Admin.
Parameters. None required. Pagination is not applied in GetRules (returns full GetRulesWithAgentAssignments result).
Response (200).
{"rules": []}API_SCHEMA_DOCUMENTATION_BLOCKED for enhanced assignment columns — wrapper is gin.H{"rules": enhancedRules} not V1OK.
Errors. 500 Failed to list rules.
Edition. SHARED.
GET /api/v1/rules/:id
Purpose. Fetch one rule.
Authentication. Admin.
Parameters. :id integer.
Response (200). {"rule": { ... Rule ... }}. 400 Invalid rule ID or dedicated-path error; 404 Rule not found.
Edition. SHARED.
PUT /api/v1/rules/:id
Purpose. Update a rule.
Authentication. Admin.
Request (UpdateRuleRequest): all optional — rule_type, parameters, description, is_enabled, priority, scope.
Response (200). Updated rule wrapper (gin.H). 400/404/500 as create.
Edition. SHARED.
DELETE /api/v1/rules/:id
Purpose. Delete a rule.
Authentication. Admin.
Response (200). {"message":"Rule deleted successfully"}. 400/404/500.
Edition. SHARED.
POST /api/v1/rules/:id/enable
POST /api/v1/rules/:id/disable
Purpose. Toggle is_enabled.
Authentication. Admin.
Request. Empty.
Response. success gin.H with message. 404 if missing.
Edition. SHARED.
POST /api/v1/rules/:id/assign
Purpose. Assign an existing rule to one Agent.
Authentication. Admin.
Request.
{"agent_id": 1}agent_id required.
Response (200). success gin.H.
Errors. 400 invalid ids / bind; 404 rule or Agent missing; 409 {"error":"Hosting observation Agents cannot receive rules"}; 500 assign/check failures.
Edition. SHARED.
Security. Hosting profile is observation-only.
DELETE /api/v1/rules/:id/assign/:agent_id
Purpose. Unassign.
Authentication. Admin.
Parameters. :id, :agent_id integers.
Response. success message gin.H. 400/404/500.
Edition. SHARED.
POST /api/v1/rules/bulk
Purpose. Bulk create.
Authentication. Admin.
Request. Array/payload local to BulkCreateRules. API_SCHEMA_DOCUMENTATION_BLOCKED — bind is a slice/map not exported as a stable named DTO in the handler file header.
Edition. SHARED.
GET /api/v1/rules/stats
Purpose. Rule counters.
Authentication. Admin.
Response. API_SCHEMA_DOCUMENTATION_BLOCKED — GetStatistics gin.H.
Edition. SHARED.
POST /api/v1/rules/validate
Purpose. Validate a draft without persisting.
Authentication. Admin.
Request. Same family as create (CreateRuleRequest).
Response. RuleValidationResult: is_valid, errors, warnings.
Edition. ENTERPRISE in Main V1 router (inventory). Do not document as Community unless the Community router registers it.
GET /api/v1/rules/cidr
POST /api/v1/rules/cidr
DELETE /api/v1/rules/cidr/:id
Purpose. CIDR-oriented rule helpers.
Authentication. Admin.
Request/response. API_SCHEMA_DOCUMENTATION_BLOCKED for CIDR-specific bind beyond CreateRuleRequest parameters (is_cidr on Rule). Delete 400/404/500.
Edition. SHARED.
DNS hostname rules
Prefix /api/v1/rules/dns.
GET /api/v1/rules/dns
POST /api/v1/rules/dns
GET /api/v1/rules/dns/:id
PUT /api/v1/rules/dns/:id
DELETE /api/v1/rules/dns/:id
POST /api/v1/rules/dns/:id/resolve
POST /api/v1/rules/dns/:id/enable
POST /api/v1/rules/dns/:id/disable
GET /api/v1/rules/dns/stats
Create request (CreateDNSRuleRequest): hostname required, action required, direction, description, enabled.
Update (UpdateDNSRuleRequest): pointer fields optional.
Response object (DNSRuleResponse): id, hostname, action, direction, resolved_ips, last_resolved, next_resolve, description, ttl, enabled, rule_id, created_at, updated_at.
Resolve response (ResolveHostnameResponse): hostname, ips, ipv4, ipv6, ttl, resolved_at, cache_hit.
Stats (DNSRuleStatsResponse): total_rules, enabled_rules, resolution/cache counters, hostname_stats.
Edition. SHARED. Not a DNS WAF.
UID/GID rules
Prefix /api/v1/rules/uid-gid. Implemented; not a stable customer ABI.
GET /api/v1/rules/uid-gid
POST /api/v1/rules/uid-gid
GET /api/v1/rules/uid-gid/:id
PUT /api/v1/rules/uid-gid/:id
DELETE /api/v1/rules/uid-gid/:id
GET /api/v1/rules/uid-gid/status
GET /api/v1/rules/uid-gid/stats
Request/response. API_SCHEMA_DOCUMENTATION_BLOCKED for field-level customer cookbook — UIDGIDHandler uses domain structs that are explicitly not the V3 enablement contract. Document existence, auth (admin), edition SHARED, and that operators must not treat UID/GID as production-complete.
Edition. SHARED implementation, unstable.