diff --git a/src/pages/client/desktop-app.mdx b/src/pages/client/desktop-app.mdx
index 1959f6a6..f79a88dd 100644
--- a/src/pages/client/desktop-app.mdx
+++ b/src/pages/client/desktop-app.mdx
@@ -83,9 +83,11 @@ The settings page uses a tabbed layout that groups options by what they control.
and as LocalSystem on Windows while the app runs as you. The app shows those
switches as unavailable and puts the equivalent command next to them: run it with
`sudo` on Linux and macOS, or from an elevated prompt on Windows. Without those
- rights, an administrator has to run it, or push the setting through
- [MDM](#mdm-driven-ui), which the client applies itself. A switch that is already
- on stays operable, since turning these settings off never requires privileges.
+ rights, an administrator has to run it. The SSH server alone can also be turned on
+ from [MDM](#mdm-driven-ui) policy with `allowServerSSH`, which the client applies
+ itself; root login and SSH authentication have no policy key. A switch already in its safe
+ state stays operable: turning the SSH server off, turning root login off, and
+ re-enabling SSH authentication never require privileges.
**Connect on Startup** controls whether the background service reconnects when it starts. **Launch NetBird UI at Login** controls only whether the graphical interface opens when you sign in to the operating system. On a fresh desktop installation, launch at login is enabled once by default. Upgrades preserve the user's existing preference. Administrators can manage this behavior with [`disableAutostart`](/client/mdm-integration#disableAutostart).
diff --git a/src/pages/client/grpc-socket.mdx b/src/pages/client/grpc-socket.mdx
index 5f9624ea..f258203d 100644
--- a/src/pages/client/grpc-socket.mdx
+++ b/src/pages/client/grpc-socket.mdx
@@ -113,7 +113,7 @@ netbird --daemon-addr tcp://127.0.0.1:41731 status
## Privileged Operations
-Any local user can reach the socket, so the daemon authorizes individual operations
+On the default sockets any local user can connect, so the daemon authorizes operations
by the identity of whoever calls it, read from the kernel rather than supplied by
the client: `SO_PEERCRED` on Linux, `LOCAL_PEERCRED` on macOS, and the named-pipe
client token on Windows. A caller whose identity cannot be established is refused.
@@ -127,12 +127,21 @@ they decide who may obtain a shell on the machine:
| Enable SSH root login | the caller is not privileged |
| Disable SSH authentication | the caller is not privileged |
| Change the management URL | the caller is not privileged and that profile has the SSH server enabled |
-| Deregister the peer (logout, profile removal) | the caller is not privileged and that profile has the SSH server enabled |
+| Deregister the peer (logout) | the caller is not privileged and that profile has the SSH server enabled |
-Only the direction that creates the capability is guarded. Turning any of them off
-is always allowed, and restating a value that is already set is not a change, so an
-integration that submits a whole settings form does not start failing once an
-administrator enables SSH.
+Only the direction that creates the capability is guarded. Turning the SSH server or
+root login off, and re-enabling SSH authentication, are always allowed, and restating a
+value that is already set is not a change, so an integration that submits a whole
+settings form does not start failing once an administrator enables SSH.
+
+Removing a profile is not refused. An unprivileged caller removes it locally and the
+daemon skips the deregistration, which leaves the peer registered on the management
+server rather than detached from it.
+
+A profile written before the SSH server flag existed counts as having it enabled,
+because the daemon reads an unset flag the same way the engine does. The management URL
+and deregistration guards therefore apply on those installations even though nobody
+enabled SSH explicitly.
A refusal comes back as gRPC `PermissionDenied` carrying a `google.rpc.ErrorInfo`
detail, so an integration can recognise it without parsing the message:
diff --git a/src/pages/get-started/cli.mdx b/src/pages/get-started/cli.mdx
index 64347944..b5d86159 100644
--- a/src/pages/get-started/cli.mdx
+++ b/src/pages/get-started/cli.mdx
@@ -509,7 +509,9 @@ For SFTP and SCP, use native clients (`sftp` and `scp` commands) which work with
**Connection fails:**
-- Ensure SSH is enabled on the target peer, which requires root or an administrator:
+- Ensure SSH is enabled on the target peer, which requires root or an administrator.
+ The commands below use `sudo` for Linux and macOS; on Windows run the same ones
+ without it, from an elevated prompt:
```shell
sudo netbird down; sudo netbird up --allow-server-ssh
```
@@ -520,13 +522,16 @@ For SFTP and SCP, use native clients (`sftp` and `scp` commands) which work with
- Complete the OIDC flow when prompted (browser window will open)
- Verify your IdP is properly configured
-- To disable JWT authentication, as root or an administrator: `sudo netbird down; sudo netbird up --allow-server-ssh --disable-ssh-auth`
+- To disable JWT authentication, as root or an administrator: `sudo netbird down; sudo netbird up --allow-server-ssh --disable-ssh-auth`.
+ This drops per-user authentication for SSH on that peer, leaving any peer the ACL
+ policy allows able to connect, so use it to isolate a problem and re-enable it with
+ `sudo netbird down; sudo netbird up --allow-server-ssh` afterwards.
**Port forwarding not working:**
- Ensure the server has the appropriate flags:
```shell
- sudo netbird up --allow-server-ssh \
+ sudo netbird down; sudo netbird up --allow-server-ssh \
--enable-ssh-local-port-forwarding \
--enable-ssh-remote-port-forwarding
```
@@ -833,7 +838,7 @@ This will output:
-S, --system-info Adds system information to the debug bundle (default true)
-U, --upload-bundle Uploads the debug bundle to a server
--upload-bundle-url string Service URL to get an upload URL for the debug bundle (default "https://upload.debug.netbird.io/upload-url")
- --upload-bundle-insecure Allow uploading to an http or untrusted-TLS upload server (self-hosted); requires root
+ --upload-bundle-insecure Allow uploading to an http or untrusted-TLS upload server (self-hosted); requires root on Linux and macOS, or an administrator on Windows
```
### debug for
@@ -873,7 +878,7 @@ Log level restored to INFO
-S, --system-info Adds system information to the debug bundle (default true)
-U, --upload-bundle Uploads the debug bundle to a server
--upload-bundle-url string Service URL to get an upload URL for the debug bundle (default "https://upload.debug.netbird.io/upload-url")
- --upload-bundle-insecure Allow uploading to an http or untrusted-TLS upload server (self-hosted); requires root
+ --upload-bundle-insecure Allow uploading to an http or untrusted-TLS upload server (self-hosted); requires root on Linux and macOS, or an administrator on Windows
```
### debug log
diff --git a/src/pages/help/troubleshooting-client.mdx b/src/pages/help/troubleshooting-client.mdx
index 52584f94..c73165b0 100644
--- a/src/pages/help/troubleshooting-client.mdx
+++ b/src/pages/help/troubleshooting-client.mdx
@@ -313,6 +313,13 @@ Upload file key:
Uploading to a custom endpoint with `--upload-bundle-url` (for example a self-hosted upload server) requires root/administrator and an `https` URL. To upload to a server that uses `http` or an untrusted TLS certificate, add `--upload-bundle-insecure`.
+
@@ -98,6 +100,7 @@ sudo netbird up --allow-server-ssh For additional SSH server features, use these flags: ```bash +sudo netbird down sudo netbird up --allow-server-ssh \ --enable-ssh-local-port-forwarding \ --enable-ssh-remote-port-forwarding \