Device-Side Protection
Most of what NetDefense guarantees — signed commands, a fixed operation set, replay protection — is enforced by the control plane and by NDAgent’s verification of what it receives. This page is about a different, narrower layer: protections against configuration-sync content that live on the firewall itself, enforced independent of what the sync itself claims. Even a fully authenticated, correctly signed sync — including one issued by a compromised control plane — runs into these when it tries to touch a critical account or grant a new privilege.
This page does not cover remote sessions. A compromised control plane, or any credential with write access, can still open one — and a remote session is a shell. See Security for that boundary and what actually bounds it today.
Treat this page as defense-in-depth for configuration pushes, not a single mechanism and not a complete answer to every worst case. Each guarantee below holds on its own, and they don’t depend on each other to be effective.
Read-only sessions are enforced on the device
Section titled “Read-only sessions are enforced on the device”Read-only remote access to a device’s web administration interface is not a client-side restriction the browser happens to honor — the constraint is enforced by the firewall itself. In a read-only session, every service the agent could otherwise reach is refused except the web UI, and even within the web UI, configuration saves are blocked by a dedicated OS-level read-only account rather than by hiding controls in the interface. From ndagent 1.20.1 the agent also refuses the requests it found that change the device without saving its configuration, such as clearing a log, restarting a service, or applying pending interface changes; older agents let those through.
A session is read-only when a Read-Only member opens it, and on every session to a device whose Remote Access Policy is Read-only web UI only.
What a read-only session can’t see or change
Section titled “What a read-only session can’t see or change”From ndagent 1.20.1, a read-only session also stops showing the secrets the device stores, on the pages and OPNsense releases NetDefense has reviewed:
- Stored secrets are blanked. Where a page or an API response would show a stored secret — for example local users’ password hashes, API keys and one-time-password seeds, private keys of certificates and authorities, WireGuard and IPsec keys, and VPN, high-availability and service passwords — the session gets an empty field. Everything else on the page stays visible.
- Private keys can’t be exported. Downloading a certificate’s or an authority’s private key, or a PKCS#12 bundle, is refused; the certificate itself and a signing request still download. The generated IPsec configuration view, which lists every pre-shared key, is refused too.
- Dashboard and menu-favorite saves are refused, like every configuration save. Each of those saves would cut a configuration revision on the device and push older backups out of its history.
- Crash reports and packet captures aren’t available. What those pages show can’t be cleaned of secrets, so a read-only session doesn’t get them.
If a response that may carry a secret can’t be cleaned reliably, the session withholds it, and the page shows an error rather than the raw response.
What a read-only session can still see
Section titled “What a read-only session can still see”Blanking covers the fields where OPNsense stores secrets. Some gaps remain:
- Logs and free-text settings stay readable. A credential a component wrote into a log, or that someone typed into a free-text setting — an alias URL, a cron command, a custom-options field — is shown as it was written.
- A search can recover a hidden value. Lists whose rows hold secrets can still be searched, and OPNsense matches the search phrase against the stored secret too. The rows come back with their secrets blanked, but which rows match shows whether a phrase occurs in a hidden field, and a phrase extended one character at a time can recover the whole value — a password hash, a one-time-password seed, a pre-shared key, or a private key — from the Users, WireGuard, IPsec, and similar lists. Treat read-only access to a device as access to those secrets. The Certificates and Authorities lists are the exception from agent 1.21.0: a read-only session’s search of either is refused with an error, so their private keys can’t be recovered this way. Older agents let it through.
- Coverage follows NetDefense’s review. These rules come from reviewing the pages and actions of the OPNsense releases NetDefense supports. A page, field, or action that a later OPNsense release, or a plugin NetDefense hasn’t reviewed, adds may not be covered until it has been reviewed.
Critical accounts can’t be touched by a configuration sync
Section titled “Critical accounts can’t be touched by a configuration sync”A handful of accounts on the device are structurally excluded from configuration sync, regardless of what a pushed configuration contains: root, the agent’s own service account, and the dedicated read-only account described above, along with the built-in admins group and the read-only account’s group. A snippet named after one of them can’t be saved, and a sync that still names one fails at the device instead of touching it — this isn’t a validation rule that could be bypassed by constructing the sync differently, it’s a boundary the agent enforces on itself before it ever considers what a sync is asking for. Other administrator accounts aren’t excluded, but from ndagent 1.20.1 changing one through a snippet needs Superuser clearance.
A local policy for privilege-sensitive changes — on by default since v1.14.0
Section titled “A local policy for privilege-sensitive changes — on by default since v1.14.0”The critical-account protection above is always on — it isn’t something you opt into. The agent also supports an additional guardrail on top of it: a local policy, set on the firewall itself as Allow All Snippet Content (Services > NetDefense > Settings, under Advanced Settings, Configuration Sync). While that setting is off, the firewall rejects configuration pushes attempting to grant new privileges, add SSH keys, or enable remote command execution on service accounts. From ndagent 1.20.1 it also refuses adding an account to admins, the read-only account’s group, or a group that is administrator-equivalent on the device, and every administrator-equivalent privilege rather than only blanket ones such as page-all; older agents don’t check group membership. When it’s active, even an authenticated, correctly signed configuration sync is refused if it tries to do any of those things — the device is the one deciding to say no, not the control plane deciding not to ask.
The agent’s own name for this policy is reject_dangerous_snippets, with the opposite polarity: Allow All Snippet Content off is reject_dangerous_snippets=true. From agent 1.21.0, a refusal names the setting itself: rejected by local policy reject_dangerous_snippets: …; to allow it, turn on "Allow All Snippet Content" (reject_dangerous_snippets=false) in Services > NetDefense > Settings, Advanced Settings, Configuration Sync, and apply. An older agent’s refusal ends with a suggestion to set reject_dangerous_snippets=false instead, which on the settings page means turning Allow All Snippet Content on.
Since agent v1.14.0, the policy is on for new installations. Allow All Snippet Content starts off, so the device starts closed, and an operator has to make an explicit, local decision to open it back up.
Existing installations are grandfathered on upgrade. A device that was already configured before the policy existed, and never had it set either way, comes out of the upgrade with Allow All Snippet Content turned on — your current behavior is preserved exactly, nothing changes silently, and no working sync starts failing because of the update. When you’re ready to move to the stricter default, turn Allow All Snippet Content off and click Apply; the agent restarts with the new setting.
Change it on the settings page, not in the agent’s configuration file. The plugin writes /usr/local/etc/ndagent.conf from its settings, and rewrites it whenever they’re applied and on every plugin update, so a reject_dangerous_snippets line edited there by hand doesn’t last.
Setting this is deliberately a local, on-device decision rather than something the platform can flip on your behalf — it lives in the firewall’s own settings, not the control plane, and no configuration sync writes it, so enabling or disabling it is always an explicit choice the device operator makes.
Authentication server and login-order changes are gated too
Section titled “Authentication server and login-order changes are gated too”reject_dangerous_snippets also covers external authentication servers and the login order that decides which one wins: creating or updating a directory server, and writing a new login order, are both refused with the setting at its default (enabled) — even from a fully authenticated, correctly signed sync. In the plugin’s own settings page this is the Allow All Snippet Content checkbox, and it has to be turned on (off by default) before either of those pushes will apply.
Deleting a server is never gated — removal is always allowed. One narrow exception on the create/update side: NetDefense is allowed to grow the set of names a managed directory server excludes from directory login, without needing the setting on, because that change can only ever make the server more restrictive, never less.
Certificate and CA changes are gated too
Section titled “Certificate and CA changes are gated too”reject_dangerous_snippets also covers certificates and CAs: adding or updating either is refused with the setting at its default (enabled), even from a fully authenticated, correctly signed sync, and the sync reports TRUST_REJECTED_DANGEROUS. In the plugin’s settings page, Allow All Snippet Content has to be turned on before those pushes apply.
Removing a certificate or CA is never gated.
The agent never trusts a CA a sync delivers
Section titled “The agent never trusts a CA a sync delivers”A CA synced to the firewall is trusted by the firewall’s own services, but never by the agent’s connection to NetDefense. From agent 1.21.0, the agent checks NetDefense’s certificate against public root certificates built into the agent, plus an optional file of extra CAs that only someone on the device can set (Extra CA File). It doesn’t use the firewall’s certificate store, which a sync can change. So a CA delivered by a sync, whoever authored it and however validly it was signed, can’t be used to intercept the agent’s own connections, including the one-time fetch of the keys it uses to verify what the control plane sends.
Snippets that grant administrator rights
Section titled “Snippets that grant administrator rights”Only a Superuser can save a snippet that, as far as the control plane can tell, grants firewall administrator rights — see Snippets that grant administrator rights. NetDefense marks each USER and GROUP snippet in the signed sync when a Superuser saved it and every variable it uses. From ndagent 1.20.1 the device checks that mark itself, against accounts and groups only it can see — ones created by hand on the device included. Without the mark, it refuses a USER or GROUP element that would:
- add an account to a group that is administrator-equivalent on this device;
- grant an administrator-equivalent privilege, or one NetDefense doesn’t recognize;
- give an account the system scope; or
- change any setting of an account or group that already is administrator-equivalent here.
A refused element is reported with the code ADMIN_EQUIVALENT_REQUIRES_SUPERUSER and a message naming the snippet and what it would have done; the rest of the sync is applied, and the task fails.
Allow All Snippet Content doesn’t lift this check. The two answer different questions: the mark says a Superuser saved the content, and the local policy above decides whether this device accepts privileged content at all. A Superuser-saved snippet that grants an administrator-equivalent privilege, or puts a user in admins, is still refused while the setting is off.
On a device running OPNsense below 26.1.11 — or one whose release the agent can’t read — a set of privileges that OPNsense hardened in 26.1.11 also counts as administrator-equivalent, for this check and for the local policy. See Prerequisites.
This check is about whether a Superuser saved the content. It relies on a mark the control plane signs, so it is no defense against a compromised control plane; there, only the local policy still refuses the content it covers, where it’s turned on. Agents older than 1.20.1 don’t run it, so on those devices nothing catches a snippet that joins a hand-made administrator group or changes an existing administrator account. NetDefense still refuses to build a configuration whose elevated snippets lack Superuser clearance, for every device.
Re-verified on every upgrade, not just first install
Section titled “Re-verified on every upgrade, not just first install”These protections aren’t something NDAgent sets up once and assumes stays true. They’re re-verified on every package upgrade, so a routine pkg upgrade doesn’t quietly regress a device back to a less-protected state — the same checks that applied on day one apply again after every update.
Why this layer exists
Section titled “Why this layer exists”This page exists for one specific worst case: a configuration sync that is correctly signed and fully authorized — including one issued by a compromised control plane — but attempts something the device itself should refuse. Signing and the fixed operation set stop a different problem: they stop an attacker from inventing an operation type that doesn’t exist, or tampering with one in flight. They do not stop the control plane itself from legitimately requesting a privilege-granting sync, because a compromised control plane holds the signing key and needs no forgery — it can sign anything the vocabulary allows. That’s exactly why this layer exists: critical-account protection and reject_dangerous_snippets are the device’s own, independent refusal of specific sync content, regardless of who signed it or how validly.
This layer is scoped to configuration sync. It says nothing about remote session — one of the ten fixed operations — which a compromised control plane, or any write-scoped credential, can still request. Two layers that don’t depend on each other both having to fail is the point for the sync path; the remote-session path is a separate, currently open question addressed on the security page.
See also
Section titled “See also”- Authentication Servers — external LDAP/Active Directory servers and the login order, including this exact gate.
- Certificates — CAs and certificates synced into the trust store, including the same gate.
- Device Identity — how commands are signed and verified in the first place.
- Re-binding — rotating a device’s identity if it’s ever compromised.
- Read-Only Remote Access to Your Firewall’s WebAdmin — the read-only session model in more depth.
- Secure by Default: Config Pushes That Grant Privileges Are Now Rejected Out of the Box — the v1.14.0 announcement, including the grandfathering behavior for existing installs.
- Security — the full model, including what a compromised control plane can and can’t do.