docs: design-13 — WireGuard + NetGuard as first-class plugins - #1
Merged
Conversation
Two signed system plugins (latticenet.netguard, latticenet.wireguard) following the vpn-core migration pattern: engine stays core (approvals, plan-hash, watchdog/rollback scaffolding, task executor), plugins own domain models, compilers, RPC interfaces, and dashboard IA via builtin views. NetGuard: zones (trusted interfaces — the tailscale0 lockout fix), reusable security groups with port ranges and group/zone/node remotes, reality-first authoring (listener + nft -j reporting, suggestions, drift detection), pre-plan lockout linting, blank-machine bootstrap, L1/L2/L3 nftables feature ladder. WireGuard: networks/memberships/external-device peers with one-time conf/QR issuance, mesh + hub-and-spoke + custom topologies, adoption bridge for existing on-box configs, apply gains nft-parity dead-man rollback (today it has none), full option surface with templated PostUp allowlist. Migration behind a byte-parity gate over converted NFTInputs fixtures; phased G1-G7 / W1-W5 tracks. Claude-Session: https://claude.ai/code/session_01D6PbasV2UT8nytJXGpn47Q
Exact seams for G/W slices: capability risk-table additions (netguard:*/wireguard:* scopes), builtin-view double registration with ownership pinning, namespaced RPC interface enforcement, gateway scope union, system-runner contract, and marketplace shipping constraints. Claude-Session: https://claude.ai/code/session_01D6PbasV2UT8nytJXGpn47Q
…y, WG apply safety Claude-Session: https://claude.ai/code/session_01D6PbasV2UT8nytJXGpn47Q
lr00rl
marked this pull request as ready for review
July 9, 2026 06:26
An accidental `git add -A` swept a Claude Code settings temp file into the previous docs commit. It held only a local command allowlist (no secrets), but .claude/ is session state and never belongs in the repo. Claude-Session: https://claude.ai/code/session_01D6PbasV2UT8nytJXGpn47Q
Records lattice-plugin-netguard and lattice-plugin-wireguard (0.1.0-alpha.1, unsigned) and the security finding that forced both manifests to ship without interfaces: the plugin gateway checks scopes with an empty node id, and RPCHandler carries no principal, so a node-restricted PAT could read the whole fleet through POST /api/plugins/call. Claude-Session: https://claude.ai/code/session_01D6PbasV2UT8nytJXGpn47Q
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Design document for splitting WireGuard and nftables out of the current core forms into two independent signed system plugins —
latticenet.netguardandlatticenet.wireguard— with cloud-security-group-grade graphical control, following the proven vpn-core migration pattern (design-09/10/11).Key decisions
/api/plugins/call), and dashboard IA viabuiltincomponent keys. Zero plugin JS in the browser.nft -jruleset → suggestions + drift badges), pre-plan lockout linting, blank-machine bootstrap (preflight → install plan), L1/L2/L3 nftables feature ladder ending in a linted raw-snippet escape hatch.wg show all dump+ redacting conf parser), apply gains nft-parity dead-man rollback (todaywireguardapply has none — server.go:4810-4821), full option surface with a templated PostUp allowlist.NFTInputsmust reproduce today'sGenerateNFTPlanoutput byte-identically before the legacy path retires;NetPolicy/Group*map 1:1 into GuardRules.Grounding
Code-audited against
internal/network/nft.go,internal/netpolicy,internal/wireguard,server.goapply scripts/watchdog, agent taskexec sandbox, and the dashboard Guard/WireGuard views; gap list (no WG rollback, no drift visibility, silent selfcheck skip, hardcoded watchdog, no reality input) is enumerated in §3 and each gap maps to a design section.Phasing
Track G1–G7 (netguard) and W1–W5 (wireguard), each an
iter-NNNslice with exit bars; G1/W1 are read-only foundations with zero apply-path changes.Test plan
https://claude.ai/code/session_01D6PbasV2UT8nytJXGpn47Q