Skip to content

Permission Guard Pro

The permission-guard command extracts permissions from compiled artifacts — APK via apkanalyzer and IPA via plist parsing — then diffs them against a committed baseline. This catches permissions injected by third-party libraries at compile time, which source-level AndroidManifest.xml diffing cannot detect.

Why compiled extraction matters

A library added to pubspec.yaml can inject permissions into the merged AndroidManifest.xml during the Gradle build without any change to your source manifests. permission-guard reads permissions from the final artifact so no injection goes unnoticed.

Prerequisites

ToolRequired forHow to install
apkanalyzerAndroidAndroid SDK command-line tools (cmdline-tools/latest/bin/)
unzipiOSPre-installed on macOS and standard Linux distributions

Commands

android

bash
dart run monorepo_toolkit permission-guard android \
  --apk build/app/outputs/flutter-apk/app-release.apk

# Diff against a baseline
dart run monorepo_toolkit permission-guard android \
  --apk build/app/outputs/flutter-apk/app-release.apk \
  --baseline permission_baseline/android.txt

ios

bash
dart run monorepo_toolkit permission-guard ios \
  --ipa build/ios/ipa/MyApp.ipa

# Diff against a baseline
dart run monorepo_toolkit permission-guard ios \
  --ipa build/ios/ipa/MyApp.ipa \
  --baseline permission_baseline/ios.txt

update-baseline

bash
dart run monorepo_toolkit permission-guard update-baseline \
  --platform android \
  --artifact build/app/outputs/flutter-apk/app-release.apk \
  --output permission_baseline/android.txt

Flags

FlagCommandsDefaultDescription
--apkandroidrequiredPath to the compiled APK
--ipaiosrequiredPath to the compiled IPA
--baselineandroid, iosnonePath to committed baseline file to diff against
--platformupdate-baselinerequiredandroid or ios
--artifactupdate-baselinerequiredPath to APK or IPA for baseline extraction
--outputupdate-baselinerequiredDestination path for the new baseline file

Baseline pattern

Baselines are committed to the repository at:

permission_baseline/
├── android.txt
└── ios.txt

Update baselines after a deliberate permission change by running update-baseline and committing the result.

Configuration

Create a .permissionguard.yaml at the workspace root to control failure behavior:

yaml
permission_guard:
  fail_on_new: true
  warn_on_removed: true
KeyDefaultDescription
fail_on_newtrueExit 1 if new permissions are detected
warn_on_removedtruePrint a warning (but do not fail) if permissions were removed

CI integration

yaml
# Android permission gate on PR
- name: Permission guard (Android)
  run: |
    dart run monorepo_toolkit permission-guard android \
      --apk build/app/outputs/flutter-apk/app-release.apk \
      --baseline permission_baseline/android.txt

# iOS permission gate on PR
- name: Permission guard (iOS)
  run: |
    dart run monorepo_toolkit permission-guard ios \
      --ipa build/ios/ipa/MyApp.ipa \
      --baseline permission_baseline/ios.txt

# Update baseline on develop merge (Android example)
- name: Update permission baseline
  if: github.ref == 'refs/heads/develop'
  run: |
    dart run monorepo_toolkit permission-guard update-baseline \
      --platform android \
      --artifact build/app/outputs/flutter-apk/app-release.apk \
      --output permission_baseline/android.txt
    git add permission_baseline/android.txt
    git commit -m "chore: update android permission baseline"
    git push

Built by Banua Coder