Skip to content

[client] mobile MDM bridge — iOS + Android setMDMPolicyFetcher entrypoint - #6435

Merged
riccardomanfrin merged 35 commits into
mainfrom
mdm_integration
Sep 8, 2026
Merged

riccardomanfrin merged 35 commits into
mainfrom
mdm_integration

Conversation

@riccardomanfrin

@riccardomanfrin riccardomanfrin commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Describe your changes

Adds the iOS and Android gomobile-facing MDM bridge on the daemon side.
Each native Client now carries an *mdm.Loader set via
SetMDMPolicyFetcher; applyMDMOverlay(cfg) runs the resolved
mdm.Policy on top of the loaded Config at every Run / login /
DebugBundle call site — mirroring how the desktop loader plugs into
Config.apply. Nil loader is a no-op: until the Swift or Kotlin side
registers a PolicyFetcher, the code is dormant and behavior is
byte-identical to pre-PR. Merging this without the app-side wiring is
safe.

Issue ticket number and link

Part of NET-1214 (MDM configuration profile support). Companion Swift /
Kotlin work lives in the netbirdio/ios-client and netbirdio/android-client
repos, on their respective mdm_integration branches; they bump the
netbird-core submodule to this PR's merge commit to activate the bridge.

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)

By submitting this pull request, you confirm that you have read and agree to the terms of the Contributor License Agreement.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

Internal SDK plumbing: the public MDM key surface, key semantics, and
mdm-integration.mdx reference all remain as shipped with the desktop
MDM feature. The native-side calling convention is documented in the
Go and Swift/Kotlin docstrings themselves.

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

N/A

@coderabbitai

coderabbitai Bot commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Refactors MDM policy loading system across desktop, server, and Android from package-level global functions and test hooks to dependency-injected Loader instances. Replaces LoadPolicy() export with Loader type holding optional PolicyFetcher. Updates all platform implementations to delegate to injected fetchers. Adds ApplyMDMPolicy method for explicit config overlays. Introduces Android JSON adapter and per-client/server loader instances. Adds explicit overlay application to CLI/embedded paths. Updates all tests to construct loaders directly instead of mutating globals.

Changes

MDM Loader Dependency Injection Refactor

Layer / File(s) Summary
Core Loader abstraction and PolicyFetcher interface
client/mdm/policy.go, client/mdm/policy_test.go
Replaces the exported LoadPolicy() function with a dependency-injected Loader type, NewLoader constructor, and (*Loader).Load() method. Adds PolicyFetcher interface for mobile platforms. Nil-receiver Load() returns an empty non-nil Policy. Updates unit test to validate nil-fetcher loader behavior.
Platform-specific loadPlatform() implementations
client/mdm/policy_darwin.go, client/mdm/policy_mobile.go, client/mdm/policy_other.go, client/mdm/policy_windows.go
Converts all platform loader implementations from standalone loadPlatformPolicy() functions to (*Loader).loadPlatform() methods. Each method conditionally returns l.fetcher.Fetch() when available, otherwise delegates to platform logic (plist on macOS, registry on Windows, nil sentinel on mobile/other). Updates documentation to reflect the loader pattern.
Android MDM JSON adapter and PolicyFetcher registration
client/android/mdm.go
Declares Android-specific PolicyFetcher interface with JSON/empty/error semantics for Kotlin bridge. Implements jsonFetcherAdapter.Fetch() to unmarshal JSON strings to map[string]any with warning on malformed input. Adds (*Client) SetMDMPolicyFetcher(p PolicyFetcher) to register or disable per-client mdm.Loader.
Android client config overlay wiring
client/android/client.go
Adds mdmLoader *mdm.Loader field to Client. Applies MDM overlay via c.applyMDMOverlay(cfg) after config load in Run, RunWithoutLogin, and DebugBundle before engine initialization. Implements applyMDMOverlay helper that applies c.mdmLoader.Load() to config via ApplyMDMPolicy.
Config ApplyMDMPolicy API and initialization
client/internal/profilemanager/config.go
Removes package-level loadMDMPolicy indirection. Adds exported (*Config).ApplyMDMPolicy(*mdm.Policy) method for explicit overlay application. Updates (*Config).apply() to initialize overlay via mdm.NewPolicy(nil) instead of global hook, ensuring fresh empty policy at apply time.
Server-side daemon-owned MDM loader
client/server/server.go, client/server/mdm.go
Adds mdmLoader *mdm.Loader field to daemon Server. Lazily initializes loader in Start() and passes to mdmTicker. Updates SetConfig and Login handlers to use s.mdmLoader.Load() for conflict detection. In getConfig, explicitly applies overlay via config.ApplyMDMPolicy(s.mdmLoader.Load()) before returning. Applies overlay in GetConfig RPC and logout path. Removes global loadMDMPolicy variable from mdm.go.
MDM Ticker dependency injection
client/mdm/ticker.go, client/mdm/ticker_test.go
Updates Ticker to store injected *Loader. Modifies NewTicker to accept loader parameter and initialize prev via loader.Load(). Updates Run to load policy via t.loader.Load() on each tick. Refactors tests to use fakePolicyFetcher with mutex-protected state, construct loaders via NewLoader(fetcher), and defer goroutine cleanup to avoid races.
Explicit MDM overlay in CLI and embedded paths
client/cmd/login.go, client/cmd/up.go, client/embed/embed.go
Adds explicit MDM policy overlay application to CLI and embedded deployment paths. login.go and up.go apply config.ApplyMDMPolicy(mdm.NewLoader(nil).Load()) after config load in foreground mode. embed.go applies MDM policy to generated config immediately after creation before option overrides. Replaces implicit auto-apply behavior with explicit control.
Config test helper refactoring
client/internal/profilemanager/config_mdm_test.go
Introduces fakeFetcher, loaderFor, and configWithMDM helpers to construct loaders from policies and apply them to configs without global hook mutation. Updates all MDM config tests to use configWithMDM(...) with inline policy inputs instead of withMDMPolicy global overrides.
Server test helper refactoring
client/server/setconfig_mdm_test.go
Updates withMDMPolicy helper to accept s *Server and inject mdm.Loader directly onto server. Introduces fakeMDMFetcher for test policy injection. Refactors all MDM TestSetConfig_* cases to use per-server policy injection instead of global loadMDMPolicy mutation.

