Three review findings, all correct.
`productsign` signs installer packages, not configuration profiles, and
an Apple Developer ID certificate cannot sign a profile at all — Apple's
own guidance is that a `.mobileconfig` is a CMS signed-data message. The
instruction predates this branch but the commit that fixed the malformed
XML comment rewrote it, so it is fixed here rather than carried forward.
It was also misleading in a second way: a profile delivered through an
MDM is signed by the MDM channel, so a managed rollout has nothing to
sign by hand. The step now says that, and gives `security cms -S` for the
case where the profile is handed out some other way.
"Every key is enforced on iOS" contradicted the list of
platform-inapplicable keys three paragraphs below it; it now reads "every
key that applies to the platform", and points at that list.
The engine-applied group — blockInbound, wireguardPort, lazyConnection,
allowRemoteJobs, debugBundleUploadURL — was stated without qualification
under a table headed "iOS / tvOS", while the warning just above says the
tvOS engine never receives the policy. Marked as iOS, with the tvOS case
pointed back at that warning.
The key is enforced on iOS like the other engine-applied ones: a peer
whose policy withholds it refuses management-requested jobs. What is not
there yet is the lock on the Troubleshoot toggle, which arrives with the
iOS client PR that introduces that toggle — so promising it in the table
of what the user sees would describe a screen that does not exist.
Moved to the group of keys the engine applies with nothing on screen to
mark, next to blockInbound, wireguardPort, lazyConnection and
debugBundleUploadURL. It moves back to the table once the toggle ships.
The iOS section was written while the policy stopped at the app: the
network extension that runs the engine has its own preferences domain,
and Apple's app-configuration channel does not deliver there. The app
now mirrors the configuration into the shared App Group and tells the
extension when it changes, so the keys the engine applies to the
connection are enforced too.
What replaces the old warning is a timing caveat, which is what an admin
actually needs in order to plan a rollout. The hand-off happens only
while the app is running: in the foreground a change reaches the tunnel
within about 30 seconds or immediately on activation, but iOS suspends a
backgrounded app, so a policy pushed — or withdrawn — in that window
applies the next time the app is opened. A tunnel brought up by VPN On
Demand or the widget therefore runs on the last policy the app saw.
tvOS keeps the old behaviour and now says so: the hand-off needs a shared
app group, which does not work between the tvOS app and its extension, so
only the interface is enforced there.
Also corrected: blockInbound, wireguardPort and lazyConnection are no
longer listed as having no effect but as having no control to lock, and
debugBundleUploadURL moves out of the ignored list, since the engine
applies it when a remote job produces a bundle. The app-config template
carries the same three keys and the same timing note.
The reference table listed 18 of the 23 keys the client recognises, and
claimed a count of 16. Six keys were missing from every downloadable
template as well, including lazyConnection, which the page already
documented:
- lazyConnection, disableAdvancedView, enableLocalMetrics,
localMetricsAddress, allowRemoteJobs and debugBundleUploadURL are now
in the reference table and in netbird.admx/.adml, io.netbird.client.plist,
netbird-macos.mobileconfig, netbird-macos.sh and netbird-policy.reg.
- Notes call out the two pairs that read as related but are not:
disableMetricsCollection (anonymous telemetry) versus
enableLocalMetrics (the client's own Prometheus endpoint), and
disableAdvancedView being UI-only, so unlike its neighbours it never
causes a request to be rejected.
iOS and tvOS now have a section of their own. The channel is Apple's
Managed App Configuration against bundle id io.netbird.app
(io.netbird.app.tv on tvOS), with a new netbird-ios-appconfig.plist
template and per-provider instructions. The section states what the
policy reaches today: the app locks its interface and refuses
configuration changes, while the tunnel engine runs in a Network
Extension that does not receive the app configuration, so keys the
engine applies to the connection are not enforced there yet.
Two template defects found on the way:
- netbird-macos.mobileconfig was not well-formed XML. Its header
comment contained a double hyphen, which XML forbids inside a
comment, so plutil -lint and any strict parser rejected the file an
admin downloaded.
- netbird-policy.reg had one LF-terminated line among CRLF ones;
normalised, with the UTF-16LE encoding reg import requires preserved.
Verified with npm run build and npm run lint:mdx, plus XML well-formedness
on all five XML templates, bash -n on the shell template, and a
cross-reference check that every string and presentation the ADMX
references is defined in the ADML.
The management server has reported agent_network_* counters (accounts,
providers, policies, budget rules, log collection enabled, input/output
tokens, cost) since Agent Network shipped, but the FAQ list was not
updated. Counters only, no identifying data.
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
The geo section told readers to build a 0.0.0.0/0 Network resource
because a posture check on a Route exit node "does not work". That is
only true when the check sits on the route's access control groups.
Placed on the policy between the users group and the exit node group,
the check withdraws the default route entirely, because routes are only
distributed from peers the device is allowed to connect to. Rewrite the
section around the exit node's native Routes setup, name the wrong
placement, and add the office-subnet variant with a Peer Network Range
check.
If you want a body line with it:
docs: add OpenShift client installation guide
Covers the certified rootless UBI image on restricted-v2, with both
ephemeral (no volume) and PVC-backed peer identity modes.
Domains that already have CAA records refuse certificate issuance unless
the certificate authority is authorized, leaving reverse proxy services
unreachable over HTTPS after the domain verifies successfully.
Document the sectigo.com value used by ZeroSSL on NetBird Cloud's managed
proxy clusters, the issue/issuewild records to add, CAA inheritance from
parent domains, and how to check existing records. Add a troubleshooting
entry for certificates that are not issued after verification.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* [doc] Explain custom domain verification expiry
Describe the 48-hour verification deadline, hourly cleanup, and activity event
so administrators know why a pending domain disappears and how to register it
again. Include the upgrade window and the exception for legacy service use.
* [doc] Explain custom domain name normalization
Describe how new custom domain registrations normalize case, internationalized
names, and a trailing dot, and reject malformed or wildcard names.
* docs: add NetBird client compatibility to the operator support matrix
Add a "NetBird client compatibility" section to the Kubernetes operator
support matrix. Each operator release is built and tested against a
specific NetBird release and deploys that exact, digest-pinned client by
default, so a default install runs the supported combination. Document the
current pairing (operator v0.8.0 with NetBird v0.72.4), a table of tested
clients for recent releases, and that overriding routingClientImage is
neither supported nor tested.
Also replace an em dash in the Kubernetes compatibility section with two
plain sentences.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs: ask for NetBird client version in operator issue reports
Address CodeRabbit review: the compatibility section makes the client
version part of the supported combination, so the reporting checklist now
asks for the NetBird client version and any routingClientImage override.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* docs: add Control Center Draft Mode guide
Add a how-to page for the new Draft Mode in Control Center: build a
change on a working copy of the canvas, review the exact API requests,
and deploy everything as one batch. A single running example (giving
DevOps HTTPS access to a not-yet-installed staging server) carries
through entering a draft, the canvas toolbar, node interactions,
placeholder-peer installs, and Review & Deploy.
Along the way:
- Nest Control Center in the sidebar (Overview + Draft Mode) and update
the overview page: Users view in the intro and quick start, an Edit
Nodes section covering live edits vs Draft Mode, permissions notes
including the Network Admin setup-key limitation, and a HashRedirect
for the renamed #editing-policies-from-the-graph anchor.
- Add a shared <Video> component for screen recordings: lazy playback
via IntersectionObserver, visible controls, preload="metadata", and
no autoplay under prefers-reduced-motion.
- Optimize media: re-encode recordings (H.264 CRF 26, 30 fps,
faststart, audio stripped) and losslessly recompress screenshots,
cutting the page's media payload from 6.3 MB to 1.2 MB.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: image zoom overlay flickering on close
The closing fade-out ran without animation-fill-mode: forwards, so when
the 200ms animation finished the overlay snapped back to full opacity
until React's unmount timeout fired, flashing for a frame or two.
Holding the animation end state covers that gap.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: tighten Draft Mode intro
Give the running example its own paragraph and drop the header-chrome
description; the video right below it shows the same thing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: add Focus Mode section and group-from-selection video
Document Focus Mode on the Control Center overview (right-click a node
and choose Focus, or select it and press F) with two screenshots, and
move the F shortcut prose there from the Draft Mode page. Add a
recording of creating a group from a multi-peer selection to the
Draft Mode page. New media compressed like the rest.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: correct Focus Mode shortcut order
F is pressed first, then the node is selected.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: drop setup-key caveat from Draft Mode permissions note
The Network Admin limitation is already covered where it bites, in the
placeholder install section.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: drop Agent Network disambiguation from Add Nodes
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: reorder Assign Peers to Groups videos
Show the drag-to-group recording right after the text it illustrates,
then the group-from-selection flow.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: remove change-type badge list from review section
The review rows do not carry Add/Modify/Delete/Install badges.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* docs: trim group-membership parenthetical from review example
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix: react to prefers-reduced-motion changes in Video
The reduced-motion check ran once on mount, so toggling the OS setting
while the page was open either kept videos auto-playing or left them
permanently inert. Listen for MediaQueryList changes: pause and drop
the observer when reduced motion turns on, re-observe when it turns
off.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* docs: document the fallback when the client cannot manage firewall rules
Add a troubleshooting section for hosts that are missing the netfilter
modules the client's firewall rules depend on, such as the mark match used
for policy routing or ipset. Include the client log excerpt so the error is
findable by search, with timestamps, hostname and peer identifiers removed.
Document what actually happens. The client logs the failure and proceeds
with the userspace packet filter, so NetBird keeps working and keeps
filtering, and on a routing peer the forwarding path moves to userspace as
well. Remedies are ordered from narrowest to broadest, starting with
loading the missing module and the related environment variables before
reaching for --disable-firewall.
Warn that --disable-firewall is not the same as that automatic fallback.
The userspace filter does not take over, so NetBird enforces no access
control on the peer, and the operator has to recreate the restrictions with
the host's own firewall.
Reference the new section from the Synology install page, where these
netfilter match modules can be missing alongside the tun module already
covered there.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs: reword the NB_USE_LEGACY_ROUTING line
Address CodeRabbit review: 'ip-rule based routing' was an incorrectly
hyphenated compound modifier. Reword so the sentence describes the fallback
directly and drops the compound modifier.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* docs: document that a primary nameserver is exclusive on Windows
A peer with a primary nameserver now gets a Name Resolution Policy Table rule
covering every namespace, so all resolution goes through NetBird and nowhere
else. Without it Windows queries every adapter's resolvers in parallel and keeps
whichever answer arrives first, which leaks queries to the local network and lets
another resolver answer for a name NetBird is authoritative for.
Two consequences worth knowing before it surprises someone:
- Zones only the local network resolves stop working while connected, unless
they are declared as match domains. A more specific rule takes precedence, so
declaring the zone is the fix. `.local` is exempt, so multicast DNS is
unaffected.
- Short names depend on which adapter's suffix Windows tries first, and it stops
at the first "no such name" rather than continuing down the list. On
domain-joined machines the machine's own domain wins that first attempt, so a
short name can fail while its fully qualified form resolves.
Placed next to the existing macOS note in the same section, since both are about
what a primary nameserver does beyond catching unmatched queries, and next to the
existing warning about emptying match domains, which the suffix caveat explains
the other half of.
Also documents NB_USE_LEGACY_DNS_RESOLUTION, which restores the old behaviour on
a peer.
* docs: correct how Windows expands short names, and say from which version
Two fixes to the notes added in the previous commit.
The short-name mechanism was described wrongly. Windows does not stop at the
first suffix that misses: it walks the whole suffix list of the preferred
interface, and what it will not do is fall through to another interface's
suffixes. Measured on a Windows 11 machine — with NetBird's adapter preferred, a
list of {fritz.box, netbird.cloud} resolves a name that only exists under the
second entry; with the metric raised so the physical adapter wins, the same name
fails because only that adapter's single suffix is ever tried. The practical
advice changes with it: declaring the local zone with search domains enabled puts
both suffixes in one list, which is what makes short names work either way.
Both notes now say the exclusive behaviour arrives in client v0.78.0 and what
earlier clients did instead, so the page reads correctly for someone still on
0.77, and the environment variable is marked with the version that introduces it.
* docs: say that exclusive resolution is what breaks short names on Windows
The suffix-search behaviour is not Windows' own: without the catch-all NRPT
rule Windows keeps searching the other adapters' suffix lists, and the short
name resolves. Gate the note to v0.78.0 and point at it from the exclusivity
note, so both texts agree on what the change costs.
On the Add Users page, the indirect-user-invites note told users to email
hello@netbird.io or ping Slack to fix a domain that was not classified as
private. Point it to the NetBird Support page instead, so support requests
go through the same channel as the rest of the docs.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* docs: rebuild connecting-from-the-office on Networks
The page walked the legacy Network Routes flow: create a route, assign
distribution groups, and gate the routing-peer policy. Networks is the
current model, and there was no Networks version of this use case
anywhere in the docs.
Rewritten around the Networks building blocks: the posture check hangs
off the access policy whose destination is the office resource, so the
route is not distributed while the device is on site. Adds a limits
section (re-evaluation delay after a network change, ranges carry no
identity, platform coverage) and a summary. Drops the three legacy
route-UI screenshots.
* docs: Android reports local network addresses from 0.77.1
PR #7235 landed the Android side of PeerNetworkRange: the client now
parses local interface addresses from the host app's interface
discovery, so NetworkAddresses is no longer empty. First release
containing it is v0.77.1.
Scopes the known limitation to Android clients older than 0.77.1 and
leads with the fix, mirroring how the iOS 0.69.0 note reads. Also
matches the posture check name in the office guide to the screenshot.
* docs: correct client command, alt text and wording in the office guide
netbird routes is a deprecated alias; the command is netbird networks
list. Alt text now describes what each screenshot actually shows, and
the check name, Wi-Fi spelling and description line are consistent.
* docs: use documentation-only public ranges, scope the Android note in the Zero Trust guide
1.0.0.0/24 and 3.0.0.0/23 are allocated space and a reader can copy
them into a Block check, so the public-block examples now use RFC 5737
documentation ranges.
The Zero Trust guide still stated the Android limitation
unconditionally, which contradicted the posture check reference after
0.77.1.
* docs: tighten the office guide and the Android limitation
Scopes the intro claim to what the page's own screenshots show, stops
overstating what netbird networks list reports, restores the
platform-targeting bullet with Android 0.77.1 included, and leads the
Android section with the version scope so it reads correctly under
Known Limitations.
* docs: do not present macOS interface names as cross-platform
utun100 is the macOS default (client/iface/configurer/name_darwin.go);
wt0 is the default everywhere else. The verify section now names both
once, and the summary talks about the local link and the NetBird
interface instead of en0 and utun100.
* docs: add selective internal access behind an exit node use case
Documents the two-routing-peer architecture for combining an exit node
with access to specific internal resources only: a resource peer inside
the data center scoped by policies, and an exit node placed on a segment
with internet-only egress. Names the two shortcuts that do not achieve
this (Block LAN access only covers directly attached subnets; host
forward-chain firewall rules are superseded by NetBird's own allow
rules) and adds verification steps, including the netbird down
requirement when enabling Block LAN access over the CLI on a connected
peer. Cross-links from the routing peer concepts and from How Routing
Peers Work.
* docs: make the single-host example clearly outside the subnet resource
* docs: accept all blocked-connection results and scope the exit-node guarantee
* docs: vendor-neutral egress wording and verify bullet polish
* docs: state what actually happens with multiple separate exit nodes
Replaces the 'does not work: ... no coordinated selection' claim in
Regional Exit Nodes with the verified behavior: separate exit nodes
appear as independent choices in the device's exit node selector, the
client auto-selects the alphabetically first name (metrics and latency
play no part), and there is no failover between exit nodes - a device
whose selected exit node loses its routing peer keeps it selected and
loses internet entirely, even across reconnects. Adds the matching
non-overlapping-distribution-groups caveat to the per-group placement
advice, and aligns 'exit node entry' wording to plain 'exit node'.
* docs: scope multi-exit-node selection behavior to Auto Apply
* docs: deduplicate multi-exit-node caveats
* docs: state the one-auto-applied-exit-node-per-device rule