{"record":{"id":"063ba999b2439323","repo":"microg/GmsCore","slug":"client-not-admin-yet-tried-to-add-work-account","errorCode":null,"errorMessage":"client not admin, yet tried to add work account","messagePattern":"client not admin, yet tried to add work account","errorType":"exception","errorClass":"SecurityException","httpStatus":null,"severity":"error","filePath":"play-services-auth-workaccount/core/src/main/kotlin/org/microg/gms/auth/workaccount/WorkAccountService.kt","lineNumber":142,"sourceCode":"            } else {\n                val future = accountManager.removeAccount(it, null, null)\n                Thread {\n                    future.result.let { result ->\n                        callback?.onAccountRemoved(result)\n                    }\n                }.start()\n            }\n        }\n    }\n}\n\nclass UnauthorizedWorkAccountServiceImpl : IWorkAccountService.Stub() {\n    override fun setWorkAuthenticatorEnabled(enabled: Boolean) {\n        throw SecurityException(\"client not admin, yet tried to enable work authenticator\")\n    }\n\n    override fun addWorkAccount(callback: IWorkAccountCallback?, token: String?) {\n        throw SecurityException(\"client not admin, yet tried to add work account\")\n    }\n\n    override fun removeWorkAccount(callback: IWorkAccountCallback?, account: Account?) {\n        throw SecurityException(\"client not admin, yet tried to remove work account\")\n    }\n}","sourceCodeStart":124,"sourceCodeEnd":148,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-auth-workaccount/core/src/main/kotlin/org/microg/gms/auth/workaccount/WorkAccountService.kt#L124-L148","documentation":"UnauthorizedWorkAccountServiceImpl.addWorkAccount unconditionally throws this SecurityException. Like its sibling methods, this stub exists to reject any work-account insertion attempt from callers that were not granted the authorized/admin service implementation — the operation is deliberately denied at the binder boundary.","triggerScenarios":"Calling addWorkAccount(callback, token) on IWorkAccountService when the client resolved to UnauthorizedWorkAccountServiceImpl because it lacks admin/authorization.","commonSituations":"Non-admin app trying to provision a work account via microG; scripts or tests invoking the binder directly; apps that should instead use AccountManager.addAccount with the work authenticator type.","solutions":["Obtain the authorized binding (the service must classify your client as admin) before calling addWorkAccount","Use AccountManager-based flows (addAccount with the work account type) intended for third-party apps","Catch SecurityException and route the user to proper work-profile provisioning","Verify you are connecting to AuthorizedWorkAccountServiceImpl, not the unauthorized stub"],"exampleFix":"// before\nworkAccountService.addWorkAccount(callback, token)\n// after\ntry {\n    workAccountService.addWorkAccount(callback, token)\n} catch (e: SecurityException) {\n    Log.w(TAG, \"Not authorized to add work account\", e)\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { svc.addWorkAccount(callback, token) } catch (e: SecurityException) { routeToWorkProfileProvisioning() }","preventionTips":["Confirm the authorized (non-stub) service implementation before calling","Use AccountManager.addAccount for provisioning from regular apps","Catch SecurityException on every work-account binder call"],"tags":["android","security","work-account","authorization"],"backgroundTag":"insufficient-permissions","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}