Sequence Diagram(s)

sequenceDiagram
  participant Kotlin as Kotlin/Native
  participant AndroidClient as Android Client
  participant MDMLoader as MDM Loader
  participant PlatformImpl as Platform Impl
  participant Config as Config

  Kotlin->>AndroidClient: SetMDMPolicyFetcher(fetcher)
  AndroidClient->>MDMLoader: NewLoader(jsonFetcherAdapter)
  Note over AndroidClient: Stores in mdmLoader field

  rect rgba(100, 150, 200, 0.5)
    Note over AndroidClient,Config: Config Load Path
    AndroidClient->>Config: UpdateOrCreateConfig()
    Config->>Config: apply() with NewPolicy(nil)
    AndroidClient->>MDMLoader: applyMDMOverlay(cfg)
    MDMLoader->>MDMLoader: Load()
    MDMLoader->>PlatformImpl: loadPlatform()
    PlatformImpl->>AndroidClient: fetcher.Fetch()
    AndroidClient->>Kotlin: FetchJSON()
    Kotlin-->>AndroidClient: JSON string
    AndroidClient-->>PlatformImpl: map[string]any
    PlatformImpl-->>MDMLoader: policy map
    MDMLoader->>Config: ApplyMDMPolicy(policy)
    Config-->>AndroidClient: config with overlay
  end
Loading
sequenceDiagram
  participant Server as Server.Start()
  participant MDMLoader as MDM Loader
  participant Ticker as MDM Ticker
  participant Fetcher as Platform Fetcher

  Server->>MDMLoader: NewLoader(nil)
  Note over Server: Stores in mdmLoader field

  Server->>Ticker: NewTicker(interval, mdmLoader)
  Ticker->>MDMLoader: Load() init prev
  MDMLoader->>Fetcher: loadPlatform()
  Fetcher-->>MDMLoader: policy map (or nil)
  MDMLoader-->>Ticker: Policy

  rect rgba(150, 200, 100, 0.5)
    Note over Ticker,Fetcher: Ticker Run Loop (periodic)
    loop Each Tick
      Ticker->>MDMLoader: Load() current
      MDMLoader->>Fetcher: loadPlatform()
      Fetcher-->>MDMLoader: updated policy
      MDMLoader-->>Ticker: Policy
      Ticker->>Ticker: Compare prev vs curr
      alt Policy Changed
        Ticker->>Ticker: Emit diffs, invoke onChange
      end
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • netbirdio/netbird#6374: Refactors the same MDM policy pipeline in client/mdm/policy*.go and client/internal/profilemanager/config*.go, with direct integration changes to how MDM overlays are applied and tested.

Suggested reviewers

  • lixmal
  • pappz
  • mlsmaycon
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description is on topic but omits the required issue link and test confirmations, and it describes changes such as OnMDMPolicyChanged that are not present in the supplied diff summary. Add the agreed issue URL, complete the testing and checklist items, and revise the runtime-flow summary to match the actual changeset, including ticker and loader refactoring.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the mobile MDM bridge and the SetMDMPolicyFetcher entry point, which are central to the changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mdm_integration

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@client/mdm/policy_mobile.go`:
- Around line 20-41: The global fetcher variable accessed by
SetMobilePolicyFetcher and loadPlatformPolicy lacks synchronization, creating a
potential data race if SetMobilePolicyFetcher is called concurrently or after
initialization. Add a sync.Mutex to protect access to the fetcher variable. In
SetMobilePolicyFetcher, acquire the lock before writing to fetcher, and in
loadPlatformPolicy, acquire the lock before reading from fetcher. This ensures
atomic registration and read operations regardless of when
SetMobilePolicyFetcher is invoked.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 21ce5b76-f5ba-4cd4-b900-185874005e16

📥 Commits

Reviewing files that changed from the base of the PR and between 6006761 and db2c9b6.

📒 Files selected for processing (2)
  • client/android/mdm.go
  • client/mdm/policy_mobile.go

Comment thread client/mdm/policy_mobile.go Outdated
@github-actions

github-actions Bot commented Jun 15, 2026 •

Copy link
Copy Markdown

Release artifacts

Built for PR head b65f493 in workflow run #18703.

Artifact Link
All release artifacts Download
Linux packages Download
Windows packages Download
macOS packages Download
UI artifacts Download
UI GTK3 artifacts Download
UI macOS artifacts Download

GHCR images (amd64)

This comment is updated by the Release workflow. Artifact links expire according to the workflow retention policy.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
client/mdm/policy.go (1)

108-111: ⚡ Quick win

Align NewLoader documentation with actual platform behavior.

Line 108–111 says the fetcher is consulted only on mobile, but desktop loaders also short-circuit to l.fetcher.Fetch() when a fetcher is injected. Please update this comment to match the real cross-platform contract and avoid misleading call sites.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@client/mdm/policy.go` around lines 108 - 111, The comment for NewLoader
function (lines 108-111) incorrectly states that the fetcher is consulted only
on mobile builds and is unused on desktop. Update this documentation comment to
accurately reflect that the fetcher is consulted on both mobile and desktop
platforms when a fetcher is injected, not just on mobile. The comment should
clarify the actual cross-platform contract to avoid misleading callers.
client/internal/profilemanager/config.go (1)

