Community-maintained open-source project. Not affiliated with, endorsed by, or sponsored by the OPNsense project, Deciso, Netgate, or the pfSense project. Product and trademark names (OPNsense, pfSense, Netgate) belong to their owners. Source is auditable under the MIT license.
Report privately via a GitHub Security Advisory on github.com/AIops-tools/Firewall-AIops or email zhouwei008@gmail.com. Please do not open public issues for security reports.
- Per-target secrets — the OPNsense API secret (paired with the API key for
HTTP Basic auth) or the pfSense API key — live encrypted in
~/.firewall-aiops/secrets.enc(Fernet/AES-128 + scrypt-derived key; chmod 600), never inconfig.yamland never in source. The master password is never stored — only a per-store random salt and the ciphertext are on disk. - A legacy plaintext env var
FIREWALL_<TARGET_NAME_UPPER>_SECRETis still honoured as a fallback with a deprecation warning (migrate withfirewall-aiops secret migrate). - The secret is held only in memory and never logged or echoed. It is presented
as HTTP Basic auth (OPNsense) or an
X-API-Keyheader (pfSense) at request time; the config file holds only platform, host, port, username, and TLS settings.
Every MCP tool runs through the bundled @governed_tool harness
(firewall_aiops.governance):
- Audit — every call logged to a local SQLite DB under
~/.firewall-aiops/(relocatable viaFIREWALL_AIOPS_HOME), agent-attributed, secret-redacted. - Token/runaway budget — hard ceilings (
FIREWALL_MAX_TOOL_CALLS/FIREWALL_MAX_TOOL_SECONDS) plus an on-by-default guard that trips a tight poll/retry loop, preventing unbounded API consumption. - Risk-tier labelling — each tool's declared
risk_levelis recorded on its audit row as a descriptive tier (a label, not a gate). There is no read-only switch, policy file, or approval gate: whether a write is permitted is the agent's judgement or the connecting account's permissions. - Undo-token recording — reversible writes capture the BEFORE state (via a
real GET) and record an inverse descriptor (e.g.
toggle_rulerestores the prior enabled flag;add_alias_entry→remove_alias_entry) so the change can be rolled back.
The "make it live" commits — apply_changes, reconfigure — and reboot are
risk_level=high and accept a dry_run preview. reboot is irreversible (audit
only, no undo). Rule toggle, alias entry add/remove, kill_states, and
restart_service are risk_level=medium; reversible ones capture before-state
and record an undo token. FIREWALL_AUDIT_APPROVED_BY and
FIREWALL_AUDIT_RATIONALE are optional audit annotations, recorded on the audit
row when set but never required.
verify_ssl defaults to true; disable only for self-signed lab certificates.
scheme defaults to https; set it to http only when the firewall GUI is
published over plain HTTP behind a proxy that terminates TLS for it.
All firewall-returned text (rule descriptions, alias entries, log lines, VPN peer
names, gateway names) is passed through a sanitize() truncate + control-character
strip before reaching the agent.
No webhooks, no telemetry, no outbound calls beyond the configured OPNsense / pfSense REST API endpoints. No post-install scripts or background services.
uvx bandit -r firewall_aiops/ mcp_server/
uv run ruff check .The latest released version receives security fixes. This is a preview (0.x); pin a version in production.