Permit logo

MIT License stars pub version

Buy Me A Coffee


Permit

A command-line tool for managing permissions in Flutter projects. permit simplifies adding, removing, and listing permissions in AndroidManifest.xml and Info.plist.


Installation

dart pub global activate permit

Motivation & Features

  • CLI-first: no Xcode or Android Studio opening, no manual file editing.
  • Reduces the risk of store rejections by generating native permission code only for APIs your app actually uses.
  • No key memorization: use keywords instead of platform-specific permission names.
  • Usage descriptions on the fly: add iOS descriptions inline, or by follow-up prompts.
  • Zero missing config: if runtime code exists, metadata exists in at least one platform config file.
  • Simple localization: one command to generate and keep iOS permission strings in sync.
  • Platform-scoped permissions: generate permissions and runtime code for Android or iOS independently.
  • Instant auditing: list all added permissions and their runtime code status.
  • Zero external dependencies: generates a local plugin you own and control—no third-party versioning issues.

Usage

permit <command> [options]

add Command

permit add <permission>

Adds permission metadata to the relevant platform files. Optionally, it can also generate runtime permission request code.

Supported Inputs

  • Explicit platform keys

    • android.permission.CAMERA
    • NSCameraUsageDescription
  • Searchable keywords

    • camera, location, microphone, etc.

If a keyword matches multiple permissions, you will be prompted to choose.

Examples

Add specific permission keys

permit add NSCameraUsageDescription
permit add android.permission.CAMERA

Platform detection is automatic; no flags are required.

Add permissions using keywords

permit add camera

If multiple matches are found:

Select permissions to add ›
[ ] Android: android.permission.CAMERA
[ ] iOS: NSCameraUsageDescription

Limit search to a platform

  • [-a], [--android] → Android only
  • [-i], [--ios] → iOS only
permit add contacts -a
Select permissions to add ›
[ ] Android: android.permission.READ_CONTACTS
[ ] Android: android.permission.WRITE_CONTACTS
[ ] Android: android.permission.GET_ACCOUNTS

Provide iOS usage descriptions inline

For iOS permissions, use [-d] / [--desc] to avoid interactive prompts:

permit add NSCameraUsageDescription -d "This app requires camera access to take photos."

Generate runtime permission code

By default, only metadata is added. To also generate runtime request code:

permit add camera -c

This will:

  • Add permission metadata
  • Generate runtime permission request code
  • Create a minimal local plugin at tools/permit_plugin
  • Automatically add the plugin to pubspec.yaml

Important

  • Run flutter pub get after the plugin is added
  • Hot-restart or rebuild after plugin updates
  • Add command updates existing keys, you can use it to update usage descriptions as well

remove Command

permit remove <permission>

Removes permission metadata and any generated runtime code.

Supported Inputs

  • Explicit permission keys
  • Searchable keywords

Examples

Remove specific permission keys

permit remove NSCameraUsageDescription
permit remove android.permission.CAMERA

Platform detection is automatic.

Remove using keywords

permit remove camera

If multiple matches are found:

Select which permissions to remove ›
[ ] Android: android.permission.CAMERA
[ ] iOS: NSCameraUsageDescription

Remove interactively

If no argument is provided, all added permissions are listed:

permit remove
Select which permissions to remove ›
[ ] Android: android.permission.CAMERA
[ ] Android: android.permission.RECORD_AUDIO
[ ] iOS: NSCameraUsageDescription
[ ] iOS: NSMicrophoneUsageDescription

list Command

permit list

Lists all permissions currently added to the project.

Example

permit list
Android: Uses Permissions (2):
  - android.permission.CAMERA [CODE]
  - android.permission.RECORD_AUDIO

iOS: Usage Descriptions (2):
  - NSCameraUsageDescription: This is used to record videos
  - NSMicrophoneUsageDescription: We need mic access to record audio with the video

[CODE] indicates that runtime permission code has been generated.

Platform filtering

  • [-a], [--android] → Android only
  • [-i], [--ios] → iOS only
permit list -a

localize Command (iOS only)

permit localize [language_codes...]

Generates or updates InfoPlist.xcstrings with localized usage description keys.

Behavior

  • Adds missing keys only; never removes existing ones

  • Respects:

    • Known region languages defined in the iOS project
    • Existing keys in InfoPlist.xcstrings
  • Language codes are not validated—use valid Apple locale identifiers

