Wheelhouse docs

Security, VPN and accounts#

This section documents every screen in the web UI's Security and Administration groups, the WireGuard page from the VPN group, and the Account page behind your name at the foot of the left navigation. Two different kinds of page live here. The firewall, NAT, IDS and WireGuard pages are configuration editors: they read the router's configuration tree, show you the set and delete commands a change would run, and put those commands in the staging area rather than applying them. The accounts pages — Users, API tokens, Account — are not configuration at all: they change the agent's own state file, and they take effect the moment you click.

Where each screen is#

ScreenIn the UIAddressWho sees it
FirewallSecurity → Firewall/firewallanyone signed in
NATSecurity → NAT/natanyone signed in
IDSSecurity → IDS/idsanyone signed in, once the feature is on
WireGuardVPN → WireGuard/wireguardanyone signed in, once the feature is on
Accountyour name, at the foot of the left navigation/accountanyone signed in
UsersAdministration → Users/usersadmins
API tokensAdministration → API tokens/tokensadmins

The admin routes are not registered in the app at all for a principal that is not an admin, and the routes behind them are adminOnly in the agent (ui/src/App.tsx, agent/main.go).

The pages#

PageThe screen it documents
FirewallThe screen itself: both address families, the base chains, the global state policy, named rulesets and where they are attached, and where the hit counters come from.
Firewall — rulesThe rule table column by column, the rule editor field by field, and exactly what each field stages.
Firewall — groupsThe eight group kinds, the group cards, and referencing a group from a rule instead of a literal.
Worked rulesetsThree rulesets in full: a default-drop edge, a published service, and a segment that may not reach the LAN.
NATThree tables on one page — port forwards, 1:1, source NAT — with per-rule counters.
Port forwardsThe add-forward editor, the matching accept rule it also stages, and the hairpin pair.
Source NATMasquerade and fixed-address translation, and the rule the installer writes.
1:1 NATThe nat static table, and why its editor is switched off on this platform build.
IDSSuricata as service suricata: what the page shows, what it stages, and the one word it refuses to overstate.
Inline IPSPutting the engine in the packet path with NFQUEUE, the two fail-open layers, and the safe way to turn it on.
WireGuardTunnels and peers as native configuration, and the two things the page cannot show you.
UsersAccounts, roles, creating and deleting, password resets, and linking an account to an identity provider.
RolesWhat viewer, operator and admin may each do, taken from the route table.
AccountYour own password, two-factor enrolment, your live sessions, and unlinking single sign-on.
API tokensIssuing a role-scoped token, the one time its plaintext is shown, expiry and revocation.
Single sign-onWhat OIDC sign-in does, what the UI manages and what only a flag can change.

What holds across the configuration pages#

Nothing on the Firewall, NAT, IDS or WireGuard pages is applied when you click. Every control builds a list of set and delete operations, shows them to you in a Commands or This stages block, and sends them to POST /api/stage. They sit in the staging area until you commit — agent/main.go handleStage, ui/src/lib/staging.tsx.

Every path on these pages arms commit-confirm. The Commit Bar marks an operation as one that can cut you off when its path starts firewall or nat, or touches service ssh, service https, addressing or the default route, and recommends commit-confirm for the batch — ui/src/lib/format.ts isDangerousPath. The default window is two minutes (agent/store.go defaultSettings).

Reading needs a session; changing needs the operator role and a licence. Every read route on these pages is readOnly — any authenticated principal. Every write goes through licensed, which is the operator role plus a usable licence, and answers 402 without one — agent/main.go routes, agent/license.go requireLicense. The Users, API tokens and agent settings routes are adminOnly.

Secrets are blanked below the admin role. GET /api/wireguard is wrapped in redactSecrets(RoleAdmin, …), so a viewer or an operator reading a tunnel gets [redacted] where a private-key or a pre-shared-key would be. The wrapper matches secret leaf names, not positions — agent/security.go.

Two pages are hidden until their feature is on. IDS and WireGuard carry a feature id in the navigation model, and a feature counts as installed when its switch is on in Apps or when its configuration already exists in the tree — so a router that already runs WireGuard shows the page regardless of the switch (ui/src/components/nav.ts, agent/apps.go mergeFeatureState). Firewall and NAT are never hidden.

What this section will not tell you#

  • A per-object nftables view: not built. The counters on the Firewall and NAT pages are joined from show firewall statistics and show nat … statistics. Nothing renders the nftables ruleset itself, and no page shows the chains the router compiled — agent/opmode.go.
  • IPv6 NAT. The NAT page reads the nat subtree. Nothing on it reads or writes an IPv6 NAT tree — agent/main.go handleNatRules.
  • WireGuard handshakes or transfer counters. The page says so itself: those need wg show exposed by the agent, and it does not expose it — ui/src/pages/WireGuard.tsx.

See also#

Checked against#

ui/src/pages/Firewall.tsx, ui/src/pages/Nat.tsx, ui/src/pages/Ids.tsx, ui/src/pages/WireGuard.tsx, ui/src/pages/Users.tsx, ui/src/pages/Account.tsx, ui/src/pages/Tokens.tsx, ui/src/components/nav.ts, ui/src/lib/format.ts, agent/main.go, agent/security.go, agent/license.go, agent/apps.go, agent/store.go.

Updated 2026-09-02 manual firewall nat ids wireguard accounts