# Strategies — server-pushed client config Strategies let an admin push client configuration to peers centrally, without touching each device. They are managed from the dashboard's **Strategies** page (`/admin/#strategies`). --- ## How it works 1. **Storage.** A strategy is a row with a name and a `config_options` JSON object (plus an `extra` object, reserved — currently always `{}`). The Strategies page validates only that `config_options` is a valid JSON **object**; it does **not** validate the keys inside it. 2. **Delivery.** On each peer heartbeat the server resolves the applicable strategy and embeds it in the reply as `strategy.config_options`. Changes propagate within ~15 s of the strategy row's `modified_at` changing. 3. **Apply.** The client merges every key/value straight into its own options map (the same store behind "advanced settings" and the `--config` deploy blob). A strategy key is therefore *any* key the RustDesk client reads via `Config::get_option`. ### Resolution order (per peer) The first match wins: 1. Direct peer-scoped assignment (`strategy_assignments.peer_id`) 2. Device-group assignment, via the peer's owner 3. User assignment If nothing matches, an empty config is pushed. ### Value conventions - **All values are strings**, even numbers (`"30"`, not `30`). - **Boolean keys** use `"Y"` (on) / `"N"` (off). Most default to off when unset. - **An empty string `""`** removes the override and lets the client fall back to its built-in default. (If a built-in default settings blob is present, an empty value instead keeps the key present.) - Keys the client version doesn't recognize are stored, pushed, and silently ignored — there is **no error feedback for typos**. Verify against the `keys` module in `libs/hbb_common/src/config.rs` of the client version you deploy. ### Example ```json { "enable-keyboard": "N", "enable-file-transfer": "N", "access-mode": "view", "image_quality": "best", "whitelist": "192.168.1.0/24,10.0.0.0/8", "verification-method": "use-permanent-password" } ``` --- ## Known config keys The keys below are the complete set defined in the client's `keys` module (`libs/hbb_common/src/config.rs`). Not all are equally useful in a server-managed strategy — UI-state keys (peer tabs, toolbar, floating window) are listed for completeness but are normally per-user. ### Access control & permissions | Key | Values | Effect | |---|---|---| | `access-mode` | `full` / `view` / `custom` | Overall permission preset for incoming sessions | | `enable-keyboard` | `Y`/`N` | Allow remote keyboard input | | `enable-clipboard` | `Y`/`N` | Allow clipboard sync | | `enable-file-transfer` | `Y`/`N` | Allow file transfer | | `enable-camera` | `Y`/`N` | Allow camera access | | `enable-terminal` | `Y`/`N` | Allow terminal access | | `terminal-persistent` | `Y`/`N` | Keep terminal sessions persistent | | `enable-audio` | `Y`/`N` | Allow audio | | `enable-tunnel` | `Y`/`N` | Allow TCP tunnelling | | `enable-remote-restart` | `Y`/`N` | Allow remote restart of the host | | `enable-record-session` | `Y`/`N` | Allow session recording | | `enable-block-input` | `Y`/`N` | Allow blocking local input | | `enable-privacy-mode` | `Y`/`N` | Allow privacy mode | | `enable-perm-change-in-accept-window` | `Y`/`N` | Allow changing permissions in the accept dialog | | `allow-remote-config-modification` | `Y`/`N` | Allow remote side to change this host's config | | `allow-numeric-one-time-password` | `Y`/`N` | Permit numeric one-time passwords | | `approve-mode` | `password` / `click` / `password-click` | How incoming connections are approved | | `verification-method` | `use-temporary-password` / `use-permanent-password` / `use-both-passwords` | Password verification mode | | `temporary-password-length` | `6` / `8` / `10` | Length of generated one-time passwords | | `allow-only-conn-window-open` | `Y`/`N` | Only accept connections while the connection window is open | | `allow-auto-disconnect` | `Y`/`N` | Auto-disconnect idle sessions | | `auto-disconnect-timeout` | minutes | Idle timeout for auto-disconnect | | `approve-mode` | see above | (alias note: stored as `approve-mode`) | | `enable-trusted-devices` | `Y`/`N` | Enable the trusted-devices feature | | `allow-logon-screen-password` | `Y`/`N` | Allow password entry on the logon screen | | `disable-change-permanent-password` | `Y`/`N` | Prevent the user changing the permanent password | | `disable-change-id` | `Y`/`N` | Prevent the user changing the device ID | | `disable-unlock-pin` | `Y`/`N` | Disable the unlock PIN feature | ### Network & connectivity | Key | Values | Effect | |---|---|---| | `custom-rendezvous-server` | host | ID/rendezvous server address | | `relay-server` | host | Relay server address | | `api-server` | URL | API server address | | `key` | string | Server public key | | `ice-servers` | string | ICE servers for WebRTC | | `direct-server` | `Y`/`N` | Enable direct IP access listener | | `direct-access-port` | port | Port for direct IP access | | `enable-udp-punch` | `Y`/`N` | Enable UDP hole punching | | `enable-ipv6-punch` | `Y`/`N` | Enable IPv6 hole punching | | `disable-udp` | `Y`/`N` | Disable UDP (force TCP) | | `allow-websocket` | `Y`/`N` | Allow WebSocket transport | | `allow-insecure-tls-fallback` | `Y`/`N` | Allow falling back to insecure TLS | | `enable-lan-discovery` | `Y`/`N` | Allow discovery on the local network | | `whitelist` | IPs/CIDRs | Comma/space/`;`-separated allow-list; empty = allow all | | `allow-https-21114` | `Y`/`N` | Use HTTPS on port 21114 | | `use-raw-tcp-for-api` | `Y`/`N` | Use raw TCP for the API connection | | `allow-hostname-as-id` | `Y`/`N` | Allow using the hostname as device ID | | `proxy-url` | URL | Proxy server URL | | `proxy-username` | string | Proxy username | | `proxy-password` | string | Proxy password | ### Display, codec & quality | Key | Values | Effect | |---|---|---| | `view_style` | `original` / `adaptive` | Remote display scaling | | `scroll_style` | `scrollauto` / `scrollbar` | Scroll behaviour | | `image_quality` | `best` / `balanced` / `low` / `custom` | Image quality preset | | `custom_image_quality` | `10`–`4095` | Custom quality value | | `custom-fps` | `5`–`120` | Custom frame rate | | `codec-preference` | `auto` / `vp8` / `vp9` / `av1` / `h264` / `h265` | Preferred video codec | | `enable-hwcodec` | `Y`/`N` | Enable hardware codec | | `enable-abr` | `Y`/`N` | Enable adaptive bitrate | | `i444` | `Y`/`N` | Use YUV 4:4:4 (true colour) | | `av1-test` | `Y`/`N` | Enable AV1 test path | | `zoom-cursor` | `Y`/`N` | Zoom the remote cursor | | `show_remote_cursor` | `Y`/`N` | Show the remote cursor | | `follow_remote_cursor` | `Y`/`N` | Follow the remote cursor | | `follow_remote_window` | `Y`/`N` | Follow the remote active window | | `show_quality_monitor` | `Y`/`N` | Show the quality monitor overlay | | `show_monitors_toolbar` | `Y`/`N` | Show the monitors toolbar | | `collapse_toolbar` | `Y`/`N` | Start with the toolbar collapsed | | `view_only` | `Y`/`N` | Open sessions view-only by default | | `touch-mode` | `Y`/`N` | Enable touch mode | | `displays_as_individual_windows` | `Y`/`N` | Show each remote display in its own window | | `use_all_my_displays_for_the_remote_session` | `Y`/`N` | Use all local displays for the session | | `use-texture-render` | `Y`/`N` | Use texture rendering | | `allow-d3d-render` | `Y`/`N` | Allow Direct3D rendering | | `enable-directx-capture` | `Y`/`N` | Use DirectX for screen capture | | `allow-always-software-render` | `Y`/`N` | Force software rendering | | `allow-linux-headless` | `Y`/`N` | Allow headless mode on Linux | ### Input | Key | Values | Effect | |---|---|---| | `reverse_mouse_wheel` | `Y`/`N` | Reverse mouse-wheel direction | | `swap-left-right-mouse` | `Y`/`N` | Swap mouse buttons | | `trackpad-speed` | `10`–`1000` | Trackpad speed (percent) | | `edge-scroll-edge-thickness` | `20`–`150` | Edge-scroll trigger thickness | ### Recording, files & clipboard | Key | Values | Effect | |---|---|---| | `allow-auto-record-incoming` | `Y`/`N` | Auto-record incoming sessions | | `allow-auto-record-outgoing` | `Y`/`N` | Auto-record outgoing sessions | | `video-save-directory` | path | Directory for recordings | | `enable-file-copy-paste` | `Y`/`N` | Allow file copy/paste | | `file-transfer-max-files` | number | Max files per transfer request | | `one-way-file-transfer` | `Y`/`N` | Restrict file transfer to one direction | | `sync-init-clipboard` | `Y`/`N` | Sync clipboard at session start | | `disable_clipboard` | `Y`/`N` | Disable clipboard | | `disable_audio` | `Y`/`N` | Disable audio | | `one-way-clipboard-redirection` | `Y`/`N` | One-way clipboard redirection | | `lock_after_session_end` | `Y`/`N` | Lock the host after a session ends | | `privacy_mode` | `Y`/`N` | Enable privacy mode for the session | ### Printer | Key | Values | Effect | |---|---|---| | `enable-remote-printer` | `Y`/`N` | Enable remote printing | | `printer-incomming-job-action` | string | Action for incoming print jobs (note: key is spelled `incomming`) | | `allow-printer-auto-print` | `Y`/`N` | Allow automatic printing | | `printer-selected-name` | string | Selected printer name | ### Update behaviour | Key | Values | Effect | |---|---|---| | `enable-check-update` | `Y`/`N` | Check for updates | | `allow-auto-update` | `Y`/`N` | Allow automatic updates | ### Power & session | Key | Values | Effect | |---|---|---| | `keep-screen-on` | string | Keep the screen on | | `keep-awake-during-incoming-sessions` | `Y`/`N` | Keep host awake during incoming sessions | | `keep-awake-during-outgoing-sessions` | `Y`/`N` | Keep client awake during outgoing sessions | | `allow-ask-for-note` | `Y`/`N` | Prompt for a session note | | `pre-elevate-service` | `Y`/`N` | Pre-elevate the service | | `register-device` | `Y`/`N` | Register the device with the API server | ### UI visibility / branding lockdown | Key | Values | Effect | |---|---|---| | `hide-security-settings` | `Y`/`N` | Hide the Security settings tab | | `hide-network-settings` | `Y`/`N` | Hide the Network settings tab | | `hide-server-settings` | `Y`/`N` | Hide the Server settings tab | | `hide-proxy-settings` | `Y`/`N` | Hide the Proxy settings tab | | `hide-remote-printer-settings` | `Y`/`N` | Hide remote-printer settings | | `hide-websocket-settings` | `Y`/`N` | Hide WebSocket settings | | `hide-stop-service` | `Y`/`N` | Hide the "stop service" control | | `hide-tray` | `Y`/`N` | Hide the system-tray icon | | `hide-powered-by-me` | `Y`/`N` | Hide "powered by" branding | | `hide-username-on-card` | `Y`/`N` | Hide username on peer cards | | `hide-help-cards` | `Y`/`N` | Hide help cards | | `hideAbTagsPanel` | `Y`/`N` | Hide the address-book tags panel | | `main-window-always-on-top` | `Y`/`N` | Keep the main window on top | | `theme` | `light` / `dark` / `system` | UI theme | | `lang` | language code | UI language | | `remote-menubar-drag-left` | `Y`/`N` | Allow dragging the left remote menubar | | `remote-menubar-drag-right` | `Y`/`N` | Allow dragging the right remote menubar | | `enable-confirm-closing-tabs` | `Y`/`N` | Confirm before closing tabs | | `enable-open-new-connections-in-tabs` | `Y`/`N` | Open new connections in tabs | | `disable-group-panel` | `Y`/`N` | Hide the group panel | | `disable-discovery-panel` | `Y`/`N` | Hide the discovery panel | ### Address book | Key | Values | Effect | |---|---|---| | `sync-ab-with-recent-sessions` | `Y`/`N` | Sync address book with recent sessions | | `sync-ab-tags` | `Y`/`N` | Sync address-book tags | | `filter-ab-by-intersection` | `Y`/`N` | Filter address book by tag intersection | ### Deep links | Key | Values | Effect | |---|---|---| | `allow-deep-link-password` | `Y`/`N` | Allow passwords in deep links | | `allow-deep-link-server-settings` | `Y`/`N` | Allow server settings in deep links | ### Preset values (deploy/provisioning) These pre-fill fields during enrollment/deploy rather than gating behaviour. | Key | Effect | |---|---| | `display-name` | Device display name | | `avatar` | Device avatar | | `default-connect-password` | Default connection password | | `remove-preset-password-warning` | Suppress the preset-password warning | | `preset-user-name` | Pre-fill username | | `preset-strategy-name` | Pre-fill strategy name | | `preset-device-group-name` | Pre-fill device group | | `preset-device-username` | Pre-fill device username | | `preset-device-name` | Pre-fill device name | | `preset-note` | Pre-fill session note | | `preset-address-book-name` | Pre-fill address-book name | | `preset-address-book-tag` | Pre-fill address-book tag | | `preset-address-book-alias` | Pre-fill address-book alias | | `preset-address-book-password` | Pre-fill address-book password | | `preset-address-book-note` | Pre-fill address-book note | ### Android / mobile | Key | Values | Effect | |---|---|---| | `show-virtual-mouse` | `Y`/`N` | Show the virtual mouse | | `show-virtual-joystick` | `Y`/`N` | Show the virtual joystick (also set `show-virtual-mouse`) | | `disable-floating-window` | `Y`/`N` | Disable the floating window | | `floating-window-size` | string | Floating-window size | | `floating-window-untouchable` | `Y`/`N` | Make the floating window non-interactive | | `floating-window-transparency` | number | Floating-window transparency | | `floating-window-svg` | string | Floating-window SVG icon | | `enable-android-software-encoding-half-scale` | `Y`/`N` | Half-scale Android software encoding | ### UI state (normally per-user — listed for completeness) `remoteMenubarState`, `peer-sorting`, `peer-tab-index`, `peer-tab-order`, `peer-tab-visible`, `peer-card-ui-type`, `current-ab-name`, `enable-flutter-http-on-rust`, `allow-remote-cm-modification`. --- ## Notes & caveats - The list above reflects the client `keys` module at documentation time. Newer clients may add keys; older clients will ignore keys they don't know. There is no negotiation — match the doc to the client version you actually deploy. - Some keys also exist as hbbs/hbbr command-line flags (`custom-rendezvous-server`, `relay-server`, `key`, …). Pushing them via a strategy overrides the client's local value; it does not change the server. - The `extra` object on a strategy row is reserved and currently always `{}` — there is no UI to populate it. - For the overall configuration picture see [CONFIGURATION.md](CONFIGURATION.md#strategies-server-pushed-config).