{"record":{"id":"f55aa76b967253cf","repo":"netbirdio/netbird","slug":"private-services-cannot-enable-bearer-auth-sso","errorCode":null,"errorMessage":"private services cannot enable bearer auth (SSO): NetBird-only access and SSO are mutually exclusive","messagePattern":"private services cannot enable bearer auth \\(SSO\\): NetBird-only access and SSO are mutually exclusive","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"management/internals/modules/reverseproxy/service/service.go","lineNumber":905,"sourceCode":"\t\treturn s.validateTLSMode()\n\tdefault:\n\t\treturn fmt.Errorf(\"unsupported mode %q\", s.Mode)\n\t}\n}\n\n// validatePrivateRequirements enforces the private-service contract: HTTP mode, ≥1 access group, no bearer auth.\nfunc (s *Service) validatePrivateRequirements() error {\n\tif !s.Private {\n\t\treturn nil\n\t}\n\tif s.Mode != \"\" && s.Mode != ModeHTTP {\n\t\treturn fmt.Errorf(\"private services only support HTTP mode, got %q\", s.Mode)\n\t}\n\tif len(s.AccessGroups) == 0 {\n\t\treturn errors.New(\"private services require at least one access group\")\n\t}\n\tif s.Auth.BearerAuth != nil && s.Auth.BearerAuth.Enabled {\n\t\treturn errors.New(\"private services cannot enable bearer auth (SSO): NetBird-only access and SSO are mutually exclusive\")\n\t}\n\treturn nil\n}\n\nfunc (s *Service) validateHTTPMode() error {\n\tif s.Domain == \"\" {\n\t\treturn errors.New(\"service domain is required\")\n\t}\n\tif s.ListenPort != 0 {\n\t\treturn errors.New(\"listen_port is not supported for HTTP services\")\n\t}\n\treturn s.validateHTTPTargets()\n}\n\nfunc (s *Service) validateTCPUDPMode() error {\n\tif s.Domain == \"\" {\n\t\treturn errors.New(\"domain is required for TCP/UDP services (used for cluster derivation)\")\n\t}","sourceCodeStart":887,"sourceCodeEnd":923,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/management/internals/modules/reverseproxy/service/service.go#L887-L923","documentation":"Returned by Service.validatePrivateRequirements (management/internals/modules/reverseproxy/service/service.go:905). The private-service contract is mutually exclusive with SSO at the service level: NetBird-only access means the overlay's identity already authenticates users, while bearer auth would add a second, external identity layer. Enabling both on the same service is therefore rejected.","triggerScenarios":"Creating or updating a service that simultaneously has Private: true and Auth.BearerAuth with Enabled: true.","commonSituations":"Reusing a public SSO-protected service definition and flipping on Private without clearing bearer auth; templates or copied payloads that carry auth blocks into private services; misreading SSO as an additional hardening layer on private services.","solutions":["Choose one model: for NetBird-only access set Private and remove/disable bearer auth.","For SSO-protected public access, keep BearerAuth enabled and leave Private unset.","If you need both identity layers, expose two services (one private, one SSO) rather than combining them."],"exampleFix":"# before\n{\"name\": \"app\", \"private\": true, \"access_groups\": [\"grp-ops\"],\n \"auth\": {\"bearer_auth\": {\"enabled\": true, \"issuer\": \"https://idp/example\"}}}\n\n# after: pick one access model\n{\"name\": \"app\", \"private\": true, \"access_groups\": [\"grp-ops\"]}","handlingStrategy":"validation","validationCode":"if svc.Private && svc.Auth.BearerAuth != nil && svc.Auth.BearerAuth.Enabled {\n    return fmt.Errorf(\"choose one: NetBird-only access (private) or SSO bearer auth\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat private and SSO as alternative access models, never combined.","When copying service payloads, strip the auth block before setting private."],"tags":["go","netbird","management","reverse-proxy","sso","access-control","validation"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}