Skip to content

[WIP] Add documentation for Maestro permissions system#151

Closed
Copilot wants to merge 1 commit into
mainfrom
copilot/add-permissions-system-documentation
Closed

[WIP] Add documentation for Maestro permissions system#151
Copilot wants to merge 1 commit into
mainfrom
copilot/add-permissions-system-documentation

Conversation

Copy link
Copy Markdown

Copilot AI commented May 19, 2026

Thanks for asking me to work on this. I will get started on it and keep this PR's description up to date as I form a plan and make progress.

Original prompt

User requests a full write-up explaining how the permissions system works in Maestro, detailed enough to recreate a similar system from scratch with comparable functionality. Repository explicitly provided: callstackincubator/voltra on ref main. Create a pull request that adds documentation covering:

  • Overall architecture of Maestro's permissions handling as understood from repository context.
  • End-to-end flow for setting permissions from high-level commands through platform-specific implementations.
  • Separate behavior for Android and iOS.
  • The meaning and handling of the all / grant-all flow.
  • Predefined permission sets and any platform-specific expansions.
  • Exact CLI / shell commands used by platform implementations where applicable.
  • XCTest alert-handling flow on iOS, including storage of desired permission state and auto-tapping system dialogs.
  • Distinction between simulator/device-level permission mutation and UI-driven permission dialog handling.
  • Enough implementation detail, data shapes, and control flow to let an engineer recreate a similar system from scratch.

If code/docs changes are needed, add or update documentation files in the repository accordingly.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: Find the logic responsible for granting permissions for iOS and Android. I'm interested in the 'grantAll' flow - is there a predefined set of permissions? What are the CLI commands executed by the permissions API?

Assistant: The permission-granting logic lives mostly in maestro-client/ for Android and in maestro-ios-driver/ + maestro-ios/ + the XCTest runner for iOS. For grantAll/all, yes, there is a predefined set of permissions, but it is different per platform and per iOS execution path.

Also: the code-search tool only returned a limited subset of matches, so these results may be incomplete. You can inspect more in GitHub code search here: https://github.com/search?q=repo%3Amobile-dev-inc%2FMaestro+grantAll+OR+permissions+OR+grantPermission&type=code.

Where all / “grant all” is triggered

When launchApp runs without explicit permissions, Maestro defaults to:

// For testing convenience, default to allow all on app launch
val permissions = command.permissions ?: mapOf("all" to "allow")
maestro.setPermissions(command.appId, permissions)

So the “grantAll” behavior is effectively mapOf("all" to "allow").

There is also a direct setPermissions command path:

private suspend fun setPermissionsCommand(command: SetPermissionsCommand): Boolean {
    try {
        maestro.setPermissions(command.appId, command.permissions)
    } catch (e: Exception) {
        throw MaestroException.UnableToSetPermissions("Unable to set permissions for app ${command.appId}: ${e.message}", e)
    }

    return false
}

Android: predefined permission set and CLI commands

The Android implementation is in:

  • maestro-client/src/main/java/maestro/drivers/AndroidDriver.kt

Is there a predefined set for all?

Yes. Android expands friendly names and also appears to treat "all" specially earlier in the permission collection flow, then iterates the resulting permission list and calls setPermissionInternal(...). The key execution path is:

private fun setPermissionInternal(appId: String, permission: String, rawValue: String) {
    try {
        if (permission in appOpsPermissions) {
            setAppOp(appId, permission, rawValue)
        } else {
            shell("pm ${translatePermissionValue(rawValue)} $appId $permission")
        }
    } catch (exception: Exception) {
        // Ignore if it's something that the user doesn't have control over

And for app-ops based permissions:

private fun setAppOp(appId: String, op: String, rawValue: String) {
    val opName = op.removePrefix("android.permission.")

    val appOpsValue = when (rawValue) {
        "allow" -> "allow"
        "deny" -> "deny"
        else -> "default"
    }

    sh...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

@V3RON V3RON closed this May 19, 2026
Copilot AI requested a review from V3RON May 19, 2026 06:11
Copilot stopped work on behalf of V3RON due to an error May 19, 2026 06:11
@V3RON V3RON deleted the copilot/add-permissions-system-documentation branch May 19, 2026 06:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants