summaryrefslogtreecommitdiffhomepage
path: root/util/syspolicy
AgeCommit message (Collapse)AuthorFilesLines
2025-09-04util/syspolicy/policyclient: always use no-op policyclient in tests by defaultBrad Fitzpatrick1-1/+9
We should never use the real syspolicy implementation in tests by default. (the machine's configuration shouldn't affect tests) You either specify a test policy, or you get a no-op one. Updates #16998 Change-Id: I3350d392aad11573a5ad7caab919bb3bbaecb225 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-04ipn/ipnlocal, util/syspolicy: convert last RegisterWellKnownSettingsForTest ↵Brad Fitzpatrick4-31/+120
caller, remove Updates #16998 Change-Id: I735d75129a97a929092e9075107e41cdade18944 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-03util/syspolicy: remove handler, other dead codeBrad Fitzpatrick3-125/+0
Fixes #17022 Change-Id: I6a0f6488ae3ea75c5844dfcba68e1e8024e930be Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-03util/syspolicy: delete some unused code in handler.goBrad Fitzpatrick1-17/+2
There's a TODO to delete all of handler.go, but part of it's still used in another repo. But this deletes some. Updates #17022 Change-Id: Ic5a8a5a694ca258440307436731cd92b45ee2d21 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-02ipn/ipnlocal: convert more tests to use policytest, de-global-ifyBrad Fitzpatrick1-22/+65
Now that we have policytest and the policyclient.Client interface, we can de-global-ify many of the tests, letting them run concurrently with each other, and just removing global variable complexity. This does ~half of the LocalBackend ones. Updates #16998 Change-Id: Iece754e1ef4e49744ccd967fa83629d0dca6f66a Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-02util/syspolicy/policytest: move policy test helper to its own packageBrad Fitzpatrick1-0/+117
Updates #16998 Updates #12614 Change-Id: I9fd27d653ebee547951705dc5597481e85b60747 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-02util/syspolicy: finish plumbing policyclient, add feature/syspolicy, move ↵Brad Fitzpatrick3-48/+101
global impl This is step 4 of making syspolicy a build-time feature. This adds a policyclient.Get() accessor to return the correct implementation to use: either the real one, or the no-op one. (A third type, a static one for testing, also exists, so in general a policyclient.Client should be plumbed around and not always fetched via policyclient.Get whenever possible, especially if tests need to use alternate syspolicy) Updates #16998 Updates #12614 Change-Id: Iaf19670744a596d5918acfa744f5db4564272978 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-02ipn/ipnlocal: use policyclient.Client always, stop using global syspolicy funcsBrad Fitzpatrick1-1/+55
Step 4 of N. See earlier commits in the series (via the issue) for the plan. This adds the missing methods to policyclient.Client and then uses it everywhere in ipn/ipnlocal and locks it in with a new dep test. Still plenty of users of the global syspolicy elsewhere in the tree, but this is a lot of them. Updates #16998 Updates #12614 Change-Id: I25b136539ae1eedbcba80124de842970db0ca314 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-02util/syspolicy/{setting,ptype}: move PreferenceOption and Visibility to new ↵Brad Fitzpatrick9-39/+71
leaf package Step 3 in the series. See earlier cc532efc2000 and d05e6dc09e. This step moves some types into a new leaf "ptype" package out of the big "settings" package. The policyclient.Client will later get new methods to return those things (as well as Duration and Uint64, which weren't done at the time of the earlier prototype). Updates #16998 Updates #12614 Change-Id: I4d72d8079de3b5351ed602eaa72863372bd474a2 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-09-01util/syspolicy/policyclient: add policyclient.Client interface, start plumbingBrad Fitzpatrick3-7/+75
This is step 2 of ~4, breaking up #14720 into reviewable chunks, with the aim to make syspolicy be a build-time configurable feature. Step 1 was #16984. In this second step, the util/syspolicy/policyclient package is added with the policyclient.Client interface. This is the interface that's always present (regardless of build tags), and is what code around the tree uses to ask syspolicy/MDM questions. There are two implementations of policyclient.Client for now: 1) NoPolicyClient, which only returns default values. 2) the unexported, temporary 'globalSyspolicy', which is implemented in terms of the global functions we wish to later eliminate. This then starts to plumb around the policyclient.Client to most callers. Future changes will plumb it more. When the last of the global func callers are gone, then we can unexport the global functions and make a proper policyclient.Client type and constructor in the syspolicy package, removing the globalSyspolicy impl out of tsd. The final change will sprinkle build tags in a few more places and lock it in with dependency tests to make sure the dependencies don't later creep back in. Updates #16998 Updates #12614 Change-Id: Ib2c93d15c15c1f2b981464099177cd492d50391c Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-08-31util/syspolicy/*: move syspolicy keys to new const leaf "pkey" packageBrad Fitzpatrick24-455/+479
This is step 1 of ~3, breaking up #14720 into reviewable chunks, with the aim to make syspolicy be a build-time configurable feature. In this first (very noisy) step, all the syspolicy string key constants move to a new constant-only (code-free) package. This will make future steps more reviewable, without this movement noise. There are no code or behavior changes here. The future steps of this series can be seen in #14720: removing global funcs from syspolicy resolution and using an interface that's plumbed around instead. Then adding build tags. Updates #12614 Change-Id: If73bf2c28b9c9b1a408fe868b0b6a25b03eeabd1 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-07-28util/syspolicy/setting: use a custom marshaler for time.DurationNick Khyl2-1/+32
jsonv2 now returns an error when you marshal or unmarshal a time.Duration without an explicit format flag. This is an intentional, temporary choice until the default [time.Duration] representation is decided (see golang/go#71631). setting.Snapshot can hold time.Duration values inside a map[string]any, so the jsonv2 update breaks marshaling. In this PR, we start using a custom marshaler until that decision is made or golang/go#71664 lets us specify the format explicitly. This fixes `tailscale syspolicy list` failing when KeyExpirationNotice or any other time.Duration policy setting is configured. Fixes #16683 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-07-08ipn/ipnlocal,util/syspolicy: add support for ExitNode.AllowOverride policy ↵Nick Khyl2-0/+15
setting When the policy setting is enabled, it allows users to override the exit node enforced by the ExitNodeID or ExitNodeIP policy. It's primarily intended for use when ExitNodeID is set to auto:any, but it can also be used with specific exit nodes. It does not allow disabling exit node usage entirely. Once the exit node policy is overridden, it will not be enforced again until the policy changes, the user connects or disconnects Tailscale, switches profiles, or disables the override. Updates tailscale/corp#29969 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-07-07ipn/{ipnauth,ipnlocal,localapi}: make EditPrefs return an error if changing ↵Nick Khyl1-1/+4
exit node is restricted by policy We extract checkEditPrefsAccessLocked, adjustEditPrefsLocked, and onEditPrefsLocked from the EditPrefs execution path, defining when each step is performed and what behavior is allowed at each stage. Currently, this is primarily used to support Always On mode, to handle the Exit Node enablement toggle, and to report prefs edit metrics. We then use it to enforce Exit Node policy settings by preventing users from setting an exit node and making EditPrefs return an error when an exit node is restricted by policy. This enforcement is also extended to the Exit Node toggle. These changes prepare for supporting Exit Node overrides when permitted by policy and preventing logout while Always On mode is enabled. In the future, implementation of these methods can be delegated to ipnext extensions via the feature hooks. Updates tailscale/corp#29969 Updates tailscale/corp#26249 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-07-07util/syspolicy: add HasAnyOf to check if any specified policy settings are ↵Nick Khyl1-0/+21
configured Updates tailscale/corp#29969 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-07-07ipn/ipnlocal,util/syspolicy/source: retain existing exit node when using ↵Nick Khyl1-0/+7
auto exit node, if it's allowed by policy In this PR, we update setExitNodeID to retain the existing exit node if auto exit node is enabled, the current exit node is allowed by policy, and no suggested exit node is available yet. Updates tailscale/corp#29969 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-06-26ipn/store: automatically migrate between plaintext and encrypted state (#16318)Andrew Lytvynov1-0/+5
Add a new `--encrypt-state` flag to `cmd/tailscaled`. Based on that flag, migrate the existing state file to/from encrypted format if needed. Updates #15830 Signed-off-by: Andrew Lytvynov <awly@tailscale.com>
2025-06-03posture: propagate serial number from MDM on AndroidAnton Tolchanov1-2/+2
Updates #16010 Signed-off-by: Anton Tolchanov <anton@tailscale.com>
2025-05-12net/dns,docs/windows/policy,util/syspolicy: register Tailscale IP addresses ↵Nick Khyl2-0/+16
in AD DNS if required by policy In this PR, we make DNS registration behavior configurable via the EnableDNSRegistration policy setting. We keep the default behavior unchanged, but allow admins to either enforce DNS registration and dynamic DNS updates for the Tailscale interface, or prevent Tailscale from modifying the settings configured in the network adapter's properties or by other means. Updates #14917 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-04-08all: unify some redundant testing.TB interface copiesBrad Fitzpatrick13-37/+26
I added yet another one in 6d117d64a256234 but that new one is at the best place int he dependency graph and has the best name, so let's use that one for everything possible. types/lazy can't use it for circular dependency reasons, so unexport that copy at least. Updates #cleanup Change-Id: I25db6b6a0d81dbb8e89a0a9080c7f15cbf7aa770 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-02-27all: statically enforce json/v2 interface satisfaction (#15154)Joe Tsai4-0/+25
The json/v2 prototype is still in flux and the API can/will change. Statically enforce that types implementing the v2 methods satisfy the correct interface so that changes to the signature can be statically detected by the compiler. Updates tailscale/corp#791 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2025-02-27go.mod: bump github.com/go-json-experiment/json (#15010)Joe Tsai5-43/+43
The upstream module has seen significant work making the v1 emulation layer a high fidelity re-implementation of v1 "encoding/json". This addresses several upstream breaking changes: * MarshalJSONV2 renamed as MarshalJSONTo * UnmarshalJSONV2 renamed as UnmarshalJSONFrom * Options argument removed from MarshalJSONV2 * Options argument removed from UnmarshalJSONV2 Updates tailscale/corp#791 Signed-off-by: Joe Tsai <joetsai@digital-static.net>
2025-02-24ipn/ipnlocal,util/syspolicy,docs/windows/policy: implement the ↵Nick Khyl1-0/+7
ReconnectAfter policy setting In this PR, we update the LocalBackend so that when the ReconnectAfter policy setting is configured and a user disconnects Tailscale by setting WantRunning to false in the profile prefs, the LocalBackend will now start a timer to set WantRunning back to true once the ReconnectAfter timer expires. We also update the ADMX/ADML policy definitions to allow configuring this policy setting for Windows via Group Policy and Intune. Updates #14824 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-02-01client/tailscale,ipn/ipn{local,server},util/syspolicy: implement the ↵Nick Khyl1-1/+8
AlwaysOn.OverrideWithReason policy setting In this PR, we update client/tailscale.LocalClient to allow sending requests with an optional X-Tailscale-Reason header. We then update ipn/ipnserver.{actor,Server} to retrieve this reason, if specified, and use it to determine whether ipnauth.Disconnect is allowed when the AlwaysOn.OverrideWithReason policy setting is enabled. For now, we log the reason, along with the profile and OS username, to the backend log. Finally, we update LocalBackend to remember when a disconnect was permitted and do not reconnect automatically unless the policy changes. Updates tailscale/corp#26146 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-02-01util/syspolicy/internal/metrics: replace dots with underscores for metric namesNick Khyl1-0/+1
Dots are not allowed in metric names and cause panics. Since we use dots in names like AlwaysOn.OverrideWithReason, let's replace them with underscores. We don’t want to use setting.KeyPathSeparator here just yet to make it fully hierarchical, but we will decide as we progress on the (experimental) AlwaysOn.* policy settings. tailscale/corp#26146 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-31ipn/ipnauth,util/syspolicy: improve commentsNick Khyl1-0/+1
Updates #cleanup Updates #14823 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-31ipn/ipn{auth,server,local}: initial support for the always-on modeNick Khyl1-0/+10
In this PR, we update LocalBackend to set WantRunning=true when applying policy settings to the current profile's prefs, if the "always-on" mode is enabled. We also implement a new (*LocalBackend).EditPrefsAs() method, which is like EditPrefs but accepts an actor (e.g., a LocalAPI client's identity) that initiated the change. If WantRunning is being set to false, the new EditPrefsAs method checks whether the actor has ipnauth.Disconnect access to the profile and propagates an error if they do not. Finally, we update (*ipnserver.actor).CheckProfileAccess to allow a disconnect only if the "always-on" mode is not enabled by the AlwaysOn policy setting. This is not a comprehensive solution to the "always-on" mode across platforms, as instead of disconnecting a user could achieve the same effect by creating a new empty profile, initiating a reauth, or by deleting the profile. These are the things we should address in future PRs. Updates #14823 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-23cmd/tailscaled,util/syspolicy/source,util/winutil/gp: disallow acquiring the ↵Nick Khyl1-2/+80
GP lock during service startup In v1.78, we started acquiring the GP lock when reading policy settings. This led to a deadlock during Tailscale installation via Group Policy Software Installation because the GP engine holds the write lock for the duration of policy processing, which in turn waits for the installation to complete, which in turn waits for the service to enter the running state. In this PR, we prevent the acquisition of GP locks (aka EnterCriticalPolicySection) during service startup and update the Windows Registry-based util/syspolicy/source.PlatformPolicyStore to handle this failure gracefully. The GP lock is somewhat optional; it’s safe to read policy settings without it, but acquiring the lock is recommended when reading multiple values to prevent the Group Policy engine from modifying settings mid-read and to avoid inconsistent results. Fixes #14416 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2025-01-22util/slicesx: add AppendNonzeroBrad Fitzpatrick1-3/+1
By request of @agottardo. Updates #cleanup Change-Id: I2f02314eb9533b1581e47b66b45b6fb8ac257bb7 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2025-01-17ipnlocal: allow overriding os.Hostname() via syspolicy (#14676)Andrea Gottardo1-0/+6
Updates tailscale/corp#25936 This defines a new syspolicy 'Hostname' and allows an IT administrator to override the value we normally read from os.Hostname(). This is particularly useful on Android and iOS devices, where the hostname we get from the OS is really just the device model (a platform restriction to prevent fingerprinting). If we don't implement this, all devices on the customer's side will look like `google-pixel-7a-1`, `google-pixel-7a-2`, `google-pixel-7a-3`, etc. and it is not feasible for the customer to use the API or worse the admin console to manually fix these names. Apply code review comment by @nickkhyl Signed-off-by: Andrea Gottardo <andrea@gottardo.me> Co-authored-by: Nick Khyl <1761190+nickkhyl@users.noreply.github.com>
2025-01-03util/slicesx: add MapKeys and MapValues from golang.org/x/exp/mapsBrad Fitzpatrick1-1/+2
Importing the ~deprecated golang.org/x/exp/maps as "xmaps" to not shadow the std "maps" was getting ugly. And using slices.Collect on an iterator is verbose & allocates more. So copy (x)maps.Keys+Values into our slicesx package instead. Updates #cleanup Updates #12912 Updates #14514 (pulled out of that change) Change-Id: I5e68d12729934de93cf4a9cd87c367645f86123a Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-11-22util/syspolicy/rsop: reduce policyReloadMinDelay and policyReloadMaxDelay ↵Nick Khyl3-9/+15
when in tests These delays determine how soon syspolicy change callbacks are invoked after a policy setting is updated in a policy source. For tests, we shorten these delays to minimize unnecessary wait times. This adjustment only affects tests that subscribe to policy change notifications and modify policy settings after they have already been set. Initial policy settings are always available immediately without delay. Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-10-31util/syspolicy: add policy key for onboarding flow visibilityAaron Klotz1-0/+4
Updates https://github.com/tailscale/corp/issues/23789 Signed-off-by: Aaron Klotz <aaron@tailscale.com>
2024-10-30util/syspolicy/source: put EnvPolicyStore env keys in their own namespaceBrad Fitzpatrick2-41/+46
... all prefixed with TS_DEBUGSYSPOLICY_*. Updates #13193 Updates #12687 Updates #13855 Change-Id: Ia8024946f53e2b3afda4456a7bb85bbcf6d12bfc Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2024-10-30util/syspolicy/setting: make setting.Snapshot JSON-marshallableNick Khyl2-0/+180
We make setting.Snapshot JSON-marshallable in preparation for returning it from the LocalAPI. Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-10-30util/syspolicy/setting: make setting.RawItem JSON-marshallableNick Khyl3-140/+335
We add setting.RawValue, a new type that facilitates unmarshalling JSON numbers and arrays as uint64 and []string (instead of float64 and []any) for policy setting values. We then use it to make setting.RawItem JSON-marshallable and update the tests. Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-10-30util/syspolicy/source: use errors instead of github.com/pkg/errorsNick Khyl1-1/+1
Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-10-30util/syspolicy: implement a syspolicy store that reads settings from ↵Nick Khyl5-5/+518
environment variables In this PR, we implement (but do not use yet, pending #13727 review) a syspolicy/source.Store that reads policy settings from environment variables. It converts a CamelCase setting.Key, such as AuthKey or ExitNodeID, to a SCREAMING_SNAKE_CASE, TS_-prefixed environment variable name, such as TS_AUTH_KEY and TS_EXIT_NODE_ID. It then looks up the variable and attempts to parse it according to the expected value type. If the environment variable is not set, the policy setting is considered not configured in this store (the syspolicy package will still read it from other sources). Similarly, if the environment variable has an invalid value for the setting type, it won't be used (though the reported/logged error will differ). Updates #13193 Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-10-25util/syspolicy, ipn/ipnlocal: update syspolicy package to utilize syspolicy/rsopNick Khyl11-741/+738
In this PR, we update the syspolicy package to utilize syspolicy/rsop under the hood, and remove syspolicy.CachingHandler, syspolicy.windowsHandler and related code which is no longer used. We mark the syspolicy.Handler interface and RegisterHandler/SetHandlerForTest functions as deprecated, but keep them temporarily until they are no longer used in other repos. We also update the package to register setting definitions for all existing policy settings and to register the Registry-based, Windows-specific policy stores when running on Windows. Finally, we update existing internal and external tests to use the new API and add a few more tests and benchmarks. Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-10-16util/syspolicy: add rsop package that provides access to the resultant policyNick Khyl9-18/+1834
In this PR we add syspolicy/rsop package that facilitates policy source registration and provides access to the resultant policy merged from all registered sources for a given scope. Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-10-08util/syspolicy, ipn: add "tailscale debug component-logs" supportNick Khyl3-12/+89
Fixes #13313 Fixes #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-10-08util/syspolicy/setting: update Snapshot to use Go 1.23 iteratorsNick Khyl1-14/+11
Updates #12912 Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-09-04control/controlclient,posture,util/syspolicy: use predefined syspolicy keys ↵Nick Khyl1-0/+8
instead of string literals With the upcoming syspolicy changes, it's imperative that all syspolicy keys are defined in the syspolicy package for proper registration. Otherwise, the corresponding policy settings will not be read. This updates a couple of places where we still use string literals rather than syspolicy consts. Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-09-03util/syspolicy/source: add package for reading policy settings from external ↵Nick Khyl11-2/+3009
stores We add package defining interfaces for policy stores, enabling creation of policy sources and reading settings from them. It includes a Windows-specific PlatformPolicyStore for GP and MDM policies stored in the Registry, and an in-memory TestStore for testing purposes. We also include an internal package that tracks and reports policy usage metrics when a policy setting is read from a store. Initially, it will be used only on Windows and Android, as macOS, iOS, and tvOS report their own metrics. However, we plan to use it across all platforms eventually. Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-08-19ipnlocal: support setting authkey at login using syspolicy (#13061)Andrea Gottardo1-0/+4
Updates tailscale/corp#22120 Adds the ability to start the backend by reading an authkey stored in the syspolicy database (MDM). This is useful for devices that are provisioned in an unattended fashion. Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
2024-08-12util/syspolicy/setting: add package that contains types for the next ↵Nick Khyl16-85/+2605
syspolicy PRs Package setting contains types for defining and representing policy settings. It facilitates the registration of setting definitions using Register and RegisterDefinition, and the retrieval of registered setting definitions via Definitions and DefinitionOf. This package is intended for use primarily within the syspolicy package hierarchy, and added in a preparation for the next PRs. Updates #12687 Signed-off-by: Nick Khyl <nickk@tailscale.com>
2024-06-14xcode/iOS: support serial number collection via MDM on iOS (#11429)Andrea Gottardo1-0/+4
Fixes tailscale/corp#18366. This PR provides serial number collection on iOS, by allowing system administrators to pass a `DeviceSerialNumber` MDM key which can be read by the `posture` package in Go. Signed-off-by: Andrea Gottardo <andrea@gottardo.me>
2024-05-24all: do not depend on the testing packageMaisem Ali1-2/+8
Discovered while looking for something else. Updates tailscale/corp#18935 Signed-off-by: Maisem Ali <maisem@tailscale.com>
2024-05-06util/syspolicy: add auto exit node related keys (#11996)Claire Wang2-0/+65
Updates tailscale/corp#19681 Signed-off-by: Claire Wang <claire@tailscale.com>
2024-04-23util/syspolicy: add ReadStringArray interface (#11857)Andrea Gottardo5-0/+59
Fixes tailscale/corp#19459 This PR adds the ability for users of the syspolicy handler to read string arrays from the MDM solution configured on the system. Signed-off-by: Andrea Gottardo <andrea@gottardo.me>