Android's permission model is a cornerstone of user privacy and system integrity. It dictates what an application can access, from hardware sensors to sensitive user data. Permissions are categorized by their protection levels, which determine how and when they are granted.
Install-time vs Runtime Permissions
Historically, Android granted all requested permissions at install time. If a user did not agree to the permissions, they could not install the app. Starting with Android 6.0 (API level 23), the model shifted to runtime permissions for sensitive data, giving users granular control over what apps can access while actively using them.
Install-time permissions are automatically granted by the system when the application is installed, provided they are declared in the AndroidManifest.xml. Runtime permissions must be explicitly requested by the app during execution, prompting a dialog for the user to approve or deny.
Normal Permissions
normal permissions cover areas where the application needs to access data or resources outside its sandbox, but where there is very little risk to the user's privacy or the operation of other applications.
Examples:
android.permission.INTERNETandroid.permission.ACCESS_NETWORK_STATEandroid.permission.SET_ALARM
Because the risk is low, the system automatically grants normal permissions at install time. The user is not prompted, and the permission cannot be revoked via the system settings.
Dangerous Permissions and User Consent
dangerous permissions provide access to restricted data or allow the application to perform actions that could substantially affect the user's privacy or the operation of the device.
Examples:
android.permission.READ_CONTACTSandroid.permission.ACCESS_FINE_LOCATIONandroid.permission.CAMERA
These are the runtime permissions. The application must explicitly call requestPermissions() in its code. The system then displays a UI to the user. The app must handle the onRequestPermissionsResult() callback to see if the user granted the request. Users can also revoke dangerous permissions at any time through the system Settings app.
Signature Permissions
signature permissions are the most restrictive. The system grants these permissions at install time, but only if the application requesting the permission is signed with the same certificate as the application that declared the permission.
This is heavily used by the Android OS itself. Many internal system APIs are protected by signature permissions defined by the android framework package. Only apps signed with the platform key (like SystemUI, Settings, or vendor-specific apps) can be granted these permissions.
Example:
android.permission.MANAGE_USERS: Allows an application to create and delete users. This is a highly sensitive operation restricted to platform-signed apps.
Privileged Permissions and Allowlist
A subcategory of signature permissions is signature|privileged (often just called privileged permissions). These are granted to applications that are both signed with the platform key AND located in the /system/priv-app/ or /vendor/priv-app/ partition.
In modern Android versions, privileged permissions must be explicitly allowlisted by the device manufacturer. This is done via XML files in the etc/permissions/ directory. If a privileged app requests a privileged permission that is not explicitly allowlisted for that specific app package, the device will fail to boot or the app will crash, ensuring strict control over OEM-bundled applications.