SecureGuard maintains one canonical, object-based, zone-aware configuration document and renders it into each daemon's native configuration on every change. Everything an operator sees or does is an operation on that one document.
The control plane
| Daemon | Responsibility |
|---|---|
configd | Owns the canonical document, the validation gate, the renderers, the applier and the revision store. Single-writer. |
apid | The management API surface the console and any automation talk to, proxying configd's local control API. Admin auth, RBAC and audit live here. |
flowd | Flow telemetry: pf state and pflog rule-match events plus Suricata EVE events, aggregated into flow records. |
aid | Scores those records into a confidence value and enforces the graduated response within its guardrails. |
had | The HA state machine: heartbeat, election, promote/demote, config sync over the dedicated link. Tested and shipping on Business+: dedicated HA port, layer-2 MAC/IP takeover, config sync and pf state sync. |
mgmtd | The outbound agent for the free Orchestrator download. Dials out; never listens. Not a Business+ license feature. |
The console and any automation reach apid; apid reaches configd over a local socket. No component writes a daemon's configuration directly, and nothing but configd writes the document.
The commit pipeline
A commit is candidate → validate → render → apply, optionally followed by a confirm window. It is modeled on Junos and VyOS, and it is atomic.
Nothing is configured directly. Every config state is an immutable, content-addressed snapshot with a parent pointer, so backup is a copy, export is a readable JSON document, and rollback is an id. HA config sync ships those revisions between nodes on a Business+ cluster.
Validate
Validation is referential and returns every problem it finds, not the first. A rule cannot reference a zone or object that does not exist; a built-in zone cannot be redefined; duplicate interface or zone names are rejected. Some checks are safety rather than tidiness — a nameserver must be a literal address, because it is rendered into a shell assignment and because the resolver cannot resolve a hostname before it has a resolver.
A document that does not validate is never rendered and never applied.
Render
A renderer is a pure function from the document to a set of artifacts and reload actions. It never touches the live system. That has two consequences worth having: renderers are fully unit-testable against golden files, and a preview is simply a render with no apply — so the diff you approve is the text that will land.
Apply
The applier writes the artifacts atomically and runs the reload actions. It supports a staging root and a dry run, which is how the pipeline is tested without a live box.
Confirm — the part that saves you
Changing a firewall remotely can sever the session you are changing it from. A commit may therefore opt into a confirmed-commit window: configd applies the change and arms an auto-revert, and unless a matching confirm arrives inside the window it re-applies the previous revision. The auto-revert runs under the same single-writer lock as any commit, so it cannot race one.
A plain commit with no window is permanent, which matters: the first-boot baseline and the management hub both rely on that.
Revisions
Every config state is an immutable, content-addressed snapshot — the SHA-256 of its canonical JSON — with a parent pointer, an author and a message. From that one property:
- Backup is copying a revision out.
- Restore is loading a revision and committing it.
- Export for review needs no exporter: the revision is a human-readable JSON document.
- Rollback is re-applying an earlier revision id.
- HA sync is shipping revisions between nodes, which is why both members hold byte-identical config. Tested and shipping on Business+ — see HA.
Objects and zones
Policy is expressed zone-to-zone and references named objects — hosts, networks, ranges, groups, services — never raw addresses. Renaming or re-scoping an object updates every rule that uses it, and a topology change like moving an interface between zones does not rewrite policy. More on the policy model.
The AI layer's place in this
The appliance runs a thin harness only — no model weights, no ML runtime. It collects telemetry and calls an external endpoint, then emits suggestions: candidate config patches with a rationale and a risk rating. Those go through the same validate → render → apply path as anything a human typed. Autonomous enforcement, where enabled, is expressed as entries in pf tables with expiry rather than as rules written into your ruleset. The full design.