Language codes must be space-separated:

en ar_LY it fr

Examples

Generate localization for specific languages

permit localize en ar_LY it

Update all supported languages

If no arguments are passed:

permit localize

This updates existing localization files with any new permission keys.

Add additional languages

permit localize fr de

Creates French and German localization files if they don’t already exist.


build Command

permit build

Rebuilds runtime permission code based on the current platform permission metadata.

When to use

  • After manually modifying the generated plugin
  • To regenerate code from existing permission entries

NOTE: it's automatically run after add with the -c flag or removing permissions

permit detects which permissions require runtime code using the annotation:

<!--@permit:code-->

Examples

AndroidManifest.xml

<!--@permit:code-->
<uses-permission android:name="android.permission.CAMERA" />

Info.plist

<!--@permit:code-->
<key>NSCameraUsageDescription</key><string>This app requires camera access to take photos.</string>

Generated Code

The generated code is placed in tools/permit_plugin/lib/permit.dart. E.g after adding camera permission with code generation:

import 'package:permit_plugin/permit.dart';

// check permission status
final status = await Permit.camera.status;

switch(status){
    case PermissionStatus.denied:
    // Permission was denied or not yet requested.
    case PermissionStatus.granted:
    //  Permission was granted.
    case PermissionStatus.restricted:
    //  Permission is restricted (iOS only).
    case PermissionStatus.limited:
    //  Permission is limited (iOS only).
    case PermissionStatus.permanentlyDenied:
    //  Permission is permanently denied, user must enable it from settings.
    case PermissionStatus.provisional:
    // Permission is provisional (iOS only).
    case PermissionStatus.notApplicable:
    // Permission is not applicable for this platform, either not supported or not added in config files.
}

// request permission
final status = await Permit.camera.request();

// some permissions report service status
final serviceStatus = await Permit.location.serviceStatus;

// check if you should show rationale on Android
final shouldShowRationale = await Permit.microphone.shouldShowRequestRationale;

// open app settings
final wasOpened = await Permit.openSettings();

Support Permit

If you find permit useful, consider supporting the project by liking it, sharing it, or buying a coffee!

Libraries

commands/add_permission_command
commands/build_code_command
commands/list_permissions_command
commands/localize/localize_permissions_command
commands/localize/ruby_scripts
commands/localize/utils
commands/permit_runner
commands/remove_permission_command
editor/models
editor/pubspec_editor
editor/xml_editor
generate/plugin_generator
generate/templates/android/handlers/ignore_battery_optimizations_handler
generate/templates/android/handlers/kotlin_handler_snippet
generate/templates/android/handlers/manage_external_storage_handler
generate/templates/android/handlers/request_install_packages_handler
generate/templates/android/handlers/schedule_exact_alarm_handler
generate/templates/android/handlers/system_alert_window_handler
generate/templates/android/plugin_gradle_temp
generate/templates/android/plugin_kotlin_class_temp
generate/templates/android/plugin_manifest_temp
generate/templates/constants
generate/templates/ios/handlers/assistant_permission_handler
generate/templates/ios/handlers/bluetooth_permission_handler
generate/templates/ios/handlers/calendar_permission_handler
generate/templates/ios/handlers/camera_permission_handler
generate/templates/ios/handlers/contacts_permission_handler
generate/templates/ios/handlers/location_permission_handler
generate/templates/ios/handlers/media_library_permission_handler
generate/templates/ios/handlers/microphone_permission_handler
generate/templates/ios/handlers/photos_permission_handler
generate/templates/ios/handlers/reminders_permission_handler
generate/templates/ios/handlers/sensors_permission_handler
generate/templates/ios/handlers/speech_permission_handler
generate/templates/ios/handlers/swift_handler_snippet
generate/templates/ios/handlers/user_tracking_permission_handler
generate/templates/ios/plugin_pod_temp
generate/templates/ios/plugin_privacy_manifest
generate/templates/ios/plugin_swift_class_temp
generate/templates/plugin_dart_temp
generate/templates/plugin_pubspec_temp
generate/templates/template
generate/utils
path/path_finder
registry/android_permissions
registry/ios_permissions
registry/models
registry/permit_registry
utils/logger
utils/utils