Why let an agent from a vendor you don’t know manage your firewall?
Because you don’t have to take our word for it. Every claim on this page is something you can check yourself — read the code that runs on your device, watch the traffic on the wire, and verify what our control plane can and cannot do.
Read the code that runs on your firewall.
NDAgent — the daemon running on the firewall — and NDCLI — the CLI and MCP server on your workstation — are both open source, licensed Apache-2.0.
netdefense-io/NDAgent
Apache-2.0The daemon that runs on your OPNsense firewall. Read exactly what executes on your device before you install it.
netdefense-io/NDCLI
Apache-2.0The CLI and MCP server that talks to your fleet from your workstation.
Source is mirrored on every release tag and is buildable standalone — anyone can audit exactly the code they’re installing, diff it between releases, and rebuild it themselves rather than trusting a download.
This openness is scoped to the edge: the agent on your device and the CLI on your desk. The control plane behind them is closed source — but every guarantee that matters about it is designed to be behaviorally testable from the outside, not something we ask you to take on faith. That’s what the rest of this page is about.
The security pillars
Ten design decisions that hold whether or not you trust us — each one independently verifiable.
A fixed, finite set of named operations
NDAgent understands exactly ten named operations — ping, config sync, config pull, restart, reboot, shutdown, backup, remote session, plugin install, firmware upgrade — and rejects anything outside that set: the wire protocol has no freeform "run this arbitrary string" channel. That doesn’t make every operation harmless — remote session is one of the ten, and a remote session reaches a shell. What a fixed vocabulary buys you is integrity of the channel: the control plane can’t invent an eleventh operation type, and every one of the ten is signed, sequenced, and independently verified by the device (see the next two pillars). It is not, on its own, a claim that a compromised control plane or a stolen write-scoped credential is contained — see “What if our platform is compromised” below for that boundary. Several of the most sensitive operations can only ever be constructed by the control plane’s own internal services; they are not reachable through the public API at all. This is verifiable directly in the public agent source.
Every command is cryptographically signed — TLS is not the trust anchor
Each command is Ed25519-signed by the control plane, covering the operation, target device, expiry, and sequence number. The dispatcher that relays commands to devices holds no signing key and independently re-verifies before forwarding. The agent rejects anything unsigned or altered, with no configuration option to disable the check.
Outbound-only agent
NDAgent opens no listening ports — nothing for an attacker to scan or connect to. It only dials out over TLS. Verifiable in the public source: grep for a listening socket and you won’t find one.
Commands can’t be replayed, reordered, or fired late
Strictly-increasing per-device sequence numbers are persisted on the device before execution, and every command carries a hard expiry. Replays are no-ops, and stale commands fail instead of firing late — ordering and freshness are cryptographically signed and strictly enforced, not left to database row order.
The device has the final say — over configuration content
Once a support session is flagged read-only, the firewall itself enforces it — write paths blocked by a dedicated OS-level account, not by hiding controls in a browser; a modified or instrumented client can’t reach around it. What decides whether a session is read-only in the first place is still the request that opens it, so this is a claim about how faithfully the device honors that flag, not about the device overriding it. Two things on this device genuinely don’t depend on what the cloud says at all: critical accounts can never be modified by a config sync, and — on by default for new installations since NDAgent v1.14.0 — a local policy makes the firewall reject config pushes that try to grant privileges or add SSH keys, even from an authenticated session.
Pinned platform keys, operator-gated re-keying
On first contact, the agent pins the platform’s signing keys. Any change to those keys afterward is a loud, logged event. Re-establishing a device identity — replacing which key the device trusts — requires an admin-issued, one-time token applied at the device itself; it cannot be triggered remotely. That’s a guarantee about identity replacement specifically: it stops an attacker from silently swapping in a new trusted key. It says nothing about what an already-trusted control plane can request through the normal signed-command channel — see “What if our platform is compromised” below.
Hard tenant isolation with a privilege ceiling
Every resource is bound to your organization at the database level; dispatch is routed by exact device identity. Roles are read-only, read-write, or owner, and automation tokens are org-pinned, individually revocable, and structurally capped below owner privilege.
Remote sessions are short-lived and never inspected
Console sessions exist only when a caller with write access opens one, expire automatically within minutes, and pair exactly one device with one operator. The relay that carries the session contains no logic that reads, records, or analyzes its content — it forwards bytes; your browser never receives device credentials. To be direct about what this pillar is and isn’t: a remote session is a shell on the device, so this is a claim about the privacy of that channel, not a limit on what it can do. See “What if our platform is compromised” below for what actually bounds remote-session access today.
Signed software delivery
Firewall packages are RSA-4096-signed FreeBSD packages, verified by the OS package manager before install, against a fingerprint published alongside the package repository. NDCLI releases ship with sha256 checksums and are buildable from the public source.
A hardened, minimal web surface
Interactive login uses standard OAuth2/OIDC with PKCE. Session tokens live in browser memory only, never in local storage. NDWeb ships as static files on a CDN with no server-side session state, behind strict transport and content-security policies.
What if our platform is compromised — or gone?
The honest answer to the worst case, not just the best case.
A compromised dispatch tier
cannot forge commands. It holds no signing key — only the ability to verify and forward what the control plane already signed.
A compromised control plane
cannot invent an operation type outside the fixed set, and cannot forge or replay a command — every one is Ed25519-signed and independently verified by the device. It can mint a fully valid, correctly-signed remote session for any credential with write access, and a remote session is a shell. That’s the honest edge of this guarantee — see below.
An unreachable platform
does not stop your firewall from filtering. Your device keeps enforcing its policy exactly as configured, with or without us.
The honest limit
Signing protects the channel, not the credential. Any account with write access — a stolen token, a compromised control plane, or a prompt-injected AI agent driving the API — can request a remote session, and a remote session is a shell. The fixed operation set, the signatures, and the sequence numbers stop forgery, tampering, and replay; none of them stop an authorized-looking request for an operation the caller is entitled to ask for. Scope automation tokens to the minimum they need, and treat anything capable of opening a remote session with the same caution you’d give an SSH key. Configuration sync is a separate surface from remote sessions altogether: it can install packages, and a package’s post-install scripts run as root.
The clean-exit point
NDAgent only touches the firewall objects it created — identified by an ownership marker and a documented convention in the public agent source — so uninstalling the plugin leaves your firewall exactly as it was. No lock-in.
Verify it yourself
You don’t need our cooperation to check any of this.
- Read and build NDAgent and NDCLI from the public repos.
- Grep the agent source for a listening socket. There isn’t one.
- Scan our web app’s security headers with any public header-scanning tool.
- Watch your browser’s dev tools during login: standard OAuth2 PKCE parameters, a bearer token on every API call, nothing in local storage.
- Try sending an operation type outside the fixed set of ten through the API and watch it get rejected — that’s a closed vocabulary, not a privilege check.
- Fetch the platform’s published signing keys and compare them with what your device pinned on first contact.
What we don’t claim
We don’t claim our signing keys are unbreakable, and we don’t claim that breaching our hosted platform is harmless — a write-scoped credential can open a remote session, and a remote session is a shell. What we do claim is narrower and independently verifiable: the command channel itself resists forgery, tampering, and replay, and the dispatch tier that relays commands holds no signing key of its own. And we don’t claim perfection: the codebase went through a systematic adversarial security review in 2026, with dozens of hardening fixes shipped across every component, and that work is ongoing rather than a one-time pass.
Data handling
The platform handles firewall configuration data and device backups on your behalf. Backups are encrypted. For the specifics of what’s collected and why, see our Privacy Policy.
Found a vulnerability?
We’d rather hear about it from you first. Report privately through any of these channels and we’ll respond promptly.
Prefer to encrypt your report? Use our published PGP key.