Proto commits in netbirdio/netbird

These commits are when the Protocol Buffers files have changed: (only the last 100 relevant commits are shown)

Commit:cef7f0e
Author:pascal
Committer:pascal

revert proto

Commit:f31fe82
Author:pascal

remove port-forwarding

Commit:ea5cf82
Author:Viktor Liu
Committer:Viktor Liu

Merge main into poc/certificate-posture

Commit:2dd25ec
Author:Zoltán Papp

Merge branch 'main' into fix/pkce-flow-session-extend # Conflicts: # client/ios/NetBirdSDK/login.go # client/server/server.go # shared/management/proto/management.pb.go

Commit:1bae44e
Author:riccardom

Merge branch 'main' into feat-post_quantum_ml_kem # Conflicts: # client/internal/peer/conn.go # client/internal/peer/handshaker.go

Commit:863410a
Author:mlsmaycon

[management,proxy] Simplify target access rollout Use protobuf compatibility instead of capability negotiation, and recommend proxy upgrades before using target actions. Keep existing behavior on older proxies, initialize routes when adding the first HTTP target, and split access validation into focused helpers.

Commit:7e941b9
Author:mlsmaycon

[management,proxy] Add per-target HTTP access control Allow individual HTTP locations to inherit service authentication, bypass it, or block requests while retaining literal-prefix routing. Keep authentication and forwarding on the same target snapshot, preserve existing policies in legacy updates, and gate activation on proxy capability support. Add unit, race-safe concurrency, database, integration, and container end-to-end coverage alongside proxy documentation.

Commit:30dd076
Author:Bethuel Mmbaga
Committer:GitHub

