Safety & verification 6 min read

Hesgoal: How to Check APK Permissions

How to check APK permissions with aapt2 and adb: read every declaration, judge each one, and compare against the 11 permissions in the Hesgoal build.

By Hesgoal App Team Published 28 October 2026 Updated 28 October 2026

A permission cannot be added to an installed app quietly. It lives in AndroidManifest.xml, inside the APK, and it is one of the few things about a package you can audit without running it. That makes the manifest the cheapest useful check available: one command, no install, no account, no emulator.

This walkthrough uses aapt2 and adb against the current Hesgoal build, package com.vvstreams.app, version 3.3. The commands work on any APK. The risk table applies specifically to this one.

Get the tools

aapt2 ships with the Android SDK build tools. If you have Android Studio, the binary is under build-tools/<version>/aapt2.exe on Windows or build-tools/<version>/aapt2 on macOS and Linux. Add that directory to PATH, or call the binary by full path.

adb ships with the platform tools. You only need it for the on-device checks; the manifest checks run entirely offline. Verify both are available:

aapt2 version
adb version

If you do not want to install the SDK, the command-line tools package from Android Developers includes both aapt2 and adb, and is smaller than the full IDE.

Read the declared permissions

aapt2 dump permissions hesgoal.apk

The output is a flat list:

package: com.vvstreams.app
uses-permission: name='android.permission.INTERNET'
uses-permission: name='android.permission.ACCESS_NETWORK_STATE'
uses-permission: name='android.permission.SYSTEM_ALERT_WINDOW'
uses-permission: name='android.permission.REQUEST_INSTALL_PACKAGES'
uses-permission: name='android.permission.FOREGROUND_SERVICE'
uses-permission: name='android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK'
uses-permission: name='android.permission.WAKE_LOCK'
uses-permission: name='com.google.android.finsky.permission.BIND_GET_INSTALL_REFERRER_SERVICE'
uses-permission: name='com.google.android.gms.permission.AD_ID'
uses-permission: name='android.permission.ACCESS_ADSERVICES_ATTRIBUTION'
uses-permission: name='android.permission.ACCESS_ADSERVICES_AD_ID'

That is eleven declarations. Anything more in a file you downloaded is a difference worth explaining.

Read the rest of the manifest

aapt2 dump badging prints the package identity and the features the package expects:

aapt2 dump badging hesgoal.apk

Look for these lines:

  • package: name='com.vvstreams.app' versionName='3.3'
  • sdkVersion:'24' and targetSdkVersion:'37'
  • application-label:'Hesgoal'
  • launchable-activity: for the entry point
  • native-code: for the ABIs included
  • uses-permission: repeated for each declaration

badging also reports application-debuggable when the flag is set. It should not appear; a debuggable release build allows run-as access to app data and is a genuine finding.

For attributes that badging omits, dump the binary XML directly:

aapt2 dump xmltree --file AndroidManifest.xml hesgoal.apk

Filter the output for the values that matter:

aapt2 dump xmltree --file AndroidManifest.xml hesgoal.apk | Select-String "debuggable|allowBackup|usesCleartextTraffic|exported"

On macOS or Linux, replace Select-String with grep -E. The interesting attributes are android:debuggable, android:allowBackup, android:usesCleartextTraffic, and android:exported on every component with an intent filter. This build sets usesCleartextTraffic=true and has no networkSecurityConfig, which is why HTTP sources can load.

Check what was actually granted

The manifest says what the app asks for. The device says what it got. With a phone connected and USB debugging enabled:

adb shell dumpsys package com.vvstreams.app

Search the output for granted=true and requested permissions. Normal permissions are granted at install with no prompt. Dangerous permissions show as denied until the user approves them. This build declares no dangerous permissions, so the runtime permission screen will be empty or nearly so.

For the two appop-gated capabilities, query the appops service directly:

adb shell appops get com.vvstreams.app SYSTEM_ALERT_WINDOW
adb shell appops get com.vvstreams.app REQUEST_INSTALL_PACKAGES

The result is allow, deny, default or ignore. A default for overlay usually means the user has never been asked and the app cannot draw over other apps. Settings screens can lag behind the actual appop state; the query does not.

You can revoke either without touching the app:

adb shell appops set com.vvstreams.app SYSTEM_ALERT_WINDOW deny
adb shell appops set com.vvstreams.app REQUEST_INSTALL_PACKAGES deny

Revoking overlay does not break playback. Revoking install-packages only removes the ability to prompt for another APK, which matters if an in-app updater is part of your reason for installing.

