A detailed guide to Android's permission levels (Normal, Dangerous, Signature, Privileged, Special), their impact on app functionality, security, and AOSP implementation.
Android's permission system is a cornerstone of its security model, controlling access to sensitive resources like the camera, contacts, location, and system APIs. These permissions are categorised into different protection levels, determining how and by whom they can be granted. With SELinux and the Linux kernel adding layers of isolation, this system ensures apps operate within safe boundaries. Whether you're a developer, enthusiast, or just curious about Android, understanding these permission levels sheds light on app functionality, security, and user control.
Why Permissions Matter
Android permissions impact:
- App Functionality: They dictate which APIs or data an app can use.
- Security: They prevent unauthorised access to sensitive resources.
- User Control: Users can manage certain permissions, enhancing privacy.
- System vs. Third-Party Apps: System apps enjoy broader access compared to third-party apps.
Let's dive into the main protection levels defined in Android's permission system, as outlined in AndroidManifest.xml or system definitions, and explore their implications.
Permission Protection Levels
Android defines several protection levels for permissions, as specified in the AndroidManifest.xml or system permission definitions. These levels determine the conditions under which a permission is granted. The main protection levels are:
- Normal
- Dangerous
- Signatur
- Privileged (System)
- SignatureOrSystem (Deprecated)
- Special (Runtime, Appop)
Below, I'll explain each level, its implications, and how it affects apps.
1. Normal
Definition: Permissions that pose minimal risk to user privacy or device security. They are automatically granted at install time without user interaction.
Characteristics:
- Declared in the app's AndroidManifest.xml with
<uses-permission android:name="android.permission.INTERNET" />. - No user prompt is shown; granted by the PackageManagerService during installation.
- Available to both system and 3rd party apps.
Examples:
- android.permission.INTERNET (access the internet).
- android.permission.ACCESS_WIFI_STATE (read Wi-Fi state).
- android.permission.VIBRATE (control vibration).
Impact:
- Simplifies app development by allowing access to low-risk APIs.
- No runtime permission dialog, improving user experience.
- Misuse is unlikely to harm the user or device.
AOSP Relevance:
- Defined in frameworks/base/core/res/AndroidManifest.xml.
- Managed by PackageManagerService (frameworks/base/services/core/java/com/android/server/pm).
For Learning: Normal permissions are low-stakes but still require declaration to comply with Android's security model. Check adb shell dumpsys package to see granted permissions.
2. Dangerous
Definition: Permissions that access sensitive user data or control device features that could harm privacy or security. They require user approval at runtime (introduced in Android 6.0, API 23).
Characteristics:
- Grouped into permission groups (e.g., STORAGE, LOCATION, CAMERA).
- Declared in AndroidManifest.xml but require runtime requests via APIs like ActivityCompat.requestPermissions().
- Users can grant/deny permissions individually, and permissions can be revoked later via Settings.
- Available to both system and 3rd party apps, but system apps may bypass runtime prompts (if signed with platform key).
Examples:
- android.permission.CAMERA (access the camera).
- android.permission.READ_CONTACTS (read contact data).
- android.permission.ACCESS_FINE_LOCATION (precise location).
Impact:
- Enhances user control by allowing granular permission management.
- Increases app complexity, as developers must handle permission checks and denials.
- Affects 3rd party apps more, as users are likely to scrutinize their requests.
AOSP Relevance:
- Runtime permission system is implemented in frameworks/base/core/java/android/app and frameworks/base/services/core/java/com/android/server/pm.
- Permission groups are defined in frameworks/base/core/res/values/config.xml.
- System apps in /system/priv-app may auto-grant dangerous permissions if signed with the platform key.
For Learning:
- Study the runtime permission flow (ActivityCompat, PackageManager).
- Experiment with adb shell pm grant/revoke to simulate user actions.
- Example issue: An app crashing due to missing CHECK_PERMISSION can be debugged with logcat.
3. Signature
Definition: Permissions granted only to apps signed with the same key as the app declaring the permission (typically the platform key for system permissions).
Characteristics:
- Highly secure, as only apps with matching signatures can access the protected APIs.
- Automatically granted at install time if signatures match; otherwise, denied.
- Primarily used for system apps or apps sharing a trust relationship (e.g., OEM apps).
Examples:
- android.permission.BIND_VPN_SERVICE (bind to VPN services).
- android.permission.MANAGE_USERS (manage user accounts).
- Custom permissions defined by system apps (e.g., com.android.settings.MANAGE_SETTINGS).
Impact:
- Restricts access to sensitive system APIs, ensuring only trusted apps can use them.
- Critical for system apps interacting with core services (e.g., ActivityManagerService).
- 3rd party apps cannot access signature permissions unless signed by the OEM or platform key (rare).
AOSP Relevance:
- Defined in frameworks/base/core/res/AndroidManifest.xml or vendor-specific manifests.
- Enforced by PackageManagerService during installation, checking certificate signatures.
- Requires platform key signing (platform.x509.pem) in AOSP builds.
For Learning:
- Understand the platform key signing process (build/target/product/security).
- Study PackageManagerService for signature verification logic.
- Example: Adding a custom signature permission requires defining it in AndroidManifest.xml and signing the app with the platform key.
4. Privileged (System)
Definition: Permissions granted only to apps installed in /system/priv-app (privileged system apps) or signed with the platform key. They provide access to highly sensitive system APIs.
Characteristics:
- Similar to signature permissions but tied to the app's installation location (/system/priv-app).
- Automatically granted at install time for apps in /system/priv-app.
- Not available to 3rd party apps unless they're pre-installed as privileged by the OEM.
Examples:
- android.permission.WRITE_SECURE_SETTINGS (modify secure system settings).
- android.permission.MODIFY_PHONE_STATE (control telephony features).
- android.permission.INSTALL_PACKAGES (install apps programmatically).
Impact:
- Allows system apps to perform critical tasks (e.g., Settings app modifying system configurations).
- Enhances security by restricting powerful APIs to trusted, pre-installed apps.
- 3rd party apps cannot request these permissions, preventing misuse.
AOSP Relevance:
- Managed by PackageManagerService, checking the app's installation path and signature.
- Privileged apps are defined in the AOSP build system (LOCAL_PRIVILEGED_MODULE := true in Android.mk).
- SELinux policies (system/sepolicy) grant privileged apps broader access (e.g., system_app domain).
For Learning:
- Explore /system/priv-app on a device to see privileged apps (e.g., Settings.apk).
- Study Android.bp or Android.mk for privileged app definitions.
- Example issue: A privileged permission denied error can be debugged with logcat or dumpsys package.
5. SignatureOrSystem (Deprecated)
Definition: A legacy protection level that grants permissions to apps signed with the platform key or installed in /system/app or /system/priv-app. Deprecated in favour of stricter signature and privileged levels.
Characteristics:
- Less secure than signature or privileged, as it allows non-signed apps in /system to gain access.
- Still present in older AOSP versions or custom ROMs but rarely used in modern Android.
Examples:
- Rarely used in modern Android; previously applied to permissions like android.permission.ACCESS_ALL_EXTERNAL_STORAGE.
Impact:
- Poses a security risk, as non-signed apps in /system could gain unintended access.
- Replaced by privileged permissions in Project Treble and modern AOSP.
AOSP Relevance:
- Found in legacy AOSP code or vendor-specific implementations.
- Developers should avoid using this level in new apps or permissions.
For Learning: Understand why this level was deprecated (security concerns) and how Treble enforces stricter boundaries (privileged permissions).
6. Special (Runtime, Appop)
Definition: Permissions that require special handling, such as runtime approval by the user or system-level restrictions via AppOps (App Operations).
Characteristics:
- Managed by the AppOpsService (frameworks/base/services/core/java/com/android/server/appop).
- Often tied to specific use cases (e.g., carrier privileges, device admin).
- May require user interaction via Settings or system dialog.
Examples:
- android.permission.SYSTEM_ALERT_WINDOW (draw over other apps, requires user approval via Settings).
- android.permission.WRITE_SETTINGS (modify system settings, managed via AppOps).
- Special access permissions like DEVICE_ADMIN or NOTIFICATION_ACCESS.
Impact:
- Provides fine-grained control over sensitive features, balancing security and functionality.
- Affects both system and 3rd party apps, but system apps may bypass some restrictions.
- Users can toggle these permissions via Settings, impacting app behaviour.
AOSP Relevance:
- AppOps is a core AOSP component for managing runtime permissions and special access.
- Special permissions are enforced by system services (e.g., ActivityManagerService, AppOpsService).
For Learning:
- Study AppOpsService for how special permissions are tracked.
- Use adb shell appops to inspect or modify AppOps states.
- Example: Debugging a SYSTEM_ALERT_WINDOW denial requires checking AppOps via adb shell appops query.
How Permission Levels Affect Apps
- System Apps:
- Privileges: Can request signature and privileged permissions, granting access to system APIs (e.g., TelephonyManager, WindowManagerService).
- Installation: Pre-installed in /system/app or /system/priv-app, auto-granted most permissions.
- SELinux: Run in privileged contexts (e.g., system_app), allowing broader system access.
- Example: The Settings app uses WRITE_SECURE_SETTINGS to modify system configurations, unavailable to 3rd party apps.
2. 3rd Party Apps:
- Privileges: Limited to normal, dangerous, and some special permissions. Cannot access signature or privileged permissions.
- Installation: Installed in /data/app, requiring runtime permission requests for dangerous permissions.
- SELinux: Run in untrusted_app context, enforcing strict sandboxing.
- Example: A 3rd party camera app must request CAMERA permission at runtime and cannot access MODIFY_PHONE_STATE.
3. Security and User Experience:
- Normal permissions streamline app installation but still enforce API boundaries.
- Dangerous permissions empower users to control sensitive data but require careful app design to handle denials.
- Signature/Privileged permissions protect critical system APIs, ensuring only trusted apps (e.g., OEM or AOSP apps) can use them.
- Special permissions add flexibility for edge cases but increase user interaction.
4. Debugging and Development:
- Permission denials cause SecurityException or silent failures, logged in logcat.
- Developers use adb shell dumpsys package or adb shell appops to inspect permissions.
- System apps may require AOSP build modifications (e.g., Android.bp, platform signing) to gain privileged access.
AOSP Implementation Details
Permission Declaration:
- Permissions are defined in AndroidManifest.xml (system or app) or vendor-specific manifests.
- Example:
<permission android:name="android.permission.INTERNET" android:protectionLevel="normal" />.
Enforcement:
- PackageManagerService: Verifies permissions during app installation and runtime checks.
- Binder: Enforces permission checks for IPC (e.g., checkCallingPermission).
- SELinux: Restricts process capabilities based on domain (e.g., system_app vs. untrusted_app).
- AppOps:
- Tracks runtime permission states and special access (e.g., SYSTEM_ALERT_WINDOW).
- Integrated with ActivityManagerService and PackageManagerService.
- Build System:
- System apps are assigned permissions via Android.mk or Android.bp (e.g., LOCAL_PRIVILEGED_MODULE).
- Platform key signing is required for signature and privileged permissions.
For Learning:
- Explore frameworks/base/core/res/AndroidManifest.xml for permission definitions.
- Study PackageManagerService (frameworks/base/services/core/java/com/android/server/pm) for permission granting logic.
- Analyze SELinux policies (system/sepolicy) for permission enforcement.
Sample Interview Questions and Answers
- How would you debug a 3rd party app crashing due to a permission denial?
- First, check logcat for SecurityException or permission-related errors. Identify the missing permission (e.g., CAMERA). Verify the app's AndroidManifest.xml declares the permission. For dangerous permissions, ensure the app requests it at runtime using ActivityCompat.requestPermissions(). Use adb shell dumpsys package
<package>to confirm granted permissions. If it's a special permission (e.g., SYSTEM_ALERT_WINDOW), check AppOps with adb shell appops query. For system apps, ensure proper signing and installation in /system/priv-app.
2. Why can't a 3rd party app request a privileged permission like WRITE_SECURE_SETTINGS?
- Privileged permissions are restricted to apps installed in /system/priv-app or signed with the platform key. 3rd party apps, installed in /data/app and signed with a developer key, lack the necessary trust level. The PackageManagerService denies such requests during installation, and SELinux (untrusted_app domain) further restricts access. Granting WRITE_SECURE_SETTINGS to a 3rd party app would require root access or OEM-specific modifications, violating Android's security model.
3. How does the AppOps system enhance permission management?
- AppOps (AppOpsService) provides fine-grained, runtime control over permissions, especially for special access like SYSTEM_ALERT_WINDOW or WRITE_SETTINGS. It tracks permission states (allowed, denied, ignored) and allows users to toggle them via Settings. AppOps integrates with PackageManagerService and ActivityManagerService to enforce restrictions dynamically. Developers can query AppOps states via AppOpsManager or adb shell appops, making it a powerful tool for debugging permission issues.
Conclusion
Mastering Android's permission levels unlocks a deeper grasp of its security architecture and app ecosystem. From normal permissions easing development to privileged ones safeguarding system APIs, each level plays a vital role. Whether you're building apps, debugging issues, or exploring AOSP, this knowledge empowers you to navigate Android's complex yet robust framework.