Android app permissions form the frontline defense between your personal data and the applications you install. With modern Android versions introducing more granular permission controls and new runtime permission categories, understanding how to audit these permissions has become essential for developers and power users who value their privacy and security.

This guide covers practical methods for auditing Android app permissions using built-in tools, ADB commands, and programmatic approaches. You’ll learn how to identify overprivileged apps, understand permission groups, and implement automated audit workflows.

Android Permission System Overview

Android organizes permissions into three protection levels that determine how users and developers interact with them:

Android 14 and the 2026 platform updates have added new permission categories including READ_MEDIA_VISUAL_USER_SELECTED for more granular photo access and improved NEARBY_WIFI_DEVICES permission for device discovery without location dependency.

Auditing Permissions via Settings

The most straightforward method for reviewing permissions uses Android’s Settings interface. Navigate to Settings > Apps, select any application, and tap Permissions to see a complete list of requested permissions grouped by category.

For a comprehensive overview of all apps with dangerous permissions, access Settings > Privacy > Permission Manager. This view groups permissions by category (Location, Camera, Microphone, Contacts, etc.) and shows which apps have access—essential for identifying apps that may no longer need certain permissions.

Modern Android versions display permission indicators in the status bar when apps actively use sensitive capabilities. A persistent camera or microphone icon warrants immediate investigation.

Using ADB for Comprehensive Audits

The Android Debug Bridge (ADB) provides powerful command-line capabilities for auditing permissions at scale. Enable developer options and USB debugging on your device, then connect via USB or wireless debugging.

Listing All App Permissions

Query all installed packages and their permissions using this command:

adb shell pm list packages -3 | while read pkg; do
  echo "=== $pkg ==="
  adb shell dumpsys package "$pkg" | grep -E "granted=|permission "
done

This outputs each third-party app with its permission status, including whether each dangerous permission is granted or denied.

Exporting Permission Report

Generate a complete permission inventory for analysis:

adb shell pm list packages -3 -u > packages.txt
while read pkg; do
  pkg_trimmed=${pkg#package:}
  echo "Package: $pkg_trimmed" >> permissions_report.txt
  adb shell dumpsys package "$pkg_trimmed" | \
    grep -E "runtime" | \
    grep "permission" >> permissions_report.txt
done < packages.txt

Revoking Permissions via ADB

For apps you cannot uninstall but want to restrict:

adb shell pm revoke com.example.app android.permission.CAMERA
adb shell pm revoke com.example.app android.permission.RECORD_AUDIO
adb shell pm revoke com.example.app android.permission.ACCESS_FINE_LOCATION

Note that some system apps may ignore revocations. You can also reset all permissions for an app:

adb shell pm reset-permissions com.example.app

Programmatic Permission Auditing

For developers building security tools or implementing automated audits, Android provides the PackageManager API for inspecting permissions programmatically.

Reading Permissions in Android Code

val packageManager = context.packageManager
val packageInfo = packageManager.getPackageInfo(
    "com.example.targetapp",
    PackageManager.GET_PERMISSIONS
)

packageInfo.requestedPermissions?.forEachIndexed { index, permission ->
    val isGranted = packageInfo.requestedPermissionsFlags[index] and
        PackageInfo.REQUESTED_PERMISSION_GRANTED != 0
    
    println("Permission: $permission")
    println("Granted: $isGranted")
}

Permission Group Mapping

Dangerous permissions belong to permission groups. Understanding this relationship helps assess the actual access level:

val dangerousPermissions = mapOf(
    "android.permission.READ_CONTACTS" to "CONTACTS",
    "android.permission.WRITE_CONTACTS" to "CONTACTS",
    "android.permission.GET_ACCOUNTS" to "CONTACTS",
    "android.permission.ACCESS_FINE_LOCATION" to "LOCATION",
    "android.permission.ACCESS_COARSE_LOCATION" to "LOCATION",
    "android.permission.ACCESS_BACKGROUND_LOCATION" to "LOCATION",
    "android.permission.CAMERA" to "CAMERA",
    "android.permission.RECORD_AUDIO" to "MICROPHONE",
    "android.permission.READ_CALENDAR" to "CALENDAR",
    "android.permission.WRITE_CALENDAR" to "CALENDAR",
    "android.permission.READ_SMS" to "SMS",
    "android.permission.SEND_SMS" to "SMS"
)

Granting any permission within a group typically grants access to the entire group’s data. For instance, READ_CONTACTS provides access to all contacts.

Automating Permission Reviews

Creating a scheduled audit process helps maintain ongoing security. This Python script generates permission reports:

import subprocess
import json
from datetime import datetime

def get_installed_packages():
    result = subprocess.run(
        ['adb', 'shell', 'pm', 'list', 'packages', '-3', '-f'],
        capture_output=True, text=True
    )
    packages = []
    for line in result.stdout.splitlines():
        pkg = line.replace('package:', '').split('=')[0]
        packages.append(pkg)
    return packages

def get_package_permissions(package):
    result = subprocess.run(
        ['adb', 'shell', 'dumpsys', 'package', package],
        capture_output=True, text=True
    )
    permissions = []
    for line in result.stdout.splitlines():
        if 'android.permission.' in line and 'granted=true' in line:
            perm = line.strip().split(':')[0]
            permissions.append(perm)
    return permissions

def generate_audit_report():
    packages = get_installed_packages()
    report = {
        'timestamp': datetime.now().isoformat(),
        'apps': []
    }
    
    for pkg in packages:
        try:
            perms = get_package_permissions(pkg)
            if perms:
                report['apps'].append({
                    'package': pkg,
                    'permissions': perms,
                    'count': len(perms)
                })
        except Exception as e:
            print(f"Error processing {pkg}: {e}")
    
    with open(f"permission_audit_{datetime.now().strftime('%Y%m%d')}.json", 'w') as f:
        json.dump(report, f, indent=2)
    
    return report

if __name__ == "__main__":
    report = generate_audit_report()
    print(f"Audit complete. Found {len(report['apps'])} apps with permissions.")

Run this weekly via cron or systemd timers to track permission changes over time.

Interpreting Permission Requests

Not all permissions indicate malicious intent. When auditing, consider the app’s legitimate functionality:

Be suspicious of permission combinations that exceed the app’s apparent function—a simple calculator requesting READ_CONTACTS or RECORD_AUDIO warrants investigation.

Best Practices for Permission Hygiene

Implement these practices to maintain tight permission control:

  1. Review before installing: Play Store’s permission summary shows all requested dangerous permissions before download
  2. Use “While Using” restrictions: Prefer “Allow only while using” over “Allow all the time” for location and camera
  3. Deny non-essential permissions: Many apps function without all requested permissions—test by denying
  4. Audit quarterly: Run comprehensive permission audits every three months
  5. Remove unused apps: Uninstall applications no longer in use rather than leaving them installed
  6. Check background access: Android’s Privacy Dashboard shows which apps accessed sensitive permissions recently

Conclusion

Regular Android app permission audits are a fundamental security practice. Whether using built-in tools for quick checks or implementing automated scripts for comprehensive reviews, staying aware of what access you’ve granted protects your personal data.

The Android permission system continues evolving—with each release offering users more control. Take advantage of these controls, audit regularly, and revoke permissions that no longer serve a purpose.

Built by theluckystrike — More at zovo.one