187-193: ⚡ Quick win

Clarify ApplyMDMPolicy reset semantics in the doc comment.

The current wording implies that an empty policy clears prior overlay effects on the same Config instance, but applyMDMPolicy is overlay-only and does not restore previously overridden fields. Please tighten the comment to reflect “apply on freshly resolved config” semantics (or implement explicit revert behavior).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@client/internal/profilemanager/config.go` around lines 187 - 193, The doc
comment for the ApplyMDMPolicy function currently states that passing an empty
Policy will clear any prior overlay, but this is misleading since the function
only applies overlays and does not restore previously overridden fields. Update
the doc comment to clarify the actual behavior: that ApplyMDMPolicy applies MDM
policy overlays on top of the currently resolved config values and should be
called on freshly resolved config (as the lifecycle owner does), rather than
implying it can be used to revert or clear prior overlays by passing an empty
policy. Remove or revise the wording about clearing prior overlays to accurately
reflect overlay-only semantics.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@client/mdm/policy_test.go`:
- Around line 153-161: The test TestLoader_NilFetcherReturnsEmpty is
non-deterministic because calling NewLoader(nil).Load() may read real MDM state
on Windows/macOS, causing the emptiness assertions to fail on managed hosts.
Either add build tags (such as //go:build linux) to gate this test to platforms
where nil fetcher produces a deterministic empty result, or refactor the test to
use a mock fetcher that ensures deterministic behavior regardless of actual MDM
state on the host. This ensures the assertions in the test remain valid and
consistent across all platforms.

---

Nitpick comments:
In `@client/internal/profilemanager/config.go`:
- Around line 187-193: The doc comment for the ApplyMDMPolicy function currently
states that passing an empty Policy will clear any prior overlay, but this is
misleading since the function only applies overlays and does not restore
previously overridden fields. Update the doc comment to clarify the actual
behavior: that ApplyMDMPolicy applies MDM policy overlays on top of the
currently resolved config values and should be called on freshly resolved config
(as the lifecycle owner does), rather than implying it can be used to revert or
clear prior overlays by passing an empty policy. Remove or revise the wording
about clearing prior overlays to accurately reflect overlay-only semantics.

In `@client/mdm/policy.go`:
- Around line 108-111: The comment for NewLoader function (lines 108-111)
incorrectly states that the fetcher is consulted only on mobile builds and is
unused on desktop. Update this documentation comment to accurately reflect that
the fetcher is consulted on both mobile and desktop platforms when a fetcher is
injected, not just on mobile. The comment should clarify the actual
cross-platform contract to avoid misleading callers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 239e01a4-4e58-4765-ad8d-d153e6b35e88

📥 Commits

Reviewing files that changed from the base of the PR and between bec26d5 and 8741954.

📒 Files selected for processing (15)
  • client/android/client.go
  • client/android/mdm.go
  • client/internal/profilemanager/config.go
  • client/internal/profilemanager/config_mdm_test.go
  • client/mdm/policy.go
  • client/mdm/policy_darwin.go
  • client/mdm/policy_mobile.go
  • client/mdm/policy_other.go
  • client/mdm/policy_test.go
  • client/mdm/policy_windows.go
  • client/mdm/ticker.go
  • client/mdm/ticker_test.go
  • client/server/mdm.go
  • client/server/server.go
  • client/server/setconfig_mdm_test.go
💤 Files with no reviewable changes (1)
  • client/server/mdm.go

Comment thread client/mdm/policy_test.go
@sonarqubecloud

Copy link
Copy Markdown

- login.go: keep both new imports (mdm + nbnet + server)
- ios/NetBirdSDK/client.go: additive struct-field merge (mdmLoader + stateMu/connectClient/config)
- setconfig_mdm_test.go: adopt new withMDMPolicy(t, s, policy) signature; fix stray old-signature call in TestSetConfig_MDMAllow_ManagementURLPortNormalized
Aligns to other clients OSes behavior
@riccardomanfrin riccardomanfrin changed the title [client] MDM Android mobile wiring [client] mobile MDM bridge — iOS + Android setMDMPolicyFetcher entrypoint Aug 7, 2026
riccardomanfrin and others added 6 commits August 7, 2026 12:56
# Conflicts:
#	client/cmd/up.go
#	client/embed/embed.go
#	client/ios/NetBirdSDK/client.go
The mobile bridges only carried the policy fetcher, leaving every
enforcement decision to the native apps: the desktop derived its UI
restrictions in the Wails service layer, the daemon kept the conflict
machinery in the server package, and both mobile bridges duplicated the
JSON fetch adapter. Anything the native side had to reimplement was a
place for iOS and Android to drift apart.

Enforcement now lives in client/mdm and is consumed identically by all
three platforms:

- conflicts.go holds the value-aware conflict checks lifted out of the
  daemon, so the same normalization (canonical URLs, PSK sentinel echo)
  applies wherever a config change is validated.
- restrictions.go derives the UI enforcement snapshot from a policy and
  renders it in the JSON shape the desktop frontend already consumes.
  The service-layer types become aliases, keeping one source of truth.
- jsonloader.go replaces the adapter that was copy-pasted into both
  bridges.
- changedetector.go moves change detection off the native side: the
  caller forwards the OS notification and asks whether the managed
  configuration actually changed, instead of diffing dictionaries
  itself.

The mobile bridges gain the enforcement the daemon already had. The
Preferences getters resolve managed keys from the policy, so a naive UI
shows the enforced value; Commit rejects a staged change that diverges
from a managed key; NewAuth resolves the managed management URL before
persisting the config and overlays the policy on it, so a login can no
longer run against a URL the policy forbids. Android's profile
mutations fail closed when disableProfiles is set.

NewAuth takes the fetcher as a required argument rather than keeping a
policy-blind overload: the apps consume this code as a submodule, so a
compile error at the bump is the point. The mobile PSK getter is
replaced by a presence check — the key has no reason to cross the
bridge, and not returning it means the native side needs no redaction
sentinel of its own.
pappz
pappz previously approved these changes Sep 3, 2026
# Conflicts:
#	client/ios/NetBirdSDK/client.go
#	client/ios/NetBirdSDK/login.go
#	client/server/mdm.go
The merge commit was recorded with the conflict markers still in the
tree. Resolve them so the branch builds again:

- client/ios/NetBirdSDK: keep both the mdm and mobile imports, and keep
  the mdmLoader/mdmDetector fields next to main's stateMu documentation.
- client/server/mdm.go: drop the conflict helpers main added locally,
  they already live in the client/mdm package on this branch, and keep
  the new checks main introduced (allowRemoteJobs, enableLocalMetrics,
  localMetricsAddress) as calls into the package-level helpers.
- client/mdm/conflicts.go: add ConflictStringPtr, the presence-aware
  string check main needs for the optional localMetricsAddress field.
- Port the two tests main added over the per-Server loader helper and the
  configWithMDM helper, both of which replaced the package-level policy
  injection this branch removed.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 38 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="client/internal/profilemanager/config.go">

<violation number="1" location="client/internal/profilemanager/config.go:219">
P2: When an already-overlaid config receives an empty policy, this call clears the enforcement metadata but leaves the prior MDM values in the config. Restore the pre-policy values, or re-resolve the base config before clearing the overlay, so the documented empty-policy behavior actually removes enforcement.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread client/ios/NetBirdSDK/login.go Outdated
Comment thread client/ios/NetBirdSDK/client.go Outdated
Comment thread client/mobile/profile_manager.go
Comment thread client/mdm/conflicts.go Outdated
Comment thread client/ios/NetBirdSDK/preferences.go
Comment thread client/embed/embed.go
Comment thread client/ios/NetBirdSDK/mdm.go Outdated
Comment thread client/mobile/profile_manager.go
Comment thread client/mdm/conflicts.go
Comment thread client/mdm/changedetector.go Outdated
The SetConfig, Login and mobile Commit conflict checks collapsed the PSK
to a plain string, so an explicit empty value was indistinguishable from
an unset field and slipped past the MDM gate, clearing the persisted key.
Carry the optional field as a pointer through ConflictStringPtr, treating
only the redaction sentinel as a no-op echo. ConflictString had no other
callers and is removed.
Drop the unused ChangeDetector.Current, point the stale LoadPolicy
comment references at Loader.Load, and move the profileEmail godoc back
above its function.
…onflict gate

MDMConflicts skipped allowRemoteJobs, enableLocalMetrics and
localMetricsAddress even though the overlay applies all three and the
daemon gate already checks them, so a mobile Commit could persist values
diverging from the enforced policy. Align the list with the daemon.

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 9 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread client/ios/NetBirdSDK/login.go Outdated
Comment thread client/android/login.go
Comment thread client/android/preferences.go Outdated
Comment thread client/ios/NetBirdSDK/preferences.go Outdated
…ct test

The legacy LoginRequest.PreSharedKey field is deliberately exercised by
the test, matching the nolint already carried by the production path.
SetMDMPolicyFetcher wrote the loader and change detector as two plain
fields that Run, the OS-change callback and the restrictions getter read
from other threads without synchronization. Hold both behind a single
atomic pointer so a registration is published as one unit and readers
always observe a matching loader and detector pair; Preferences gets the
same treatment for its loader. Exported signatures are unchanged.
…ences

GetRemoteJobsAllowed returned the staged or persisted value even when
the policy manages allowRemoteJobs, so the native settings UI could show
a value the Commit gate would reject. Resolve it through the overlay like
GetManagementURL does.
NewAuth already writes the config through UpdateOrCreateConfig before
the MDM policy is overlaid, and the login itself never mutates the
Config. The post-login WriteOutConfig calls therefore only rewrote the
same file with the enforced ManagementURL and PreSharedKey in it, so a
removed or changed policy kept acting through the persisted values.
ApplyMDMPolicy promised that an empty Policy clears a prior overlay, but
applyMDMPolicy only resets the enforcement metadata and the runtime-only
upload URL; the enforced ManagementURL, PreSharedKey and flags stay. Every
lifecycle owner resolves the base Config again before applying, so state
that contract instead of the reversibility that was never implemented.
The iOS Client kept the config parsed from SetConfigFromJSON and applied
the MDM overlay onto that same instance on every Run, IsLoginRequired
and DebugBundle, so a key removed from the policy stayed enforced. Store
the JSON instead and parse it per load through one loadConfig path.

Auth serialized the overlaid config from GetConfigJSON, which tvOS then
persisted to UserDefaults and fed back as the preload. Keep the resolved
config as the base, run the login on a JSON round-trip copy with the
overlay, and return the base from GetConfigJSON.
…nfig file on mobile

Preferences.GetManagementURL resolved a managed URL by reading and
overlaying the persisted config, so a corrupt file or the tvOS sandbox
turned an enforced URL into a read error. Return the canonical managed
value directly, the same string BuildRestrictions already hands to the
UI, and only fall back to the staged or persisted value when MDM does
not manage the key.

NewAuth validated the caller-supplied management URL before the overlay
ran, so a malformed or echoed value blocked or persisted under an MDM
policy that already dictates the URL. Ignore the caller value while the
key is managed; the login runs against the overlay either way.
…ke disableAdvancedView a tristate

NewLoader, PolicyFetcher and the darwin/windows loadPlatform docs claimed
the fetcher is unused on desktop, while every loader returns its values
when one is injected. That precedence is the seam the server tests rely
on across platforms, so the docs now describe it; production desktop
callers still pass nil and keep the registry / plist authoritative.

Fields.DisableAdvancedView collapsed "managed and false" into the same
JSON as "not managed", unlike AllowServerSSH and the daemon's optional
proto field. Carry it as a *bool so the UIs can tell the two apart; the
desktop reflect loop skips pointer fields already, and the mobile
decoders treat null as not managed.
- ResolveConflicts treats a managed key whose ConflictCheck has no Check
  as a conflict instead of dereferencing nil.
- Ticker.Run and ChangeDetector.Changed share policyChanged so the diff
  semantics and the log line cannot drift apart.
- TestLoader_NilFetcherReturnsEmpty skips on windows/darwin, where a nil
  fetcher reads the real registry / plist.
- The profilemanager test loader checks GetInt before GetBool so integer
  keys survive the round trip, and the PSK tests use the exported
  redaction sentinel.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 14 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="client/ios/NetBirdSDK/preferences.go">

<violation number="1" location="client/ios/NetBirdSDK/preferences.go:45">
P2: For an invalid or non-http(s) MDM management URL, GetManagementURL now returns the raw value (CanonicalURL returns the input unchanged when unparseable and doesn't check the scheme), instead of the previous behavior where ApplyMDMPolicy/parseURL validated it and fell back to the existing config URL to keep the client functional. The codebase deliberately guards this case (TestApply_MDMInvalidURL_KeepsPreviousValue); this new branch drops that safeguard. Parse the policy value with parseURL and fall back to the config URL when it fails, mirroring ApplyMDMPolicy.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic


// GetManagementURL read url from config file
func (p *Preferences) GetManagementURL() (string, error) {
if v, ok := p.policy().GetString(mdm.KeyManagementURL); ok {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: For an invalid or non-http(s) MDM management URL, GetManagementURL now returns the raw value (CanonicalURL returns the input unchanged when unparseable and doesn't check the scheme), instead of the previous behavior where ApplyMDMPolicy/parseURL validated it and fell back to the existing config URL to keep the client functional. The codebase deliberately guards this case (TestApply_MDMInvalidURL_KeepsPreviousValue); this new branch drops that safeguard. Parse the policy value with parseURL and fall back to the config URL when it fails, mirroring ApplyMDMPolicy.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At client/ios/NetBirdSDK/preferences.go, line 45:

<comment>For an invalid or non-http(s) MDM management URL, GetManagementURL now returns the raw value (CanonicalURL returns the input unchanged when unparseable and doesn't check the scheme), instead of the previous behavior where ApplyMDMPolicy/parseURL validated it and fell back to the existing config URL to keep the client functional. The codebase deliberately guards this case (TestApply_MDMInvalidURL_KeepsPreviousValue); this new branch drops that safeguard. Parse the policy value with parseURL and fall back to the config URL when it fails, mirroring ApplyMDMPolicy.</comment>

<file context>
@@ -42,16 +42,17 @@ func (p *Preferences) policy() *mdm.Policy {
 func (p *Preferences) GetManagementURL() (string, error) {
-	policy := p.policy()
-	if !policy.HasKey(mdm.KeyManagementURL) && p.configInput.ManagementURL != "" {
+	if v, ok := p.policy().GetString(mdm.KeyManagementURL); ok {
+		return mdm.CanonicalURL(v), nil
+	}
</file context>

pappz
pappz previously approved these changes Sep 8, 2026
Comment thread client/server/setconfig_mdm_test.go Outdated
values[k] = v
continue
}
if v, ok := policy.GetBool(k); ok {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here attempt order is GetString → GetBool → GetInt but in config_mdm_test.go I see String, Int and Bool.. so because GetBool accepts also an integer.. for example something like the wireguardPort: 51820 might get confused for a "true".

withMDMPolicy rebuilt the policy map by trying GetString, then GetBool,
then GetInt. Policy.GetBool accepts native ints (non-zero means true), so
an int-valued key such as wireguardPort round-tripped through the helper as
the bool true and GetInt was never reached. Try GetInt before GetBool, as
the profilemanager helper already does; GetInt does not coerce bools, so
booleans still fall through to GetBool.

No test sets an int key today, so this was latent: the first test to
exercise the wireguardPort conflict gate would have seen ConflictInt64
report a conflict for every value, including a matching one.
@sonarqubecloud

sonarqubecloud Bot commented Sep 8, 2026

Copy link
Copy Markdown

@riccardomanfrin
riccardomanfrin merged commit e14006d into main Sep 8, 2026
44 checks passed
@riccardomanfrin
riccardomanfrin deleted the mdm_integration branch September 8, 2026 09:53
JuliusFreudenberger pushed a commit to JuliusFreudenberger/nix-config that referenced this pull request Oct 2, 2026
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [netbirdio/dashboard](https://github.com/netbirdio/dashboard) | minor | `v2.92.0` → `v2.94.0` |
| [netbirdio/netbird](https://github.com/netbirdio/netbird) | minor | `0.78.1-rootless` → `0.80.0-rootless` |
| [netbirdio/netbird-server](https://github.com/netbirdio/netbird) | minor | `0.78.1` → `0.80.0` |
| [netbirdio/reverse-proxy](https://github.com/netbirdio/netbird) | minor | `0.78.1` → `0.80.0` |

---

> ⚠️ **Warning**
>
> Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/12) for more information.

---

### Release Notes

<details>
<summary>netbirdio/dashboard (netbirdio/dashboard)</summary>

### [`v2.94.0`](https://github.com/netbirdio/dashboard/releases/tag/v2.94.0)

[Compare Source](netbirdio/dashboard@v2.93.0...v2.94.0)

#### What's Changed

- Fix peer approval visible for self-hosted by [@&#8203;heisbrot](https://github.com/heisbrot) in [#&#8203;811](netbirdio/dashboard#811)
- Hide the sidebar version card from users without settings access by [@&#8203;heisbrot](https://github.com/heisbrot) in [#&#8203;812](netbirdio/dashboard#812)
- Move CI onto the Node 24 action runtime by [@&#8203;heisbrot](https://github.com/heisbrot) in [#&#8203;814](netbirdio/dashboard#814)
- Show real provider logos and rework the Agent Network modals by [@&#8203;heisbrot](https://github.com/heisbrot) in [#&#8203;809](netbirdio/dashboard#809)
- Add Agent Network support to the Control Center by [@&#8203;heisbrot](https://github.com/heisbrot) in [#&#8203;808](netbirdio/dashboard#808)
- Add Sign-in Domains settings tab by [@&#8203;heisbrot](https://github.com/heisbrot) in [#&#8203;781](netbirdio/dashboard#781)

**Full Changelog**: <netbirdio/dashboard@v2.93.0...v2.94.0>

### [`v2.93.0`](https://github.com/netbirdio/dashboard/releases/tag/v2.93.0)

[Compare Source](netbirdio/dashboard@v2.92.0...v2.93.0)

#### What's Changed

- chore: remove dead code and unused dependencies by [@&#8203;heisbrot](https://github.com/heisbrot) in [#&#8203;787](netbirdio/dashboard#787)
- Add rootless dashboard container image by [@&#8203;jnfrati](https://github.com/jnfrati) in [#&#8203;791](netbirdio/dashboard#791)
- chore: update Next.js to 16.3.4 and refresh dependencies by [@&#8203;heisbrot](https://github.com/heisbrot) in [#&#8203;797](netbirdio/dashboard#797)
- mark is cloud false unless explicitly overridden by [@&#8203;pascal-fischer](https://github.com/pascal-fischer) in [#&#8203;799](netbirdio/dashboard#799)
- Restore the Active toggle and keep it visible on disabled rows by [@&#8203;SunsetDrifter](https://github.com/SunsetDrifter) in [#&#8203;803](netbirdio/dashboard#803)
- Pick a private-capable proxy cluster when bootstrapping the agent network by [@&#8203;mlsmaycon](https://github.com/mlsmaycon) in [#&#8203;780](netbirdio/dashboard#780)
- Fix group and resource order in resource group audit events by [@&#8203;SunsetDrifter](https://github.com/SunsetDrifter) in [#&#8203;804](netbirdio/dashboard#804)
- fix: keep tables from scrolling horizontally when the Active toggle shows by [@&#8203;SunsetDrifter](https://github.com/SunsetDrifter) in [#&#8203;805](netbirdio/dashboard#805)
- Add a deployment announcement banner set through NETBIRD\_ANNOUNCEMENT by [@&#8203;bison](https://github.com/bison) in [#&#8203;806](netbirdio/dashboard#806)
- Replace the pending-approval error page with a dedicated screen by [@&#8203;heisbrot](https://github.com/heisbrot) in [#&#8203;802](netbirdio/dashboard#802)

**Full Changelog**: <netbirdio/dashboard@v2.92.0...v2.93.0>

</details>

<details>
<summary>netbirdio/netbird (netbirdio/netbird)</summary>

### [`v0.80.0`](netbirdio/netbird@v0.79.0...v0.80.0)

[Compare Source](netbirdio/netbird@v0.79.0...v0.80.0)

### [`v0.79.0`](https://github.com/netbirdio/netbird/releases/tag/v0.79.0)

[Compare Source](netbirdio/netbird@v0.78.2...v0.79.0)

##### Release Notes for v0.79.0

##### New Feature: Desktop Light Mode

The desktop app now gives you three appearance options: System, Light, and Dark. Follow your operating system's theme or choose the look you prefer. The new light theme covers the connection view, settings, profiles, and dialogs, with matching native window appearance on Windows, macOS, and Linux. [#&#8203;7344](netbirdio/netbird#7344) by [@&#8203;TechHutTV](https://github.com/TechHutTV)

<img width="2022" height="1542" alt="image" src="https://github.com/user-attachments/assets/2081f103-f766-4f2d-92df-b304eaaa5acb" />

This release also brings shared MDM policy enforcement to the mobile SDKs, a rootless Red Hat UBI container image, and improvements to DNS, relay connections, and reverse proxy access controls.

##### What's Changed

##### Desktop Client Improvements

- Fixed a Windows tray deadlock that could freeze the app when a double-click opened a window while another window was still being created. [#&#8203;7449](netbirdio/netbird#7449) by [@&#8203;pappz](https://github.com/pappz)
- Fixed the MDM settings snapshot so the UI correctly reports when remote jobs are managed by policy. [#&#8203;7485](netbirdio/netbird#7485) by [@&#8203;pappz](https://github.com/pappz)

##### Client Improvements

- Added MDM policy bridges and shared enforcement for the iOS and Android SDKs, keeping managed settings and profile restrictions consistent with the desktop client. [#&#8203;6435](netbirdio/netbird#6435) by [@&#8203;riccardomanfrin](https://github.com/riccardomanfrin)
- Accepted MDM boolean values delivered as JSON numbers, so policies using `0` and `1` are applied correctly. [#&#8203;7471](netbirdio/netbird#7471) by [@&#8203;riccardomanfrin](https://github.com/riccardomanfrin)
- Compared MDM-managed URLs by their normalized endpoints, avoiding false conflicts between equivalent URLs. [#&#8203;7472](netbirdio/netbird#7472) by [@&#8203;riccardomanfrin](https://github.com/riccardomanfrin)
- Refreshed system information on every management sync reconnect, keeping local network addresses and posture information current after network changes. [#&#8203;7409](netbirdio/netbird#7409) by [@&#8203;pappz](https://github.com/pappz)
- Used host prefixes for Android TUN addresses so local network protection does not classify the entire overlay as a local network. [#&#8203;7414](netbirdio/netbird#7414) by [@&#8203;pappz](https://github.com/pappz)
- Replaced the eBPF DNS forwarder with UDP and TCP DNAT rules when the resolver cannot listen on port 53, with rollback and cleanup for incomplete redirects. [#&#8203;7439](netbirdio/netbird#7439) by [@&#8203;lixmal](https://github.com/lixmal)
- Fixed a relay address race that could advertise a URL and IP from different connections during a reconnect. [#&#8203;7498](netbirdio/netbird#7498) by [@&#8203;pappz](https://github.com/pappz)
- Returned the context cancellation or timeout error when an SSH handshake is interrupted. [#&#8203;7426](netbirdio/netbird#7426) by [@&#8203;pappz](https://github.com/pappz)
- Updated wireguard-go to `8bf8fa968f1a`, fixing keepalive buffer-pool stalls, keeping timer paths non-blocking, and making netstack interface shutdown idempotent. [#&#8203;7532](netbirdio/netbird#7532) by [@&#8203;pappz](https://github.com/pappz)
- Allowed buffer-pool limits to be adjusted while a device is stalled, and bounded proxy-wide updates so one stuck client does not block the others. [#&#8203;7452](netbirdio/netbird#7452) by [@&#8203;riccardomanfrin](https://github.com/riccardomanfrin)

##### Management Improvements

- Restored networks using individual peers as routers in the SQLite network map when `peer_groups` is empty or null. [#&#8203;7418](netbirdio/netbird#7418) by [@&#8203;mlsmaycon](https://github.com/mlsmaycon)
- Fixed SQLite network-map reads for users with null automatic groups and expanded coverage for empty and null router groups. [#&#8203;7425](netbirdio/netbird#7425) by [@&#8203;dmitri-netbird](https://github.com/dmitri-netbird)
- Included offline peers when scheduling login expiration and ensured expired peers are disconnected, while protecting peers that have just logged in again. [#&#8203;7467](netbirdio/netbird#7467) by [@&#8203;pascal-fischer](https://github.com/pascal-fischer)
- Applied duplicate-key sync protection to user-owned peers as well as peers registered with setup keys. [#&#8203;7427](netbirdio/netbird#7427) by [@&#8203;pascal-fischer](https://github.com/pascal-fischer)
- Validated that a peer exists before adding it to a group. [#&#8203;7486](netbirdio/netbird#7486) by [@&#8203;pascal-fischer](https://github.com/pascal-fischer)
- Prevented other users from deleting the account owner. [#&#8203;7456](netbirdio/netbird#7456) by [@&#8203;pascal-fischer](https://github.com/pascal-fischer)
- Hardened OIDC issuer validation by requiring HTTPS, rejecting credentials, query strings, and fragments in issuer URLs, refusing discovery redirects, and limiting discovery response size. [#&#8203;7435](netbirdio/netbird#7435) by [@&#8203;bcmmbaga](https://github.com/bcmmbaga)
- Cleaned up resources when WebSocket-to-gRPC proxy connections close. [#&#8203;7484](netbirdio/netbird#7484) by [@&#8203;dmitri-netbird](https://github.com/dmitri-netbird)

##### Agent Network

- Added managed proxy provisioning endpoints and response types to the API specification. [#&#8203;7433](netbirdio/netbird#7433) by [@&#8203;bison](https://github.com/bison)
- Prevented deletion of groups referenced by Agent Network budget rules, preserving the rules' spending limits. [#&#8203;7450](netbirdio/netbird#7450) by [@&#8203;Tyagiquamar](https://github.com/Tyagiquamar)

##### Reverse Proxy Improvements

- Added `NB_PROXY_UPSTREAM_HTTP_VERSION` with `auto`, `1.1`, and `2` options. The default `auto` mode negotiates with HTTPS upstreams and falls back to HTTP/1.1 when an upstream's negotiated HTTP/2 connection fails at the protocol level. [#&#8203;7410](netbirdio/netbird#7410) by [@&#8203;lixmal](https://github.com/lixmal)
- Enforced group access both when issuing session cookies and when accepting existing sessions. [#&#8203;7240](netbirdio/netbird#7240) by [@&#8203;lixmal](https://github.com/lixmal)
- Required custom domain validation before creating a service or moving one to a different custom domain. [#&#8203;7341](netbirdio/netbird#7341) by [@&#8203;mlsmaycon](https://github.com/mlsmaycon)
- Added a 48-hour validation window for custom domain registrations. Existing pending registrations receive a fresh window on upgrade; expired registrations are removed unless they still have services attached. [#&#8203;7497](netbirdio/netbird#7497) by [@&#8203;mlsmaycon](https://github.com/mlsmaycon)
- Rejected unsupported direct-upstream IP addresses, including loopback, multicast, link-local, and IPv6 addresses with zone identifiers. [#&#8203;7400](netbirdio/netbird#7400) by [@&#8203;dmitri-netbird](https://github.com/dmitri-netbird)
- Validated domain names before creating certificate lock files. [#&#8203;7501](netbirdio/netbird#7501) by [@&#8203;pascal-fischer](https://github.com/pascal-fischer)

##### Self-Hosting Improvements

- Added a rootless Red Hat UBI image for AMD64 and ARM64, published with the `0.79.0-rootless-ubi` tag. [#&#8203;7469](netbirdio/netbird#7469) by [@&#8203;jnfrati](https://github.com/jnfrati)
- Supported arbitrary non-root UIDs without a passwd entry, as used by OpenShift. [#&#8203;7440](netbirdio/netbird#7440) by [@&#8203;jnfrati](https://github.com/jnfrati)
- Added RPM dependencies, license and documentation files, a generated changelog, and an example `/etc/sysconfig/netbird` to meet Red Hat software certification packaging requirements. [#&#8203;7562](netbirdio/netbird#7562), [#&#8203;7573](netbirdio/netbird#7573) by [@&#8203;mlsmaycon](https://github.com/mlsmaycon)
- Kept deployments using the embedded identity provider on a single account, with stricter configuration checks and migration handling. [#&#8203;7380](netbirdio/netbird#7380) by [@&#8203;bcmmbaga](https://github.com/bcmmbaga)
- Passed the combined server's TLS configuration through to the management listener. [#&#8203;7499](netbirdio/netbird#7499) by [@&#8203;pascal-fischer](https://github.com/pascal-fischer)
- Updated peer connection-IP extraction to honor configured `TrustedPeers`, with `X-Forwarded-For` taking precedence over `X-Real-IP`. The final release preserves trust in all IPv4 and IPv6 sources when `TrustedPeers` is empty; configure your reverse proxy's address or network to restrict which sources can supply forwarded-IP headers. [#&#8203;7454](netbirdio/netbird#7454), [#&#8203;7589](netbirdio/netbird#7589) by [@&#8203;bcmmbaga](https://github.com/bcmmbaga); [#&#8203;7561](netbirdio/netbird#7561), [#&#8203;7577](netbirdio/netbird#7577) by [@&#8203;dmitri-netbird](https://github.com/dmitri-netbird) and [@&#8203;bcmmbaga](https://github.com/bcmmbaga)

##### Internal, CI, and Docs

- Added atomic `SetNX` and `GetDel` cache operations. [#&#8203;7084](netbirdio/netbird#7084) by [@&#8203;bcmmbaga](https://github.com/bcmmbaga)
- Allowed binaries embedding management to extend its command tree. [#&#8203;7483](netbirdio/netbird#7483) by [@&#8203;bison](https://github.com/bison)
- Extracted peer update handling and added test coverage. [#&#8203;7338](netbirdio/netbird#7338) by [@&#8203;dmitri-netbird](https://github.com/dmitri-netbird)
- Replaced a hard-coded temporary directory in WebSocket adapter tests with the platform's temporary directory. [#&#8203;7503](netbirdio/netbird#7503) by [@&#8203;dmitri-netbird](https://github.com/dmitri-netbird)
- Switched the MinIO test image to `quay.io` after it became unavailable on Docker Hub. [#&#8203;7516](netbirdio/netbird#7516) by [@&#8203;Silex](https://github.com/Silex)
- Preserved image variant suffixes in snapshot tags. [#&#8203;7511](netbirdio/netbird#7511) by [@&#8203;jnfrati](https://github.com/jnfrati)
- Skipped the protobuf breaking-change check on branch-creation pushes, which have no previous commit to compare against. [#&#8203;7411](netbirdio/netbird#7411) by [@&#8203;bison](https://github.com/bison)

***

**Full Changelog:** [v0.78.0...v0.79.0](netbirdio/netbird@v0.78.0...v0.79.0)

### [`v0.78.2`](https://github.com/netbirdio/netbird/releases/tag/v0.78.2)

[Compare Source](netbirdio/netbird@v0.78.1...v0.78.2)

##### What's Changed

- \[client] Fix the Windows tray deadlock on re-entrant window creation by [@&#8203;pappz](https://github.com/pappz) in [#&#8203;7537](netbirdio/netbird#7537)
- \[client] Bump wireguard-go to [`8bf8fa9`](netbirdio/netbird@8bf8fa968f1a) by [@&#8203;pappz](https://github.com/pappz) in [#&#8203;7538](netbirdio/netbird#7538)

**Full Changelog**: <netbirdio/netbird@v0.78.1...v0.78.2>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate CLI](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43OS4yIiwidXBkYXRlZEluVmVyIjoiNDQuNzkuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Reviewed-on: https://git.jfreudenberger.de/JuliusFreudenberger/nix-config/pulls/54
pappz added a commit to netbirdio/android-client that referenced this pull request Oct 7, 2026
…ding (#282)

The netbird submodule bump pulls in the mobile MDM bridge
(netbirdio/netbird#6435), which changed two binding signatures the app
calls: Android.newAuth now takes a PolicyFetcher, and
Preferences.getPreSharedKey was replaced by hasPreSharedKey.

Pass a null fetcher, which the Go side treats as MDM enforcement off,
and switch the pre-shared key check to the new boolean getter. This is a
temporary bridge until the Android MDM support in #278 wires the real
fetcher through these call sites.
pappz added a commit to netbirdio/android-client that referenced this pull request Oct 7, 2026
* Bump netbird submodule to the deadline-only session watcher

The engine no longer arms expiry-warning timers on Android and the
gomobile StateChangeListener drops OnSessionExpiring; the app
schedules the warnings itself from the deadline.

* Keep the scheduler tests from running the worker during schedule

With the SynchronousExecutor a job with zero initial delay runs inside
schedule(). The tests used a deadline 5 minutes out, so the T-10 job ran
immediately: it marked the warning fired and finished, which broke
workerSkipsOtherProfile and cancelAllKeepsFiredMarks and let the
in-window test pass on the automatic run instead of its own call.

Use a deadline an hour out where the test drives the worker itself, and
let the late-warning test assert on the automatic run directly.

* Bump netbird submodule to main with the deadline-only session watcher

* Adapt the setup-key login and PSK check to the MDM-aware gomobile binding (#282)

The netbird submodule bump pulls in the mobile MDM bridge
(netbirdio/netbird#6435), which changed two binding signatures the app
calls: Android.newAuth now takes a PolicyFetcher, and
Preferences.getPreSharedKey was replaced by hasPreSharedKey.

Pass a null fetcher, which the Go side treats as MDM enforcement off,
and switch the pre-shared key check to the new boolean getter. This is a
temporary bridge until the Android MDM support in #278 wires the real
fetcher through these call sites.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants