Commit Graph
1213 Commits
Author SHA1 Message Date
Jack Carter 14a79a3256 docs: note that the routing peer decrypts traffic before forwarding it 2026-10-16 16:01:57 +02:00
Jack Carter a16bdc22d9 docs: use the redrawn Networks diagram on the Implement Zero Trust page
Point the routing peer section at networks-overview.png with descriptive
alt text, and remove netbird-network-routes.png, which nothing references
any more.
2026-10-16 13:19:11 +02:00
Jack Carter 34d4f4b29a docs: redraw the Networks diagram and illustrate forward vs input chain
Replace the Networks overview image on the Networks and How Routing
Peers Work pages with a redrawn diagram: peers reach a routing peer
through a WireGuard tunnel, and per-resource access policies on the
routing peer allow specific ports, while a resource with no policy is
unreachable. The old footnote referred to Network Routes HA; the new one
describes adding more than one routing peer to a Network.

Replace the ASCII block in "Through the peer, or to the peer?" with a
diagram of the two paths (network resource policy in the forward chain,
peer-to-peer policy in the input chain), and add the same diagram to
"Two chains, two policy types".

The previous image is kept because the Implement Zero Trust page still
uses it.
2026-10-16 13:09:50 +02:00
Bruno Mercier Costa f966c4815d docs: cover users waiting on their own approval after a second sign-in method (#1045)
* docs: cover users waiting on their own approval after a second sign-in method

A user who created the account with Google or Microsoft and later signs
in with email and password gets a second NetBird user with the same
email, since users are identified by their IdP user ID. Domain matching
adds it to their own account, where user approval holds it, so the
Waiting for Approval screen names their own address.

Adds a section to the account access page with the cause, the fix (sign
in with the original method, reject the extra user), the no-approval and
public-domain variants, and links it from the intro, the What to do
steps and the troubleshooting hub.

* docs: delete, not reject, the extra user when approval is off

Without user approval the second sign-in joins straight away, so it is
not pending and Reject does not apply. Point to Delete in the user's
actions menu under Team -> Users instead.
2026-10-16 12:02:17 +02:00
Riccardo Manfrin def24fafd1 Revert "Document HA routing peer selection from v0.81.1 (#1043)" (#1047)
This reverts commit 1ab145bf.

The HA routing peer selection it documents (netbirdio/netbird #7689 and
#8192) is not in any current stable release: v0.81.2 was cut from the
release branch without it, and it ships in v0.82.0. Until then the page
has to describe what released clients do, including their log messages,
and NB_HA_RELAYED_SWITCH_DELAY has no effect on them. The change comes
back with the v0.82.0 release.
2026-10-16 12:00:54 +02:00
Riccardo Manfrin 1ab145bf2e Document HA routing peer selection from v0.81.1 (#1043)
* Document HA routing peer selection from v0.81.1

Routing peer high availability changed in the client (netbirdio/netbird
#7689 and #8192): a relayed routing peer is held for a delay before an
equivalent direct one takes over, latency is sampled continuously and only
moves the route on a clear gain, and switches are logged with their reason.

Rewrite the High availability section of How Routing Peers Work for the
new behavior, document NB_HA_RELAYED_SWITCH_DELAY and its default, and
list the variable in the client environment variables reference.

* Correct the HA routing peer selection version to v0.81.1

* Spell out the latency noise margin and the exit node loss event

The latency switch margin is four times the combined measurement noise of
both paths, not the noise itself. A network with a default route records
the loss of its last routing peer as "Default route disconnected due to
peer unreachability", not as "No routing peer available".
2026-10-16 10:59:42 +02:00
Bruno Mercier Costa 7a0e1e7b60 docs: add troubleshooting for users who already belong to another account (#1042)
* docs: add troubleshooting for users who already belong to another account

Covers the 409 on invite and the 'user account ID mismatch' IdP sync
failure, how to free the user from the other account, and Sign-in
Domains as the way to prevent it. Links the new page from add users,
IdP sync, sign-in domains, account access, the troubleshooting hub and
the sidebar.

* docs: cover same-account 409s and recovery gaps on the user-in-another-account page

A 409 on invite also fires when the user is already in your own
account, for example waiting for approval, so the page now checks
Team -> Users first. Step 2a covers user approval and a domain that the
user's own account already holds, and Confirm it worked routes a
persisting 409 or failed sign-in to Support. Fixes the Identity
Provider Sync click path and drops the duplicate-users note, whose link
target had no such guidance.

* docs: scope account-conflict notes to Cloud and qualify the delete-account re-login note

Address CodeRabbit review: the 409 note on Add users and the IdP sync
rollout note now say they apply to NetBird Cloud, with the self-hosted
embedded IdP case pointing to Team -> Users. The delete-account page no
longer says a new account is always created on the next login: on
Cloud, a domain owned by another account (signup or verified sign-in
domain) joins that account instead.
2026-10-16 09:15:25 +02:00
Bethuel Mmbaga 3dcebe7b7c Add MySQL to PostgreSQL migration guide (#1024) 2026-10-15 17:27:45 +03:00
Maycon SantosandJack Carter cd63a59360 [doc] Document per-target reverse proxy access control (#1014)
* [doc] Document per-target reverse proxy access control

* docs: screenshots, when-to-use and Bypass warning for target access actions

- Add screenshots of the target Access setting and the target-list indicators
- Add "When to use per-target access actions"
- Warn that Bypass authentication makes the path public
- Note that a Block on /admin/ does not cover /admin
- Access logs: describe the User-column icon and tooltip; document access_action=invalid_path

* docs: tighten target access wording

* docs: say where the access log icons appear

---------

Co-authored-by: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
2026-10-15 16:07:02 +02:00
Bruno Mercier Costa 6f6ad52072 docs: add common issues to the troubleshooting hub and fill out the area tiles (#1039)
* docs: add common issues to the troubleshooting hub and fill out the area tiles

Lead the Troubleshooting hub with a table of the issues support sees most
often, and give each area tile the sections a reader actually needs,
including a new Reverse Proxy tile.

Add the case where a teammate signs in and gets their own account to the
pending approval page, with sign-in domains as the fix.

List the headings rendered by the troubleshooting components in "On this
page", which previously only showed Markdown headings.

* docs: address review on account-access and support wording

- Personal-address teammate: drop the direct-invite advice, since a user
  who already has an account can't be invited; point to the work address
  or NetBird Support instead.
- Support audience: say NetBird Support is mainly for paying Cloud
  customers and commercial-license deployments, consistently across the
  troubleshooting hub, the support page, and the report-bug page.

* docs: align the troubleshooting hub table and rework Still stuck

- Common issues table: fixed 50/50 columns, with the Start here column
  padded to line up with the right-hand area tiles at any width.
- Still stuck: match the width and side padding of the tiles, center the
  title and buttons, and put a short audience note under each button.
  The report hint moves to its own line above the links, with a new
  Debug bundle link.
2026-10-15 15:35:51 +02:00
Jack Carter eb9b675cb2 docs: retake certificate posture check screenshots at retina (#1040)
posture-checks-02.png and posture-checks-certificate.png from #1038 were
1x captures (614x621, 616x728) at 1.1 MB and 1.3 MB. Retaken on macOS at
retina (1326x1338, 1330x1532) and compressed to 54 KB and 80 KB. The CA
shown is a throwaway Corp Root CA, matching the guide's running example.
2026-10-15 14:21:57 +02:00
cab16a160c Add certificate posture check (#1038)
* add certificate posture checks

* update screenshots

* fix typo

* Correct the certificate posture check docs against the shipped client

* Fix the macOS import command, the Debian environment file, an anchor and a hardware claim in the certificate docs

* Trim the certificate posture docs to what a user needs

* docs: fix certificate posture accuracy and grammar nits

- The 1-hour prompt back-off applies on macOS only (collect_darwin.go)
- Key files are refused as symlinks too, not only certificate files
- Geo and network range checks use the server-observed IP, so "most"
  checks read device-reported data, not "every other"
- State the refresh as 4 hours consistently
- Grammar: "are covered", "Red Hat-based", "in the clear", passphrase phrasing

* docs: tighten certificate posture wording and align overview refresh time

* docs: recommend root-only read access for plain certificate key files

---------

Co-authored-by: Viktor Liu <viktor@netbird.io>
Co-authored-by: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
2026-10-15 09:28:58 +02:00
Brandon HopkinsandPizzaLovingNerd cb4c29844f Document Traefik and CrowdSec upgrades for self-hosted deployments (#1030)
* Updating 3rd party packages

* Fixed possible unintentional crowdsec ban

* Fixes and version updates

* Document Traefik header handling

* Traefik rollback and crowdsec allowlist note (#1035)

* Warn that rolling Traefik back before v3.7.12 restores header-alias spoofing.

---------

Co-authored-by: PizzaLovingNerd <cameron@stillhq.io>
2026-10-14 10:25:31 -07:00
Bruno Mercier Costa a9abedcb9f docs: add the NetBird Cloud path to the Agent Network quickstart (#1036)
* docs: add the NetBird Cloud path to the Agent Network quickstart

Agent Network can now be activated on NetBird Cloud, with a NetBird-managed private proxy. The quickstart only described the self-hosted install. Adds a choice between Cloud and self-hosted, shared prerequisites, a Cloud setup section with its own requirements, and a note for the private-cluster requirement when connecting a provider.

* docs: give the own-proxy choice its own step in the Cloud setup

The Cloud setup step only told readers to choose Managed proxy, even when they had been pointed to Deploy a new proxy to keep LLM requests on their own infrastructure. Each choice now has its own instruction, and the own-proxy path links to Clusters.
2026-10-13 12:38:29 +02:00
Bruno Mercier Costa 303ec4b61f docs: correct self-hosted troubleshooting for the combined netbird-server setup (#1033) 2026-10-13 06:19:39 +02:00
netbirddev ffebc1864b Update API pages with v0.81.0-rc.1 2026-10-12 18:08:59 +00:00
Maycon Santos c2198f9956 Document nblink (#1013)
* Document nblink

nblink forwards local ports into a NetBird network from an unprivileged
process, so it covers the cases where the agent cannot be installed: managed
laptops without administrator rights, rootless containers, and short-lived CI
jobs.

Covers the download, the forward syntax, the container environment variables,
and the access control and userspace limits that decide whether it fits.

* Add use cases to the nblink page

The page explained what nblink does and how to run it, but not when to reach
for it, which is the first thing a reader needs to decide.

Covers the three cases it fits best: an MCP server or local AI agent calling
an internal API, Agent Network access from a machine where the client cannot
be installed, and a sidecar for an application that ignores proxy settings.

* Note what the mounted nblink setup key requires

The container example referenced a secret path it never mounted, so it
could not have worked as written. The mount also needs calling out, because
the container runs as an arbitrary UID while a bind mount keeps the host
file's owner and mode, and a key written with the usual private mode is
unreadable to it.

* Document the nblink Host and Origin checks

A loopback forward answers only where Host names the loopback interface and
refuses a cross-site Origin, because a page the reader visits can point its
own hostname at 127.0.0.1 and would otherwise reach the upstream through the
listener under their identity.

* Describe the nblink cross-site check and its residual

The page described only the Host and Origin checks. A page can also embed the
loopback address directly, where Sec-Fetch-Site is the signal that stops it,
and a browser too old to send that header still gets through.

* Publish the nblink container port on loopback only

The container example published port 8080 on every host interface while the
forward inside listened on 0.0.0.0 with public bind enabled, so anything that
could reach the Docker host could use the forward under the peer's identity.
The paragraph beneath it justified that by saying the container boundary
restricts access, which it does not once the port is published.

The example now publishes on 127.0.0.1, with the reason the listener still
has to bind 0.0.0.0 inside the container.

The same section had drifted from the binary in two other places. The
key-file note described what -v does with a missing source path, while the
example uses --mount, which refuses to start. And a public forward now
answers 421 to a name it was not told about, which the page never mentioned:
--allowed-host is added to the container section, the configuration table and
the access-control section, including that a listed name is trusted and
applies to every forward.
2026-10-12 14:49:04 +02:00
Bruno Mercier Costa 6804d6b194 docs: correct Go toolchain and OS cutoffs in the client support matrix (#1032) 2026-10-12 14:42:24 +02:00
Bruno Mercier Costa 2a748bb210 docs: describe the Waiting for Approval screen for pending users (#1031)
* docs: describe the Waiting for Approval screen for pending users

The dashboard now shows pending users a dedicated Waiting for Approval
screen (dashboard #802) that names the account owner's masked email
(management #7533), replacing the old error page. Update the account
access troubleshooting page to match, and point pending users from the
admin-facing approve-users page to it.

* docs: note the owner address only shows when NetBird can resolve it
2026-10-12 14:15:27 +02:00
9f03f72488 docs: add MDM rollout use case under Use Cases → Deployment (#1029)
* docs: add MDM fleet rollout use case

The MDM reference pages cover installing the client and enforcing its
settings separately, per OS and per vendor, but nothing walks through a
whole rollout. This use case ties install, SSO enrollment, policy, and
update ownership together, with an end-to-end Intune example for Windows
and macOS, and links out to the reference pages for detail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JM8WrDg3kV1PQriXwjmzCb

* docs: move MDM rollout under a Deployment use-case group

Group the MDM rollout guide under a new Deployment section in the Use
Cases sidebar. Reuse existing Intune, desktop app, and Intune compliance
screenshots in the walkthrough. Drop the iOS section and the "What this
does not do" section to keep the guide focused on Windows and macOS
laptops.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JM8WrDg3kV1PQriXwjmzCb

* docs: tighten MDM rollout use case for clarity and scan

Polish the fleet rollout page: shorter preamble, clearer policy and update guidance, Related tiles, and a plain checklist without the redundant recap.

* docs: align Intune Ignore app version with update owner

The rollout guide requires Yes when NetBird owns updates and No when Intune does. Document both options on the Intune deploy page so the two guides do not conflict.

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Brandon Hopkins <brandon@techhut.tv>
2026-10-08 14:47:59 -07:00
Brandon Hopkins a390c83c0a Add Unraid docs install page (#1026) 2026-10-08 10:12:33 -07:00
Maycon SantosandClaude Opus 5.5 a436b10641 Mark direct Google IdP as not recommended for self-hosted (#1028)
* Mark direct Google IdP as not recommended for self-hosted

Using Google directly as the self-hosted IdP depends on Management
sending the OAuth client secret to every client, which is deprecated
and will be removed. It also cannot support the device authorization
flow, so headless Linux and FreeBSD peers cannot log in with SSO or
use `netbird ssh` (see netbirdio/netbird discussion 8113).

Mark the standalone Google setup as not recommended, correct the
legacy page's claim that the client secret was already removed,
document the device flow limitation, and add a Google connector
example to the external-to-embedded IdP migration guide.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WxGYofKNYt3aGPnbg6RQsX

* Point Google users to Management Setup in the advanced guide

Step 3 told every provider to follow its Standalone Setup (Advanced)
section, which no longer matches the Google page. Send Google users to
the Quickstart and the Google Management Setup instead, and keep the
standalone instruction for the other providers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WxGYofKNYt3aGPnbg6RQsX

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-10-08 15:53:40 +02:00
Bruno Mercier CostaandClaude Opus 5.5 ad136b2346 docs: Okta SSO setup is self-service in the dashboard (#1027)
The Okta page told readers to email their Client ID, Client Secret and
domains to NetBird support. SSO is now set up in Integrations >
Single Sign-On > Connect Okta, where the wizard takes those values
directly and then asks for domain ownership verification if needed.

- Point the entry path at the Single Sign-On tab and the wizard's
  Get Started / Continue / Connect steps
- Replace the email step with the form fields and the Verify Domain
  Ownership flow (TXT record, Verify Later, email fallback)
- Replace the outdated SCIM-wizard screenshot with one of the
  Enter your Okta details form
- Fix the app.netbird.io link and drop the Okta Verify reference

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 13:38:24 +02:00
netbirddev c8cc844374 Update API pages with v0.81.0-canary.pr-7407.1 2026-10-08 09:14:11 +00:00
netbirddev 71bb0e4838 Update API pages with v0.81.0-canary.pr-8098.1 2026-10-07 14:22:10 +00:00
netbirddev fd7f5c0ddb Update API pages with v0.81.0-canary.pr-7890.1 2026-10-06 21:35:00 +00:00
Pascal Fischer 698b4c48ab remove port forwarding (#1021) 2026-10-06 23:03:41 +02:00
netbirddev 2bd1f37018 Update API pages with v0.81.0-canary.pr-7395.1 2026-10-06 15:47:53 +00:00
Jack Carterandriccardom 4a9435e701 docs: group MDM policy keys by job and split delivery into per-platform pages (#1020)
* docs: document the MDM keys added since the page was written, and iOS

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.

* docs: iOS enforces every key; document when a change reaches the tunnel

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.

* docs: list allowRemoteJobs among the keys iOS enforces without a control

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.

* docs: sign macOS profiles with CMS, and scope the iOS claims properly

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.

* docs: group MDM policy keys by job and split delivery into per-platform pages

Rewrite /client/mdm-integration as the concept page and key reference:
a running example (a three-key baseline), the "pinned switches" model
(present means pinned, even as false), and the 23 keys grouped by the
job they do, each with its own anchor and the mistake it invites.

Correct claims that disagree with the client source (v0.80.0):
- disableClientRoutes stops the device using routes (resources, exit
  nodes); it was described as not routing for others
- blockInbound also stops the SSH server and routing; not a kill switch
- since v0.75.0 the app hides managed settings, no "(MDM)" tag
- a policy change restarts the connection
- splitTunnel* have no effect today (Android has no MDM channel yet)
- managementURL pins the server, not the account, on NetBird Cloud
- the pre-shared key is readable by local users on Windows and macOS

Move Windows, macOS and iOS delivery into their own pages under
MDM Deployment, add them to the nav, and point inbound links at the
new per-key anchors.

* docs: fix MDM accuracy points found in review

- integer booleans are ignored on macOS (plist decodes as uint64); say so
- disableAutostart and disableAdvancedView lock nothing; qualify the lock claim
- managementURL: drop the disableProfiles advice, no key pins the account
- drop the unverifiable restart duration and a disableAdvancedView claim
- macOS page: fix 'never write the file' vs the shell-script channel
- Windows page: warn that the sample .reg pins every key
- tighten wording

* docs: say what disableAdvancedView hides (Peers and Resources tabs)

* docs: make clear disableNetworks removes the choice, not the networks

* docs: add recommended MDM policies by device role

* docs: lazyConnection follows the account setting, on by default since v0.74.0

* docs: drop the open-an-issue line from MDM troubleshooting

* docs: make remote jobs optional for every device role

* docs: make disableNetworks and disableAdvancedView optional for laptops

* docs: rename Recap to TL;DR on the MDM pages

* docs: TL;DR on the main MDM page only, drop the lead-in

* docs: list MDM Integration first under MDM Deployment in the nav

* docs: second review pass on the MDM pages

- macOS integer booleans are locked as well as unapplied; say so
- the lock-nothing keys are not desktop-only (disableAdvancedView on iOS)
- drop Linux from disableAutostart (no MDM channel there)
- blockInbound: drop the redundant routed-network clause
- encryption intro: Rosenpass permissive does not need to match
- troubleshooting: check macOS boolean types, no warning is logged
- wording fixes

* docs: correct MDM timing and CLI claims from a macOS lab run (v0.80.0)

- netbird debug config reads the policy file on each call; the daemon
  applies a change at its next reload and logs 'MDM policy changed'
- netbird up --flag on a connected client ignores its flags; the
  rejection examples now say login --flag or up on a disconnected client
- settings-field locks apply immediately; the disableUpdateSettings,
  disableProfiles and disableNetworks gates apply at the next reload
- the restart on a policy change takes a second or two

* docs: MDM results from the Windows and macOS profile labs (v0.80.0)

- netbird logout works under every key and deregisters the peer; with
  managementURL, disableProfiles and disableUpdateSettings pinned, logout
  plus up --setup-key moves a device to another account on the same URL
- a profile-installed macOS policy file is a binary plist, root:wheel 644
- a REG_BINARY (or other unread type) value is not listed as managed
- the policy key inherits Authenticated Users read access

* docs: tighten four MDM statements to what the labs and source show

- no key blocks netbird logout of the active profile (source: only a
  non-active profile logout is gated, by disableProfiles)
- the engine-restart log line appears only while the client is connected
- macOS: binary plist is what a configuration profile produces; the shell
  script writes the same owner and mode
- Windows: the observed fact is that the NetBird key inherits Authenticated
  Users read access, not a statement about the parent key

* docs: address CodeRabbit review on the MDM delivery pages

- iOS: the app must be managed by the MDM, not necessarily installed by
  it (Apple supports taking over a user-installed app); same in the
  iOS app-config template
- macOS: Jamf's Application & Custom Settings takes the bare plist, so
  point Jamf at io.netbird.client.plist (and note the signed .mobileconfig
  upload route); JumpCloud's MDM Custom Configuration Profile takes a
  .mobileconfig per JumpCloud's docs, so drop the bare-plist claim and
  its troubleshooting entry
- Windows: ADMXInstall only ingests the template; values are set through
  Policy/Config/NetBird~Policy~NetBird/<PolicyName>; drop the
  unverified Registry CSP path

* docs: address CodeRabbit's second review of the MDM templates

- netbird-macos.sh: managementURL, allowServerSSH and wireguardPort now
  default to $NULL like every other key; the old defaults pinned them
  (allowServerSSH=true pinned the SSH server allowed) on any run that
  did not edit those lines
- drop the claim that disableMetricsCollection governs anonymous usage
  telemetry from the mobileconfig, the bare plist, the script and the
  ADML help text; the client recognizes the key but nothing reads it

* docs: correct the Mosyle path for the macOS MDM profile

Mosyle takes the .mobileconfig under Management > Management Profiles >
Certificates / Custom Profiles; there is no Custom Settings option with a
preference domain (per Orb and SI Prep deployment guides; Mosyle's own
docs need a login). Drop Mosyle from the bare-plist template header, and
align the mobileconfig header with the Jamf advice on the page.

* docs: drop the profiles-command install tip from the macOS template

macOS 11 and later cannot install configuration profiles with the
profiles command (man profiles, profiles tool 8.0+); point local testing
at a double-click and System Settings > General > Device Management, the
path the lab used.

* docs: make the Windows MDM page Intune-first, with a registry reference section

The page now leads with the Intune workflow: import the NetBird ADMX/ADML
once, create an Imported Administrative templates profile, assign it to a
device group, sync and verify, then the OMA-URI fallback and Intune
troubleshooting. Group Policy, .reg files, JumpCloud and the value-type
table move to a Registry reference section with its own troubleshooting.

New, from Microsoft Learn (Import custom ADMX templates): the current
portal paths, en-us ADML only, and that re-importing an updated template
fails until the profiles and the old template are deleted. netbird.admx
has no namespace dependencies and no combo boxes, so it imports alone.

The Intune install page stays separate; both pages now link to each
other. Main-page links follow the renamed anchors (#value-types,
#intune-troubleshooting).

* docs: move the enforce-settings link to the end of the Intune deploy page

* docs: group the Windows page's Intune steps under one heading

Mirrors the Registry reference section, so the page's table of contents
shows the Intune/registry split. Heading texts and anchors are unchanged.

* docs: rename the first MDM key group to Set the server and startup

The old heading named only managementURL; the group also holds
disableAutoConnect and disableAutostart.

* docs: add a use case to the Lock the client app section

What a developer on a locked Acme laptop sees (app tabs, the two CLI
errors, what still works), plus the finance team's disableNetworks and
Auto Apply exit node variant. Every behaviour is from the macOS and
Windows labs (v0.80.0).

* docs: replace the Lock the client app use case with a plain goals table

Goal, setting, and what users can still do, written for a junior admin.
disableProfiles row says plainly that signing out and into another
account still works (Windows lab W12).

* docs: OMA-URI payloads: <disabled/> pins an on/off setting off

The ADMX's on/off policies write enabledValue 1 and disabledValue 0, so
<enabled/> can only pin a setting on; document <disabled/> for off, the
String data type, and that un-pinning means Not configured (check the
device with reg query, since removing an OMA-URI may not clear it).

* docs: add What you can achieve tables to every MDM key section

Same goal / setting / what-to-know format as Lock the client app, for
server and startup, device exposure, encryption, support and monitoring,
and connection tuning; Lock's table now names values too. Every line
restates a claim already verified in the labs or source.

* docs: reorder the MDM page: goals first, key reference after

- What you can achieve (the six goal tables) comes first, then
  Recommended policies, How the client applies a policy, and the Policy
  keys reference; goal-table keys link down to their reference entries
- reference groups get noun names (Server and startup keys, ...) so no
  two headings share an anchor
- the Acme running example is gone; its three keys become The laptop
  baseline under Recommended policies, which the Windows, macOS and iOS
  pages now link to as their example
- a one-line pin rule opens the goals, since the explanation now follows

* docs: laptop baseline goes to the user-devices group, not just laptops

* docs: rename the laptop baseline to the user device baseline

It applies to every user device (and the iOS page uses it), so the
Recommended policies column becomes User devices, the anchor becomes
#the-user-device-baseline, and the three platform pages follow.

---------

Co-authored-by: riccardom <riccardomanfrin@gmail.com>
2026-10-06 17:41:42 +02:00
Jack Carter 7d1ca1d635 Mention the Enterprise Commercial License wherever a Cloud plan gates a feature (#1023)
* docs: mention the Enterprise Commercial License wherever a Cloud plan gates a feature

Cloud-plan and cloud-only notes now also name the self-hosted Enterprise
Commercial License for IdP sync, EDR/MDM, peer approval and MFA. The Zero
Trust guide, Plans and billing and Self-hosted vs Cloud gain self-hosted
equivalents. SSO notes state that OIDC IdPs work in both self-hosted
editions. The license page's feature table adds peer approval, audit event
streaming and notifications.

* docs: drop the MFA license claim; self-hosted MFA covers local users only

* docs: state that an Enterprise proof of concept includes every licensed feature
2026-10-06 15:53:32 +02:00
Brandon Hopkins 084ff2462c Fix mobile rendering issues (#1022) 2026-10-05 18:12:39 -07:00
Jack Carter 1ea7881248 docs: traffic events streaming fields, delivery, unrecorded traffic, audit events and peer IP allocation (#1010)
* docs: traffic events streaming fields, delivery, unrecorded traffic, audit events and peer IP allocation

* docs: scope traffic event retries to the save and list client-side data loss

* docs: scope traffic event retry guarantee to server-side steps

Reverts a2f549b4's client-side loss list and drops the restart sentence;
the retry and delayed-not-dropped claims now cover only events that have
reached the servers.
2026-10-05 14:34:48 +02:00
Jack Carter c2a502f706 docs: document unattended installation for the self-hosted quickstart (#1019)
* docs: document unattended installation for the self-hosted quickstart

getting-started.sh reads every prompt's answer from a NETBIRD_* environment
variable since v0.77.1. Document the variables, the env-then-prompt-then-default
order, NETBIRD_NON_INTERACTIVE, the curl | bash pitfall, and how unattended runs
differ (domain validation, trusted peers warning, no pause for external proxies,
no overwrite on rerun).

* docs: an empty variable counts as unset in unattended installation

* docs: say the variables must be set for bash, not reach it
2026-10-05 14:28:59 +02:00
Ivan Zinchenko 09ea3c28a4 fix: disable skew-y-[-18deg] in gecko browsers (#962)
Firefox/Gecko suffers severe scrolling jank on the documentation pages because of the large decorative SVG in the page header.

The SVG uses both:

- `mix-blend-mode: overlay`
- `transform: skewY(-18deg)`

Removing only the transform (`skew-y-[-18deg]`) for firefox-base browsers makes scrolling smooth immediately.

Reproduced in:
- Firefox on Windows
- Zen on Windows
- Zen on macOS

Chromium is unaffected.
2026-10-02 20:17:14 +02:00
Brad Ison 15fb59df47 docs: add NB_PROXY_DIRECT_UPSTREAM_BLOCK_PRIVATE to proxy env var reference (#1011)
Documents the opt-in guard from netbirdio/netbird#7913 that refuses
Direct Upstream dials to non-publicly-routable addresses.
2026-10-02 14:05:19 +02:00
Bethuel Mmbaga ca2634d77d Add proxy and enable flags to the enterprise getting-started guide (#999) 2026-10-02 12:23:28 +03:00
Edward 7d66d1b59f add section for discussion-first (#1015) 2026-10-02 11:00:17 +02:00
Maycon Santos 11b2b8944e Update slack invite (#1012) 2026-10-01 13:01:25 -07:00
Nicolas Frati 8cff42c937 docs: document Agent Network Admin and Usage Viewer roles (#1009)
* docs: document Agent Network Admin and Usage Viewer roles

* docs: unwrap hard-wrapped paragraphs in Agent Network usage pages
2026-10-01 12:06:22 -07:00
Jack Carter dff289cb8b docs: BYOP run command and exposing L4 ports, with a host-networking option (#1008)
* docs: BYOP run command and exposing L4 ports, with a host-networking option

- Bring Your Own Proxy: update the docker run commands to the dashboard
  wizard's current form (NB_PROXY_ADDRESS=:443, named certificate volume);
  the image listens on 8443 by default and runs as uid 1000.
- Bring Your Own Proxy: new section on exposing TCP and UDP services:
  publish and open each listen port, the recreate it takes, a pre-published
  range, or host networking and its port-1024 limit.
- Enable Reverse Proxy: note that changing ports recreates the proxy, and
  document host networking with the two settings it needs.
- Reverse Proxy overview: point BYOP users to the new section.

* docs(reverse-proxy): UFW does not filter Docker-published ports; host mode needs Traefik's ProxyService route
2026-09-30 18:59:24 +02:00
netbirddev 24fe038a7d Update API pages with v0.80.0-rc.2 2026-09-30 12:34:55 +00:00
33d1b212fb docs: describe how reverse proxy services share ports (#997)
* docs: describe how reverse proxy services share ports

The reverse proxy page said every L4 service needs a dedicated port and
that each port can only be used by one service. That is not what the
proxy and management do: the conflict check is per cluster, protocol
and port, so a port takes any number of TLS services (told apart by
SNI), at most one TCP service (the catch-all for unmatched
connections), and, counted separately, at most one UDP service.

Also correct the main-port description: a TCP service may listen on the
main port too, and then receives the connections that match no SNI
route, instead of the HTTP reverse proxy.

Verified against checkPortConflict (management/internals/modules/
reverseproxy/service/manager/manager.go) and handleUnmatched
(proxy/internal/tcp/router.go) in v0.79.0, and on a self-hosted
cluster: TLS services on 443 are routed by SNI, unmatched and plain
TCP connections reach the TCP service on 443, a second TCP service on
443 is rejected with 409, and a UDP service on 443 is accepted
alongside them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: TLS listen ports, custom-port fallback and one domain per service

TLS services always need an explicit listen port, including on clusters
without custom port selection, where the dashboard keeps the field
editable; auto-assignment applies to TCP and UDP. On a custom port with
no TCP service, unmatched and HTTP connections are dropped, and non-TLS
connections on the main port take the same fallback as unmatched SNI.
A domain belongs to one service, so the HTTP/TLS same-hostname warning
now says creation fails. In Docker the main port is 8443, so listen port
443 is a custom port. Drop the ECH example from the no-SNI case.

* docs: HTTP hostnames on a custom port fall back to its TCP service

A request for an HTTP service's hostname on a custom port matches no
route there, so it follows the same fallback as any unmatched
connection: the port's TCP service if it has one, otherwise dropped.

* docs: tighten the L4 port overview and the port-sharing warning

The port-sharing warning read as if a second service of any protocol
fails on a port; only TCP and UDP are limited to one per port, while
TLS services share by SNI. Say that directly, shorten the L4 overview
to a summary that links the two sections holding the rules, and name
the listen port in the TCP and UDP mode descriptions.

---------

Co-authored-by: Janek Härtter <janek@netbird.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Jack Carter <128555021+SunsetDrifter@users.noreply.github.com>
2026-09-28 16:45:23 +02:00
Jack Carter 82f3d74b54 docs: reverse proxy protocols, path prefix matching, active TCP services (#1007)
* docs: reverse proxy protocols, path prefix matching, active TCP services

Add a protocol support section: WebSocket, SSE and HTTP/2 in HTTP mode,
HTTP/1.1 toward cleartext targets (no h2c), and which mode fits gRPC
with and without TLS. Explain that path prefixes match as text, that the
matched prefix is stripped unless Preserve Full Path is on, and how a
trailing slash matches a whole segment. Add a troubleshooting entry for
an active TCP service whose backend does not answer.

* docs: split path matching from prefix stripping, tighten wording

Move the path-matching notes after the existing overview sentence they
were interrupting, and split them into matching (and the trailing-slash
form) and prefix stripping (and Preserve Full Path). Merge two
overlapping sentences on the upstream HTTP version, and shorten the
troubleshooting cause and solution.

* docs: point the active-TCP troubleshooting entry at the listener check

Step 3 of the checklist is an HTTP request, which cannot confirm a TCP
backend such as SSH or RDP; step 6 checks the listening socket and bind
address on the target host.
2026-09-28 16:44:43 +02:00
Jack Carter 588d11fa25 docs: explain how peers pick and switch routing peers (#1004)
Rewrite the High availability section of How Routing Peers Work around the
routing peer selection order (metric, then direct over relayed, then latency),
the events that make a peer switch, and what a switch does to open
connections.

- Name a direct connection falling back to relayed as a switch trigger when
  routing peers share a metric, and state that different metrics prevent it.
- State that, with masquerade on, every switch resets established TCP
  connections, including the failback to a returning primary, which happens
  as soon as the primary reconnects, before a direct connection is back.
- Replace the 20 ms latency threshold with the 10 ms margin the client uses,
  and state that latency is measured when the connection is set up, so a
  peer keeps its routing peer when latency later changes.
- Add where a switch appears in the client log.
- Production checklist: with equal metrics a peer picks by connection type,
  then latency, when it connects; this is not load balancing.
- Exit nodes: retarget the link to the renamed section.
2026-09-28 16:29:17 +02:00
Jack Carter 557b13130c docs: explain the per-peer lazy connection override and DNS warm-up scope (#1006) 2026-09-28 14:46:40 +02:00
Jack Carter d5f4dbfa8a Reverse proxy: the server must reach its own public IP (#1002)
The proxy's embedded NetBird client connects to Signal and the relay at the
NetBird domain's public address, even when the proxy reaches Management over the
Docker network. Without hairpin NAT every proxied service times out; split DNS
works but forces relayed connections.
2026-09-28 14:10:33 +02:00
Jack Carter ec1c1c14db HA guide: add the auth block and deploy the flow receiver and enricher (#1001)
Step 7's config.yaml had no auth block, and the combined server exits without one
(issuer is required). The guide also enabled trafficFlow without deploying the
services that receive and store traffic events. Add both, the receiver's subject
under the traffic-events stream, its secret (the relay secret), and the
/flow.FlowService/ route on the Management load balancer.
2026-09-28 14:09:59 +02:00
Jack Carter c6e5853465 Enterprise custom TLS: NetBird Proxy needs the private CA too (#1000)
With a private-CA certificate the proxy container registers as online but cannot reach Signal until it trusts the CA. Document giving it a CA bundle through docker-compose.override.yml, which getting-started-enterprise.sh does not regenerate.
2026-09-28 14:09:16 +02:00
Jack Carter 97f7ca40f9 docs: clarify Signal message encryption and Windows PATH after install (#979)
* docs: clarify Signal message encryption and Windows PATH after install

- how-netbird-works: the Signal candidate message uses NaCl box
  (Curve25519, XSalsa20, Poly1305): a shared key derived from the
  local private key and the remote public key, no separate signature.
  Spell that out so readers with an RSA sign-then-encrypt model do not
  read the sentence as a mistake.
- windows install: both installers add C:\Program Files\NetBird to the
  system PATH, but terminals opened before the install keep the old
  PATH. Add a note to open a new terminal, and use the full exe path in
  the scripted install + setup-key snippets, where the same shell runs
  both commands.

* docs: state that Signal sees the peers' public keys, not the body

* docs: keep bare netbird up in the setup-key snippets, note a new terminal instead

* docs: drop the repeated new-terminal note from the setup-key section
2026-09-28 12:57:33 +02:00
Jack Carter 8eafcdc59e docs: explain why the WireGuard port is not a required firewall rule (#1005) 2026-09-28 11:38:01 +02:00