Three classes of permission

The count is misleading on its own. Android permissions fall into three groups, and each is granted through a different mechanism.

Three classes of permission
ClassGrant mechanismUser promptExample
NormalAutomatic at installNoneINTERNET, WAKE_LOCK
Dangerous (runtime)User dialog, revocable in SettingsYesCAMERA, READ_CONTACTS
Appop / specialSettings toggle or adb, checked per operationSometimesSYSTEM_ALERT_WINDOW

A package with forty normal permissions produces zero prompts. A package with one appop permission can draw over your bank app. Counting prompts is not a security metric.

Risk table for the eleven declarations

Risk table for the eleven declarations
PermissionClassWhat it enablesRiskRecommendation
INTERNETNormalOpen sockets to any hostLowRequired
ACCESS_NETWORK_STATENormalDetect connectivity before playbackLowAllow
WAKE_LOCKNormalKeep CPU awake during playbackLowAllow
FOREGROUND_SERVICENormalKeep a service running in backgroundLowAllow
FOREGROUND_SERVICE_MEDIA_PLAYBACKNormalDeclare that service as media playbackLowAllow
BIND_GET_INSTALL_REFERRER_SERVICENormal, granted by PlayRead install attribution valueLowAllow; ad-related
AD_IDNormalRead the resettable advertising IDMediumReset or opt out in Settings
ACCESS_ADSERVICES_ATTRIBUTIONNormalPrivacy Sandbox attribution APIMediumTied to ad SDK
ACCESS_ADSERVICES_AD_IDNormalPrivacy Sandbox ad ID APIMediumTied to ad SDK
REQUEST_INSTALL_PACKAGESAppopPrompt installation of another APKMediumDeny
SYSTEM_ALERT_WINDOWAppopDraw over other appsHighDeny

The table is not a verdict on intent. It is a mapping from declaration to capability. SYSTEM_ALERT_WINDOW is high risk because the capability itself is dangerous in any package, including one you trust today.

What the permission list does not tell you

A manifest audit is a boundary check, not a behaviour report. It cannot tell you:

  • which hosts the app contacts, or over which protocol;
  • what the ad SDK does with the advertising ID after it reads it;
  • whether a server-side configuration changes the interface after install;
  • whether a bundled third-party library contains vulnerable code.

For those questions you need traffic inspection, an SDK inventory or a code review, and each has limits. The security page states which of these checks were performed on this build and which were not. The app privacy page covers Firebase Analytics, AdMob and the cleartext-traffic finding in detail.

Diff the list across versions

The most useful audit habit is comparison. Save the permission output for each version you install:

aapt2 dump permissions hesgoal-3.3.apk > permissions-3.3.txt

When a new build arrives, run the same command and diff the files. A new dangerous permission or a new appop request in an update is more informative than any absolute count, because it shows what changed in capability rather than what changed in marketing copy.

Record the version code alongside the list. A file claiming version 3.3 with a different code is a different artifact.

Where to go next

Confirm the file before you audit it. The hash guide covers the SHA-256 comparison, and the signature explainer covers the certificate check. Both are prerequisites: auditing the permissions of an unidentified file tells you about a package you may not want.

The full permission walkthrough with plain-language explanations is on the safety page. Installation steps, including when each prompt appears, are in the install guide. The verified file and its published values are on the download page.

Written by Hesgoal App Team
Reviewed by Hesgoal App Team — Android release team · Updated 28 October 2026 · Editorial policy · How we test

Questions

What does aapt2 dump permissions print?
It prints the package name and every uses-permission element declared in the compiled AndroidManifest.xml, including the permission string and any maxSdkVersion attribute. It does not install or execute the app.
Why does the app show 11 permissions but only two prompts?
Only dangerous permissions produce runtime prompts. Normal permissions are granted at install, and appop-gated capabilities such as overlay and install-packages use a settings toggle rather than a dialog.
Can I check permissions without a computer?
Yes, after installation: Settings → Apps → Hesgoal → Permissions lists runtime grants, and Special access lists overlay and install-packages. The manifest cannot be read on the phone without a tool that parses APKs.
How do I see whether overlay is actually granted?
Run adb shell appops get com.vvstreams.app SYSTEM_ALERT_WINDOW. The output reports allow or deny, which is more reliable than reading a settings screen.
Do normal permissions still matter?
They describe capability. INTERNET is normal, but it is what lets the app contact any host it wants. The risk comes from the combination, not from the protection level alone.
Keep reading

Related articles

Go to download v3.3
4.76 MB