feature: managed settings. - #10589
Draft
camilasan wants to merge 17 commits into
Draft
Conversation
camilasan
force-pushed
the
feature/5497/mdm
branch
from
August 19, 2026 15:27
e0beb6d to
24b18b8
Compare
camilasan
force-pushed
the
feature/5497/mdm
branch
from
September 7, 2026 09:41
24b18b8 to
db6b6be
Compare
Move phase, version and legacy discovery out of ConfigFile, Application, AccountManager, AccountState and FolderMan into src/libsync/settings. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
Cover the phase lifecycle, version comparison and legacy discovery. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
Add MIGRATION.md next to the sources. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
camilasan
force-pushed
the
feature/5497/mdm
branch
3 times, most recently
from
September 7, 2026 13:35
6e21f30 to
99cd928
Compare
Resolves the effective value of a setting from a set of injectable sources and returns metadata (winning source, default or locked). Precedence: locked policy, then user config, then the highest default, then the builtin settings. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
Native registry, plist and conf adapters plus buildDeviceSources, replicating the app name selection of ConfigFile::getValue and getPolicySetting. The OS adapters are not unit tested on the Linux build; only the factory is smoke tested. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
…ngs resolver skipUpdateCheck and autoUpdateCheck now go through ManagedSettings with the device sources and the user config, preserving the precedence policy over user over OS default over builtin. The user source carries the connection group so a locked policy still overrides a group scoped user value. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
Add ForcedPreferenceSource, a locked platform policy source that contributes a value only when an administrator forces the key. MacForcedPreferenceSource implements it with CFPreferencesAppValueIsForced and CFPreferencesCopyAppValue, so host and per user managed preferences are honored. buildDeviceSources now uses it on macOS instead of reading the managed preferences plist as a file. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
Add ServerManagedSettings, parsing and an allow list sanitizer for the values the server delivers through the support.desktopClient capability. Only allow listed keys pass, and only server lockable keys stay locked. ServerSettingsSource and buildServerSources expose them as ServerDefault (priority 30) and ServerLocked (priority 100), so device policy still wins. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
Add the end to end resolution flow above ManagedSettings and the server delivery flow above ServerManagedSettings, in the same in header style as Migration. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
An admin enforces settings, so LockState, enforceable, the ServerLocked source kind, and the wire and config keys become EnforcementState, enforceable, ServerEnforced, and enforced. ForcedPreferenceSource keeps Apple's forced term. Also shorten comments. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
getConfig resolves a setting name across the enforcement hierarchy and returns the value with its source and enforcement. getConfigBool/Int/String, setConfig (refused when the value is enforced), isEnforced and sourceOf build on it. skipUpdateCheck and autoUpdateCheck now use it; resolveManagedBool is removed. Also document managed config getConfig gateway design. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
getConfig parsed the server settings JSON from the config file on every call. ManagedConfig caches the parsed settings, keyed by config path and guarded by a read write lock, refreshed on write. ConfigFile serverManagedSettings and setServerManagedSettings delegate to it. Reads stay live for the user and device layers. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
When autoUpdateCheck is enforced by device policy or the server, the checkbox is disabled and its tooltip names who manages it. Populating it does not write the value back, and the toggle saves through setConfig, which refuses an enforced value. skipUpdateCheck still hides the whole updater section. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
A trusted server can suggest but not enforce skipUpdateCheck, autoUpdateCheck and the proxy keys; only device policy enforces them, so a server cannot disable updates or reroute traffic. sanitizeServerManagedSettings drops them from a server enforced payload. Virtual files and folder limits stay server enforceable. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
Test targets compile with QT_NO_KEYWORDS, so the slots keyword does not resolve. Use Q_SLOTS. Assisted-by: Claude Code:claude-opus-4-8 Signed-off-by: Camila Ayres <hello@camilasan.com>
camilasan
force-pushed
the
feature/5497/mdm
branch
from
September 7, 2026 14:03
99cd928 to
47b4cdf
Compare
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.
Resolves
#5497
This PR is branched off #9191.
Managed settings for the desktop client
Adds a managed settings subsystem so an administrator can set or enforce client settings from three inputs, resolved through one precedence hierarchy: device policy (Windows registry, macOS managed preferences), server delivered values (via the support app capability), and the user config.
Design and resolution flow are documented in
src/libsync/settings/README.md.What it does
ManagedSettingsresolver that ranks sources by enforcement state and priority, converts the resolved value to the type declared in the schema, and reports the winning source plus whether it is enforced.Software\PoliciesandSoftwarehives, macOS forced preferences viaCFPreferencesAppValueIsForced, Linux conf.support.desktopClientfrom the capabilities, sanitizes it against a client allow list, caches the parsed values in a thread safeManagedConfigservice, and persists them for offline use.ConfigFile::getConfigplus thegetConfig<T>template, so callers resolve through the hierarchy instead of reading the config directly.setConfigrefuses to overwrite an enforced value.Security
Scope
Update settings (
skipUpdateCheck,autoUpdateCheck) are wired end to end. The remaining allow listed keys (virtual files mode, proxy, folder limits) are accepted and cached but not yet consumed by their accessors; that is a tracked follow up.Tests
Unit tests cover resolution precedence, type conversion, the getConfig gateway,
setConfigrefusal when enforced, server caching and persistence, and allow list sanitization including the dropped server enforced update and proxy keys.Server side
Delivery depends on the support app change (separate repo and PR) exposing
support.desktopClientin the capabilities, gated on an enterprise subscription.Checklist
AI (if applicable)