[management,proxy] Use single-use codes for OIDC session handoff (#7635) * Generalize PKCE verifier store into SingleUseStore * Generalize PKCE verifier store into SingleUseStore * Extend single-use store to generate one-time retrieval codes * Hand off proxy OIDC session via one-time code instead of URL token * Use the single-use store in integration tests * Read active proxy versions by cluster * Detect proxy clusters that support session codes * Bind OIDC session handoff mode to signed state * Deprecate legacy OIDC session token handoff * Remove unrelated session code test stub * fix tests * fix merge * Fix session code compatibility detection * Isolate proxy session codes in shared cache * bump min session version

Commit:619b687
Author:bcmmbaga

Deprecate legacy OIDC session token handoff

Commit:87103f9
Author:Viktor Liu

Merge branch 'reverse-proxy-allow-match-or' into reverse-proxy-crowdsec-appsec # Conflicts: # proxy/internal/auth/middleware.go # proxy/internal/auth/middleware_test.go # proxy/internal/auth/tunnel_lookup_test.go # proxy/management_integration_test.go # proxy/server.go # shared/management/proto/proxy_service.pb.go

Commit:6f4b2e0
Author:Viktor Liu

Merge remote-tracking branch 'origin/main' into HEAD # Conflicts: # shared/management/proto/proxy_service.pb.go

Commit:37eca69
Author:bcmmbaga

Hand off proxy OIDC session via one-time code instead of URL token

Commit:5d9e791
Author:Theodor S. Midtlien

Fix comments

Commit:cec9ee6
Author:Theodor Midtlien
Committer:GitHub

[Client] Surface readable Authz errors and add profile claim command (#7540) * [client] Surface error messages for IPC authz in UI (#7553)

Commit:75bb512
Author:Theodor S. Midtlien
Committer:Theodor S. Midtlien

(WIP) Add claim command and surface readable Authz Gate errors

Commit:15003fc
Author:Theodor S. Midtlien
Committer:Theodor S. Midtlien

Add owners to list profile ipc

Commit:2ec78d2
Author:Theodor S. Midtlien

(WIP) Add claim command and surface readable Authz Gate errors

Commit:91f1a72
Author:riccardom
Committer:riccardom

Adds observability and fixes cross cases - strict-kem vs strict-rp said "Connected + Quantum resistance: true" but it is actually blocked - perm-kem vs perm-rp "Connected + Quantum resistance: true" but it's a classic WG link, without PQ safety

Commit:6a42f7d
Author:riccardom
Committer:riccardom

Communicate the port over the signal exchange

Commit:6a644df
Author:riccardom
Committer:riccardom

Protocol update

Commit:c71fd1d
Author:riccardom
Committer:riccardom

[management,client] Default to NetBird's upload service when nothing is configured The previous commit made a peer with no destination — no MDM override, no URL named by the caller, nothing published by its management server — refuse to upload and keep the bundle local unless it was enrolled with NetBird's cloud. That closed the reported data-boundary concern, but it broke the default for everyone who uploads a bundle as part of their day: a self-hosted user opening a support ticket got a refusal where the command used to work. Product decision (NetBird's, not the reporter's): the knob to keep bundles inside your own infrastructure is what this branch provides, and it is enough. The default stays the service NetBird runs, self-hosted included. An admin who needs the bundles to stay in-house configures the destination; until then the everyday flow keeps working. So ResolveUploadURL drops the cloud check, the sentinel error and the managementURL argument, and never fails: MDM > explicitly named URL > published by management > NetBird's service Nothing observable changes for a deployment that configures nothing, which also removes two edge cases the fail-closed default had: a peer still enrolled on the legacy api.wiretrustee.com host would have been classified self-hosted and refused, and an upgrade would have silently stopped uploads for self-hosted deployments relying on them. The privilege gate is unaffected — a host other than the default one still requires a privileged caller, so pointing the CLI somewhere other than what management published needs root.

Commit:9f6d17b
Author:riccardom
Committer:riccardom

[management,client] Take the debug-bundle upload destination from management The debug-bundle paths that upload without a human picking a destination compiled the vendor endpoint in: the mobile clients and the desktop UI hold `https://upload.debug.netbird.io/upload-url` as a constant, the CLI defaults its flag to it, and the remote job falls back to it when nothing else is set. A self-hosted deployment therefore shipped peer logs, routes, DNS and firewall state to NetBird-run infrastructure without its operator ever configuring that, and had no way to point those paths anywhere else. #7147 and #7153 gave the remote job a per-job URL and an MDM override, but neither reaches the mobile, UI or CLI paths, and both fail open when unset. Publish the destination from the management server instead, on the channel that already carries stun/turn/signal/relay/flow/metrics: - `NetbirdConfig.debug.upload_url`, sourced from the new account setting `debug_bundle_upload_url` (REST + dashboard) and falling back to the new `DebugUpload.URL` in the management server config, which a self-hosted install can set once so a fresh account is not left on the vendor default. Both are validated as https-with-host where they are written; a change fans out to connected peers rather than waiting for the next login. - One resolver on the client, `debug.ResolveUploadURL`, used by every path: MDM override > explicitly named URL > destination published by management > the NetBird service, but only for a peer enrolled with NetBird's cloud. Anything else fails closed with ErrNoUploadDestination and the bundle stays local, which is the behaviour change: a self-hosted deployment that names no upload service no longer uploads at all. - The engine keeps the published value (`Engine.DebugUploadURL`) so the bundle paths, which run off the engine loop, do not have to read it back out of the opt-in sync-response store. - The daemon request grows `upload`, so "upload to wherever this deployment says" is expressible; an empty `uploadURL` no longer has to mean "no upload". The privilege gate is unchanged and still applies only to a URL the local caller named — a destination published by management is the operator naming their own service. - The desktop UI stops carrying a vendor URL of its own and sends the intent. Reported privately as GHSA-hf99-43rj-h577.

Commit:d25661a
Author:riccardom
Committer:riccardom

[management,client] Take the debug-bundle upload destination from management The debug-bundle paths that upload without a human picking a destination compiled the vendor endpoint in: the mobile clients and the desktop UI hold `https://upload.debug.netbird.io/upload-url` as a constant, the CLI defaults its flag to it, and the remote job falls back to it when nothing else is set. A self-hosted deployment therefore shipped peer logs, routes, DNS and firewall state to NetBird-run infrastructure without its operator ever configuring that, and had no way to point those paths anywhere else. #7147 and #7153 gave the remote job a per-job URL and an MDM override, but neither reaches the mobile, UI or CLI paths, and both fail open when unset. Publish the destination from the management server instead, on the channel that already carries stun/turn/signal/relay/flow/metrics: - `NetbirdConfig.debug.upload_url`, sourced from the new account setting `debug_bundle_upload_url` (REST + dashboard) and falling back to the new `DebugUpload.URL` in the management server config, which a self-hosted install can set once so a fresh account is not left on the vendor default. Both are validated as https-with-host where they are written; a change fans out to connected peers rather than waiting for the next login. - One resolver on the client, `debug.ResolveUploadURL`, used by every path: MDM override > explicitly named URL > destination published by management > the NetBird service, but only for a peer enrolled with NetBird's cloud. Anything else fails closed with ErrNoUploadDestination and the bundle stays local, which is the behaviour change: a self-hosted deployment that names no upload service no longer uploads at all. - The engine keeps the published value (`Engine.DebugUploadURL`) so the bundle paths, which run off the engine loop, do not have to read it back out of the opt-in sync-response store. - The daemon request grows `upload`, so "upload to wherever this deployment says" is expressible; an empty `uploadURL` no longer has to mean "no upload". The privilege gate is unchanged and still applies only to a URL the local caller named — a destination published by management is the operator naming their own service. - The desktop UI stops carrying a vendor URL of its own and sends the intent. Reported privately as GHSA-hf99-43rj-h577.

Commit:04b8bd2
Author:Theodor S. Midtlien

Merge branch 'main' into profile-ownership

Commit:f372ed0
Author:Viktor Liu
Committer:Viktor Liu

Merge branch 'main' into embedded-vnc

Commit:329b24d
Author:Zoltán Papp

[client] Drop the unused file drop port from the signal exchange The field dates from the first file drop commit, when the sender was to advertise the port its receiver had bound. Pinning the tunnel-side port replaced that: the port is fixed, a receiver that cannot bind it redirects the well-known port to whatever it got, and the sender dials the constant without negotiating. Nothing ever read the field. It never reached main, so field number 12 goes back to being free rather than needing a reserved slot. Regenerated with the pinned protoc 3.21.12 and protoc-gen-go 1.26.0, so the diff is the field and the descriptor bytes behind it.

Commit:8238e08
Author:Theodor S. Midtlien

Add owners to list profile ipc

Commit:8c5cf86
Author:pascal

Merge remote-tracking branch 'origin/main' into poc/certificate-posture

Commit:967f647
Author:Zoltan Papp

Merge branch 'main' into file-share

Commit:c2b5d21
Author:Viktor Liu
Committer:GitHub

[management] Enforce reverse proxy group access before minting and when honouring a session cookie (#7240)

Commit:be33e9e
Author:Viktor Liu

Merge branch 'main' into embedded-vnc

Commit:b08036a
Author:Viktor Liu

Merge branch 'main' into embedded-vnc

Commit:8ca9be8
Author:Zoltán Papp

Merge branch 'main' into file-share # Conflicts: # client/ios/NetBirdSDK/client.go

Commit:ebc259e
Author:Maycon Santos
Committer:GitHub

[management,client] Gate remote jobs behind an admin opt-in with MDM support (#7153) This introduces a disabled-by-default allow-remote-jobs setting that controls whether the management server may run jobs (such as debug bundles) on a peer. The flag propagates end to end: through client configuration, the daemon SetConfig and Login requests, authentication, and system info, up to management, where it is stored on the peer and exposed on the peers API as remote_jobs_allowed. The client refuses any management-requested job unless the peer has opted in. Because enabling remote jobs crosses the user-to-root boundary, turning it on requires privilege, mirroring the SSH-server gate. Administrators can enforce the setting through MDM policy on both macOS and Windows, and MDM can also override the debug-bundle upload URL. The change ships policy documentation and generated profile templates, and adds configuration, conflict, and enforcement tests covering the opt-in, privilege, and MDM paths.

Commit:1081ca0
Author:Maycon Santos
Committer:GitHub

[management,client] Add anonymize level and upload URL to remote debug bundle jobs (#7147) This extends the management-requested remote debug-bundle job with two new, optional parameters. anonymize_level selects how aggressively the bundle is scrubbed: "default" keeps internal (private) IP ranges readable, while "strict" also anonymizes private, CGNAT and link-local addresses; the value is trimmed and lowercased, and an unknown level is rejected at creation. upload_url lets an operator point the peer at a specific upload service instead of the default one; it must be a well-formed https URL with a host, and an empty value falls back to the default upload server. Both fields flow through the job workload API and are surfaced in the create-debug-job modal on the dashboard. Validation is shared so the client executor and the management boundary agree on what a valid upload URL is, preventing drift between the two checks.

Commit:6230a95
Author:mlsmaycon

Merge branch 'debug-bundle-anonymize-level-upload-url' into feat/remote-jobs-optin-mdm Sync main up the stack. Conflict resolution: - client/proto/daemon.proto: main and this branch both claimed the same field numbers for new optional fields. Kept main's enable_local_metrics/ local_metrics_address (41/42 in LoginRequest, 36/37 in SetConfigRequest) and renumbered remoteJobsAllowed to 43 (LoginRequest) and 38 (SetConfigRequest). Regenerated daemon.pb.go from the merged proto. - client/cmd/up.go: adopted main's setSSHSetConfigFields/setSSHLoginFields helpers and set remoteJobsAllowed via setBoolPtrIfChanged in setupSetConfigReq/setupLoginRequest after the SSH helper call. - client/server/ssh_gate.go: kept both the remote-jobs and the local-metrics fields and privilege gates. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUdj7EhXdGMd953nHoBUTD

Commit:a3176c9
Author:mlsmaycon

Merge remote-tracking branch 'origin/main' into debug-bundle-anonymize-level-upload-url

Commit:84d83fa
Author:pascal

implement certificate posture check

Commit:3ce0957
Author:Viktor Liu

Describe the approval no-match result and the cursor-skip key as they behave Claude-Session: https://claude.ai/code/session_01QKDYfH4WKLbpNQHccpVo3P

Commit:89aafa1
Author:Viktor Liu

Describe the approval no-match result and the cursor-skip key as they behave

Commit:12040b1
Author:Viktor Liu

Refuse an ambiguous X display and settle the approval timeout race under one claim Claude-Session: https://claude.ai/code/session_01QKDYfH4WKLbpNQHccpVo3P

Commit:8389211
Author:Viktor Liu

Refuse an ambiguous X display and settle the approval timeout race under one claim

Commit:fecd7cf
Author:Viktor Liu

Attach to the X server on the active VT and keep a retryable DXGI frame from tearing down the capturer Claude-Session: https://claude.ai/code/session_01QKDYfH4WKLbpNQHccpVo3P

Commit:c49727f
Author:Viktor Liu

Attach to the X server on the active VT and keep a retryable DXGI frame from tearing down the capturer

Commit:f7e186f
Author:Viktor Liu

Merge branch 'main' into embedded-vnc

Commit:09e069a
Author:Viktor Liu

Merge branch 'main' into embedded-vnc

Commit:63c26be
Author:Viktor Liu
Committer:GitHub

[client] Add local Prometheus metrics endpoint (#6689)

Commit:680d87d
Author:mlsmaycon

Merge branch 'debug-bundle-anonymize-level-upload-url' into feat/remote-jobs-optin-mdm # Conflicts: # shared/management/proto/management.pb.go

Commit:b074013
Author:mlsmaycon

Merge branch 'main' into debug-bundle-anonymize-level-upload-url # Conflicts: # shared/management/proto/management.pb.go

Commit:2a9c8dd
Author:riccardom
Committer:riccardom

Adds observability and fixes cross cases - strict-kem vs strict-rp said "Connected + Quantum resistance: true" but it is actually blocked - perm-kem vs perm-rp "Connected + Quantum resistance: true" but it's a classic WG link, without PQ safety

Commit:e1f91d0
Author:riccardom
Committer:riccardom

Communicate the port over the signal exchange

Commit:d29faa7
Author:riccardom
Committer:riccardom

Protocol update

Commit:9769893
Author:Zoltán Papp

Merge branch 'main' into fix/pkce-flow-session-extend management.pb.go conflicted because both sides added to it: main gave ResourceCompact an id and GroupCompact a resources list, this branch added PKCEAuthorizationFlowRequest.SessionExtend. The .proto merged cleanly, so the generated file was regenerated from it rather than resolved by hand.

Commit:e06c17c
Author:Pascal Fischer
Committer:GitHub

[management] network map from nmap data type (#6919) Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io> Co-authored-by: Dmitri Dolguikh <dmitri.external@netbird.io>

Commit:8a4aafe
Author:Zoltán Papp

Merge branch 'main' into file-share # Conflicts: # client/android/client.go # client/android/login.go # client/android/profile_prefs.go # client/internal/connect.go # client/internal/engine.go # client/mobile/profile_state.go # client/ui/i18n/locales/de/common.json # client/ui/i18n/locales/en/common.json # client/ui/i18n/locales/es/common.json # client/ui/i18n/locales/fr/common.json # client/ui/i18n/locales/hu/common.json # client/ui/i18n/locales/it/common.json # client/ui/i18n/locales/ja/common.json # client/ui/i18n/locales/pt/common.json # client/ui/i18n/locales/ru/common.json # client/ui/i18n/locales/zh-CN/common.json # client/ui/main.go

Commit:3145ad5
Author:mlsmaycon

Merge debug-bundle-anonymize-level-upload-url into feat/remote-jobs-optin-mdm Sync #7153 onto the freshly main-synced base #7147. Only conflict was the generated shared/management/proto/management.pb.go; the .proto merged cleanly (keeps remoteJobsAllowed=17 plus the base's anonymize_level/upload_url), so management.pb.go was regenerated with the pinned toolchain (protoc v3.21.12, protoc-gen-go v1.26.0), management_grpc.pb.go left untouched. Management, shared, and client trees build; the e2e suite compiles.

Commit:a171aa9
Author:mlsmaycon

Merge origin/main into debug-bundle-anonymize-level-upload-url Sync the base branch onto main (was ~50 commits behind). The only conflict was the generated shared/management/proto/management.pb.go; the .proto merged cleanly, so management.pb.go was regenerated from it with the pinned toolchain (protoc v3.21.12, protoc-gen-go v1.26.0) — management_grpc.pb.go left untouched to keep its version header. Management, shared, and client trees build clean.

Commit:7f84d90
Author:Viktor Liu
Committer:GitHub

Merge branch 'main' into proxy-oidc-group-enforcement

Commit:31c183c
Author:Zoltán Papp

Merge branch 'main' into fix/pkce-flow-session-extend Both sides extended the OAuth flow entry points: main threads a login hint through GetOAuthFlow/NewOAuthFlow, this branch threads a sessionExtend flag. The merged signatures carry both. client/android/login.go keeps main's structure — the hint reaches the flow through GetOAuthFlow rather than a loginHintSetter assertion, profile email helpers live in client/mobile, and runOAuthFlow is the shared driver — with this branch's sessionExtend plumbing and wrong-account retry layered on top. The branch's runInteractiveFlow is dropped in favour of runOAuthFlow. client/android/ssh_client.go is new from main and merged without conflict, but calls NewOAuthFlow; SSH login is a fresh login, so it passes false. management.pb.go regenerated with the pinned protoc-gen-go v1.26 from generate.sh. The .proto merged cleanly: main's LazyState and proxy_embedded are disjoint from this branch's SessionExtend field.

Commit:51095cb
Author:Viktor Liu
Committer:GitHub

[client, management] Support per-peer lazy connection state and default proxy peers to lazy (#6762) * Support per-peer lazy connection state and default proxy peers to lazy * Classify forward targets from incoming config in lazy exclusion * Set IsUserspaceBind mock so lazy manager starts in engine test * Skip lazy exclude reconciliation when the set is unchanged * Keep cached lazy flag when a sync carries no peer config

Commit:4b72019
Author:Viktor Liu

Merge branch 'main' into embedded-vnc

Commit:b6dccbb
Author:Viktor Liu

Merge branch 'main' into embedded-vnc

Commit:9af14c1
Author:Viktor Liu

Merge branch 'main' into client-local-metrics

Commit:793412f
Author:Viktor Liu

Merge branch 'main' into notification-localization

Commit:3ea046b
Author:Dmitri Dolguikh
Committer:Dmitri Dolguikh

Revert "testing breaking change" This reverts commit 05e6ef9b78fa2baec147191924b7a43e7b7f46f4. Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>

Commit:05e6ef9
Author:Dmitri Dolguikh

testing breaking change Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>

Commit:6faedeb
Author:pascal

fix proto compatibility

Commit:5885fcc
Author:Viktor Liu
Committer:Viktor Liu

Add CrowdSec AppSec request inspection to the reverse proxy

Commit:4efadd1
Author:Viktor Liu
Committer:Viktor Liu

Add allow_match any/all mode to reverse proxy access restrictions

Commit:b640804
Author:Viktor Liu
Committer:Viktor Liu

Enforce reverse proxy group access before minting and when honouring a session cookie

Commit:73cffdb
Author:Zoltán Papp

Add peer-to-peer file drop Files move directly between peers over the overlay, with no server in the path. The receiver listens on the WireGuard address only, so the port is unreachable from outside the tunnel, and every offer is matched to a known peer before anything is read. Consent is the default: an offer carries metadata alone, and no payload moves until the receiver accepts. Policy is per profile and device-local — off, ask, or auto-accept, with per-sender exceptions on top. Policy and history live in the profile's preferences, so removing a profile takes its file drop state with it. Transfers interrupted by a restart are settled on load; nothing survives to finish them, and left alone they would sit in the log as permanently pending. The Android bindings pull payload bytes through a chunk-returning stream: gomobile copies a []byte argument into a fresh Java array and never copies it back, so a fill-my-buffer method would hand back the right length with no data.

Commit:0738734
Author:Zoltán Papp

[client] Force interactive login when extending the auth session A session extend must be answered from the account the peer is registered under. With a silent PKCE flow (DisablePromptLogin or max_age=0) the IdP answers from whatever session it already holds, which need not be the peer's account when several are signed in; the token then fails the user match in ExtendAuthSession with no way to pick another account. Mark the PKCE flow request as a session extend so the management server can force prompt=login for it, overriding the configured silent flow.

Commit:fdb956a
Author:Dmitri Dolguikh

Merge remote-tracking branch 'origin/main' into revert/component-types Signed-off-by: Dmitri Dolguikh <dmitri.external@netbird.io>

Commit:e290769
Author:Viktor Liu
Committer:GitHub

[client] Take the graphical session answer from the caller instead of the daemon environment (#7187)

Commit:b08120b
Author:mlsmaycon
Committer:Maycon Santos

[management,client] Plumb anonymize level and upload URL through remote debug bundle jobs PR #7102 added an anonymization level to debug bundles and the anonymize_level proto field, but nothing on the management side ever set it: the remote-job builder dropped the field and the REST schema never exposed it, so a remotely triggered bundle always ran at the default level regardless of what an operator asked for. The upload destination for remote jobs was likewise fixed to the default upload server, with no way to direct a bundle to a self-hosted one. Expose anonymize_level and a new upload_url on the REST BundleParameters and the management proto, and map both onto the job request streamed to the client. Both are optional: an omitted value crosses the wire as the empty string, which the client resolves to its own defaults — the default anonymization level and the default upload server — matching how the netbird CLI defaults the same inputs.

Commit:1d93c5e
Author:mlsmaycon
Committer:Maycon Santos

[management,client] Report the remote-jobs opt-in to management The dashboard needs to know which peers have opted out of remote jobs so it can reflect that in the UI, the same way it surfaces the SSH server flag. Report RemoteJobsAllowed as peer system-info: the client sets it on the reported flags (like ServerSSHAllowed), the proto Flags message carries it, and management decodes it onto the peer meta and exposes it on the peers API as remote_jobs_allowed. Kept out of the components/network-map path: unlike ServerSSHAllowed it does not participate in firewall-rule calculation, so it only rides the reporting flags, not ComponentPeer.

Commit:7da4127
Author:mlsmaycon
Committer:Maycon Santos

[client] Gate remote jobs behind an admin opt-in with MDM support Remote jobs (debug bundles requested by the management server) run on the peer with no local consent. This makes them an explicit opt-in, mirroring the SSH-server opt-in: an --allow-remote-jobs flag persisted in the client config, defaulting off. Enabling it off->on crosses the user-to-root boundary and is refused for unprivileged IPC callers by the daemon gate, the same way enabling the SSH server is. When disabled, the job-stream handler refuses every job before doing any work. Because the flag is admin-controlled, it is also MDM-managed: the allowRemoteJobs policy key can enable or lock it, and a user SetConfig that diverges from an enforced value is rejected like the other managed fields. A second MDM key, debugBundleUploadURL, overrides the debug-bundle upload service for remote jobs, taking precedence over the management-supplied value (MDM > management > default). This lets an operator pin uploads to a trusted host regardless of what management requests. The override is validated as an https URL with a host, the same as the management value. Defaulting the opt-in off is a behavior change: existing deployments that rely on management-triggered debug bundles must opt in (flag or MDM) before they work again.

Commit:ec0ce38
Author:mlsmaycon

[management,client] Report the remote-jobs opt-in to management The dashboard needs to know which peers have opted out of remote jobs so it can reflect that in the UI, the same way it surfaces the SSH server flag. Report RemoteJobsAllowed as peer system-info: the client sets it on the reported flags (like ServerSSHAllowed), the proto Flags message carries it, and management decodes it onto the peer meta and exposes it on the peers API as remote_jobs_allowed. Kept out of the components/network-map path: unlike ServerSSHAllowed it does not participate in firewall-rule calculation, so it only rides the reporting flags, not ComponentPeer.

Commit:833df7a
Author:mlsmaycon

[client] Gate remote jobs behind an admin opt-in with MDM support Remote jobs (debug bundles requested by the management server) run on the peer with no local consent. This makes them an explicit opt-in, mirroring the SSH-server opt-in: an --allow-remote-jobs flag persisted in the client config, defaulting off. Enabling it off->on crosses the user-to-root boundary and is refused for unprivileged IPC callers by the daemon gate, the same way enabling the SSH server is. When disabled, the job-stream handler refuses every job before doing any work. Because the flag is admin-controlled, it is also MDM-managed: the allowRemoteJobs policy key can enable or lock it, and a user SetConfig that diverges from an enforced value is rejected like the other managed fields. A second MDM key, debugBundleUploadURL, overrides the debug-bundle upload service for remote jobs, taking precedence over the management-supplied value (MDM > management > default). This lets an operator pin uploads to a trusted host regardless of what management requests. The override is validated as an https URL with a host, the same as the management value. Defaulting the opt-in off is a behavior change: existing deployments that rely on management-triggered debug bundles must opt in (flag or MDM) before they work again.

Commit:38c5932
Author:pascal

merge main

Commit:9c889e4
Author:mlsmaycon

[management,client] Plumb anonymize level and upload URL through remote debug bundle jobs PR #7102 added an anonymization level to debug bundles and the anonymize_level proto field, but nothing on the management side ever set it: the remote-job builder dropped the field and the REST schema never exposed it, so a remotely triggered bundle always ran at the default level regardless of what an operator asked for. The upload destination for remote jobs was likewise fixed to the default upload server, with no way to direct a bundle to a self-hosted one. Expose anonymize_level and a new upload_url on the REST BundleParameters and the management proto, and map both onto the job request streamed to the client. Both are optional: an omitted value crosses the wire as the empty string, which the client resolves to its own defaults — the default anonymization level and the default upload server — matching how the netbird CLI defaults the same inputs.

Commit:5584f8e
Author:Viktor Liu
Committer:GitHub

[client] Add strict anonymization level and MAC anonymization to debug bundles (#7102)

Commit:0f77715
Author:mlsmaycon

[management,proxy] Enforce custom domain validation and scope claims per account A custom domain row was created and bound to a live service whether or not its CNAME ownership check ever succeeded. Validated was computed once, stored, and read only by the dashboard listing, so an account that never proved DNS control still had its hostname routed and a certificate ordered for it. The domain string was also claimed globally, with no expiry, so an abandoned unvalidated row blocked that name for every other account permanently. Cluster derivation now matches a custom domain only when it is validated, and reports "domain is not validated" so the API tells the caller what to fix. Service updates no longer fall back to the previously derived cluster when derivation fails, which was a way around the same check. Claims carry a claimed_at date and are evicted after 24h without validation. Uniqueness is now per (account_id, domain); the global constraint is dropped and replaced by a manager-side rule that only one account may hold a validated row for a name. That matches what the check actually proves: control of the zone, not the identity of the requester, so the first account to validate owns the name and a later one is refused. Creation pre-checks both cases and returns AlreadyExists without naming the holding account. An hourly job re-checks validated domains and, after three consecutive failed lookups, marks them unvalidated and restarts their claim window, so a domain whose DNS moved away stops being served and eventually frees the name. Custom domains are capped per account because each one becomes an ACME order against issuance rate limits shared by every account on the cluster. ProxyMapping carries the verdict and the proxy refuses to set up routes, auth, or certificate management without it, so the domain cannot be served if the management-side gate is ever regressed. This makes management the required first upgrade: a proxy on this version drops mappings from an older management that does not set the field. The migration drops the old constraint before AutoMigrate (dropping it rebuilds the table on SQLite, discarding its indexes) and backfills claimed_at from the upgrade time, so pre-existing unvalidated rows get a full window to validate before they expire.

Commit:d0bc7d9
Author:Viktor Liu
Committer:Viktor Liu

Add strict anonymization level for debug bundles and always anonymize MAC addresses

Commit:b9d83de
Author:riccardom
Committer:riccardom

Communicate the port over the signal exchange

Commit:4dd8cc9
Author:riccardom
Committer:riccardom

Protocol update

Commit:b3ead5e
Author:Viktor Liu

Localize daemon notifications via stable message keys

Commit:c93aa03
Author:pascal

merge main

Commit:610f87c
Author:riccardom
Committer:riccardom

Communicate the port over the signal exchange

Commit:09315d7
Author:riccardom
Committer:riccardom

Protocol update

Commit:e193e59
Author:mlsmaycon

[client] Route agent-network through the daemon and shape env per provider Two field-test findings drive this change: the direct-dial path needed sudo (the profile's WireGuard key is root-owned), and a single flat ANTHROPIC_* export set is wrong for providers that speak other API shapes. Relay the setup request through the daemon instead: a new GetAgentNetworkSetup daemon RPC forwards to management over the engine's existing peer connection, so unprivileged callers get the caller-scoped answer the same way 'netbird status' works — no sudo, and the key never leaves the daemon. The daemon's JSON gateway exposes the RPC for the desktop UI for free. Teach 'agent-network env' the per-provider environment contracts, mirroring Claude Code's LLM-gateway configuration: - anthropic flavor: ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN / ANTHROPIC_MODEL - bedrock_api: CLAUDE_CODE_USE_BEDROCK, ANTHROPIC_BEDROCK_BASE_URL, CLAUDE_CODE_SKIP_BEDROCK_AUTH (the proxy injects AWS credentials) - vertex_ai_api: CLAUDE_CODE_USE_VERTEX, ANTHROPIC_VERTEX_BASE_URL, CLAUDE_CODE_SKIP_VERTEX_AUTH, plus comments for the admin-supplied ANTHROPIC_VERTEX_PROJECT_ID and CLOUD_ML_REGION (the proxy forwards the URL path, so those values must be the operator's real ones) - openai flavor: OPENAI_BASE_URL / OPENAI_API_KEY - anything else: comment lines only — no guessed variables Selection stays explicit: --provider picks by operator label or catalog id and is required when several providers are authorized; --model is validated against the provider's allowed set and required when several models are allowed. Ambiguity renders as shell comments, never as exports. Linear: NET-1399

Commit:5d4c7f3
Author:mlsmaycon

[management] Add peer-facing Agent Network setup RPC Peers onboarding to the Agent Network have no way to discover which providers and models their groups authorize or which endpoint to call, so they trial-and-error into 403s at the proxy. Add GetAgentNetworkSetup, an EncryptedMessage peer RPC following the Expose service shape: the WireGuard key is the credential and the answer is caller-scoped — strictly what the calling peer's own groups authorize, computed by a new effective-setup routine in the agentnetwork manager that mirrors the proxy's enforcement exactly (policy filter as filterApplicablePolicies, model logic as policyPermitsModel, orphan and disabled providers omitted like the router synthesizer omits them). The response carries display metadata only: endpoint, provider name, catalog id, API flavor, and effective models. No keys, upstream URLs, policy or guardrail structure, and no hint of providers the caller cannot reach; "account not set up" and "caller has no access" are deliberately indistinguishable. Linear: NET-1399

Commit:0b83669
Author:riccardom
Committer:riccardom

Communicate the port over the signal exchange

Commit:990b78a
Author:riccardom
Committer:riccardom

Protocol update

Commit:af1f94b
Author:Viktor Liu

Merge branch 'main' into reverse-proxy-crowdsec-appsec # Conflicts: # management/server/store/sql_store.go # management/server/store/sql_store_service_test.go

Commit:f05f3fc
Author:Viktor Liu

Merge branch 'main' into reverse-proxy-allow-match-or # Conflicts: # management/server/store/sql_store.go # management/server/store/sql_store_service_test.go

Commit:6b7c22e
Author:Viktor Liu

Merge branch 'main' into client-local-metrics # Conflicts: # client/internal/debug/debug.go

Commit:707bc3e
Author:Viktor Liu
Committer:Viktor Liu

Support per-peer lazy connection state and default proxy peers to lazy

Commit:86d775f
Author:Viktor Liu

Merge main into embedded-vnc # Conflicts: # client/configs/configs.go

Commit:2fd27f7
Author:Viktor Liu

Merge main into embedded-vnc # Conflicts: # client/configs/configs.go