microg/GmsCore · error · SecurityException
client not admin, yet tried to enable work authenticator
Error message
client not admin, yet tried to enable work authenticator
What it means
UnauthorizedWorkAccountServiceImpl.setWorkAuthenticatorEnabled unconditionally throws this SecurityException. This stub is returned to clients that are not authorized to manage work accounts (not an admin/delegated caller), so any attempt to toggle the work authenticator through it always fails by design — it is an intentional authorization guard, not a bug.
Source
Thrown at play-services-auth-workaccount/core/src/main/kotlin/org/microg/gms/auth/workaccount/WorkAccountService.kt:138
Intent(WORK_ACCOUNT_CHANGED_BOARDCAST).setPackage("com.android.vending")
)
callback?.onAccountRemoved(success)
} else {
val future = accountManager.removeAccount(it, null, null)
Thread {
future.result.let { result ->
callback?.onAccountRemoved(result)
}
}.start()
}
}
}
}
class UnauthorizedWorkAccountServiceImpl : IWorkAccountService.Stub() {
override fun setWorkAuthenticatorEnabled(enabled: Boolean) {
throw SecurityException("client not admin, yet tried to enable work authenticator")
}
override fun addWorkAccount(callback: IWorkAccountCallback?, token: String?) {
throw SecurityException("client not admin, yet tried to add work account")
}
override fun removeWorkAccount(callback: IWorkAccountCallback?, account: Account?) {
throw SecurityException("client not admin, yet tried to remove work account")
}
}View on GitHub (pinned to 157c9d86ac)
Solutions
- Become an authorized caller: the client must satisfy the service's admin/authorization check (e.g. hold the required system/admin permission or be the designated authenticator admin)
- Use the Android AccountManager work-authenticator APIs available to regular apps instead of the restricted service
- Catch SecurityException and degrade gracefully (inform the user work-account management is unavailable)
- Request device-owner/admin provisioning if work-account administration is genuinely required
Example fix
// before
workAccountService.setWorkAuthenticatorEnabled(true)
// after
try {
workAccountService.setWorkAuthenticatorEnabled(true)
} catch (e: SecurityException) {
Log.w(TAG, "Not authorized to manage work authenticator", e)
} Defensive patterns
Strategy: try-catch
Validate before calling
val authorized = ctx.checkCallingOrSelfPermission(ADMIN_PERMISSION) == PackageManager.PERMISSION_GRANTED // per service policy
Try / catch
try { svc.setWorkAuthenticatorEnabled(true) } catch (e: SecurityException) { showNotAuthorizedUi() } Prevention
- Only manage work accounts from an authorized/admin context
- Prefer AccountManager public APIs for third-party work-account needs
- Catch SecurityException around all IWorkAccountService calls
When it happens
Trigger: Calling setWorkAuthenticatorEnabled(true/false) via IWorkAccountService when the bound implementation is UnauthorizedWorkAccountServiceImpl, i.e. the caller lacks the admin/authorization the service requires.
Common situations: A third-party app binding to the microG work-account service without being an authorized admin client; calling the work authenticator API from a non-device-owner context; attempting work-account management without the required system/admin privileges.
Understand the failure class
Background: "You do not have permission" / 403 Forbidden errors: authenticated but not allowed — causes and fixes across open-source libraries — this error's family across 31 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- client not admin, yet tried to add work account
- client not admin, yet tried to remove work account
- Access denied, missing google package permission for
- suggested UID [
- suggested PID [
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/9dc9d6169d78ef83.
Report an issue: GitHub.