microg/GmsCore · error · SecurityException

Access denied, missing google package permission for

Error message

Access denied, missing google package permission for 

What it means

microG's PackageUtils.assertGooglePackagePermission throws this SecurityException when the calling app does not hold the org.microg.gms.EXTENDED_ACCESS permission (or is not a recognized Google-signed package) required for the requested GooglePackagePermission. It is a deliberate access-control gate: the check runs against the Binder caller, then logs and rethrows the SecurityException. The message ends with the name of the missing permission (permission.name()), though here the name rendered empty in the captured message.

Source

Thrown at play-services-base/core/src/main/java/org/microg/gms/common/PackageUtils.java:68

    @Deprecated
    public static boolean isGooglePackage(@NonNull Context context, @Nullable String packageName) {
        if (packageName == null) return false;
        return new ExtendedPackageInfo(context, packageName).isGoogleOrPlatformPackage();
    }

    /**
     * @deprecated Extended access is a deprecated concept
     */
    @Deprecated
    public static boolean callerHasExtendedAccessPermission(@NonNull Context context) {
        return context.checkCallingPermission("org.microg.gms.EXTENDED_ACCESS") == PackageManager.PERMISSION_GRANTED;
    }

    public static void assertGooglePackagePermission(@NonNull Context context, GooglePackagePermission permission) {
        try {
            if (!callerHasGooglePackagePermission(context, permission))
                throw new SecurityException("Access denied, missing google package permission for " + permission.name());
        } catch (SecurityException e) {
            Log.w("ExtendedAccess", e);
            throw e;
        }
    }

    public static boolean callerHasGooglePackagePermission(@NonNull Context context, GooglePackagePermission permission) {
        for (String packageCandidate : getCallingPackageCandidates(context)) {
            if (new ExtendedPackageInfo(context, packageCandidate).hasGooglePackagePermission(permission)) {
                return true;
            }
        }

        // TODO: Replace with explicit permission instead of generic "extended access"
        if (callerHasExtendedAccessPermission(context)) return true;

        return false;
    }

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Declare <uses-permission android:name="org.microg.gms.EXTENDED_ACCESS"/> in the calling app's manifest and ensure microG's permission is installed/granted on the device.
  2. If the client should be exempt, make it a recognized Google package: sign it with the expected key or add its signature/package to the allowlist microG checks.
  3. Verify you actually need the guarded internal API; switch to the public Google Play services or microG public API surface that is not permission-gated.
  4. Catch SecurityException around the call and degrade gracefully rather than crashing.

Example fix

// before
gmsClient.callInternalApi(context);

// after
try {
    gmsClient.callInternalApi(context);
} catch (SecurityException e) {
    Log.w(TAG, "Extended microG access denied; falling back to public API", e);
    gmsClient.callPublicApi(context);
}
Defensive patterns

Strategy: try-catch

Validate before calling

int granted = context.checkCallingPermission("org.microg.gms.EXTENDED_ACCESS");
if (granted != PackageManager.PERMISSION_GRANTED) {
    Log.w(TAG, "Caller lacks EXTENDED_ACCESS; skip guarded API");
}

Type guard

boolean hasExtendedAccess(Context ctx) {
    return ctx.checkCallingPermission("org.microg.gms.EXTENDED_ACCESS") == PackageManager.PERMISSION_GRANTED;
}

Try / catch

try {
    PackageUtils.assertGooglePackagePermission(context, permission);
    doGuardedCall();
} catch (SecurityException e) {
    Log.w(TAG, "Google package permission denied: " + permission, e);
    fallbackToPublicApi();
}

Prevention

When it happens

Trigger: Calling an internal microG API guarded by assertGooglePackagePermission (e.g. from an app binding to a microG service) while the caller's UID lacks the org.microg.gms.EXTENDED_ACCESS permission and is not exempted as a Google package; also triggered when a client passes a GooglePackagePermission whose name cannot be resolved, producing a message with an empty name.

Common situations: Apps integrating with microG's extended/internal APIs instead of the public play-services surface; ROM or microG setups where a privileged client is not listed/signed as an allowed Google package; unit tests invoking the helper without granting the EXTENDED_ACCESS permission to the test caller.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/412fa69eecb1d6ba. Report an issue: GitHub.