Privileged apps are system apps that are located in a
priv-app
directory on one of the system image partitions. The
partitions used for Android releases are
- Android 8.1 and lower -
/system
- Android 9 and higher -
/system, /product, /vendor
Throughout this page, /etc/permissions/priv-app
resolves to
partition/etc/permissions/priv-app
.
Historically, device manufacturers had little control over which
signature|privileged permissions could be granted to
privileged apps. Starting in Android 8.0, manufacturers must explicitly grant
privileged permissions in the system configuration XML files in the
/etc/permissions
directory. As of Android 9, implementors must
explicitly grant or deny all privileged permissions or the device won’t
boot.
The privapp-permissions.xml
file can only grant or deny
permissions for privileged apps on the same partition. For example, if
an app on the /vendor
partition requests privileged permissions,
the request can only be granted or denied by a
privapp-permissions.xml
file that’s also on
/vendor
.
Adding allowlists
Permission allowlists for apps can be listed in a single XML or in multiple
XML files located in the frameworks/base/etc/permissions
directory as follows:
/etc/permissions/privapp-permissions-OEM_NAME.xml
/etc/permissions/privapp-permissions-DEVICE_NAME.xml
There is no strict rule for organizing content. Device implementers can
determine content structure as long as all apps from
/system/priv-app
are allowlisted. For example, Google has a
single allowlist for all privileged apps developed by Google, and
recommends the following organization:
- Permissions for apps that are already included in the Android Open Source
Project (AOSP) tree are listed in
/etc/permissions/privapp-permissions-platform.xml
. - Permissions for Google apps are listed in
/etc/permissions/privapp-permissions-google.xml
. - For other apps, use files of the form:
/etc/permissions/privapp-permissions-DEVICE_NAME.xml
.
Generating allowlists
To automatically generate an allowlist for all apps available on the
system image, use the AOSP command line tool at
development/tools/privapp_permissions/privapp_permissions.py
. To
generate an initial version of device-specific
privapp-permissions.xml
:
- Build a system image:
. build/envsetup.sh
lunch PRODUCT_NAME
make -j
- Run the
privapp_permissions.py
script to generate aprivapp-permissions.xml
file that lists all signature|privileged permissions required to be allowlisted:development/tools/privapp_permissions/privapp_permissions.py
This tool prints XML content that can be used either as a single file, or split into multiple files in the/etc/permissions
directory path. If the device already includes allowlists in the/etc/permissions
directories, the tool only prints the differences (such as the missing signature|privileged permissions you need to add to the allowlist). This is also useful for audit purposes: When a new version of the app is added, the tool detects the additional permissions needed. - Copy the generated files to the appropriate
/etc/permissions
directory, where the system reads the files during boot.
Customizing allowlists
AOSP includes an allowlist implementation that can be customized as needed.
Permissions for apps included in AOSP are already allowlisted in
/etc/permissions/privapp-permissions-platform.xml
.
By default, the privapp_permissions.py
script generates output
that automatically grants any permission requested by a privileged
application. If there are permissions that should be denied, edit the XML to
use a "deny-permission" tag instead of a "permission" tag. Example:
<!-- This XML file declares which signature|privileged permissions to grant to privileged apps that come with the platform --> <permissions> <privapp-permissions package="com.android.backupconfirm"> <permission name="android.permission.BACKUP"/> <permission name="android.permission.CRYPT_KEEPER"/> </privapp-permissions> <privapp-permissions package="com.android.cellbroadcastreceiver"> <!-- Don't allow the application to interact across users --> <deny-permission name="android.permission.INTERACT_ACROSS_USERS"/> <permission name="android.permission.MANAGE_USERS"/> <permission name="android.permission.MODIFY_PHONE_STATE"/> <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> <permission name="android.permission.RECEIVE_EMERGENCY_BROADCAST"/> </privapp-permissions> ...
Finding missing permissions
To find missing permissions when bringing up a new device, enable transitional log mode:
ro.control_privapp_permissions=log
Violations are reported in the log file, but nonprivileged permissions are still granted. This keeps the device in a working state while providing the list of violations. This is the error message format:
PackageManager: Privileged permission {PERMISSION_NAME} for package {PACKAGE_NAME} - not in privapp-permissions allowlist
All violations must be addressed by adding the missing permissions to the appropriate allowlists.
- On Android 8.0 and lower, the affected apps aren’t granted the missing
permissions even if they are in the
priv-app
path. - On Android 9 and higher, violations (of privileged permissions) mean the device doesn’t boot. You must explicitly either allow or deny all privileged permissions
Enforcing allowlists
After allowlists are in place, enable runtime enforcement by setting the build
property ro.control_privapp_permissions=enforce
.