Skip to main content
iOS installs and launches WebDriverAgent (WDA) only when an Apple team has signed it for that specific iPhone. mobilerun-ios setup does all of this for you. It downloads the prebuilt Mobilerun runner, gets signing material from your Apple account, signs the runner and its extensions, installs it, and checks that it launches. You do not build WDA yourself.
Signing is needed only in WDA mode. A phone on iOS 27 or later that uses native control has no runner to sign.

Choose a backend

A third option, a pre-signed runner, is for teams whose own build system already signs the runner for their phones. With no backend selected, interactive setup asks which one to use when Xcode is installed, and uses App Store Connect otherwise.

Xcode

Run it

  1. Install Xcode from the Mac App Store and open it once to finish installing its components.
  2. In Xcode → Settings → Accounts, click +, choose Apple Account, and sign in. Xcode creates an Apple Development certificate in your login keychain.
  3. Run setup:
If no certificate exists yet, setup opens Xcode and waits while you sign in. If signing in alone does not create the certificate, setup tells you to add one under Settings → Accounts → Manage Certificates → + → Apple Development. When setup asks for the runner bundle identifier, press Enter to accept the suggestion. It includes your team ID, so it does not collide with other teams’ registrations.

What setup does with Xcode

Setup uses Xcode only for its signing identity and its automatic provisioning. It does not build or run WDA in Xcode.
  1. Selects your identity. Setup lists the Apple Development identities in your login keychain. It uses the one you name with --identity, the only one present, or the one you pick.
  2. Chooses the bundle identifier. The default is ai.mobilerun.WebDriverAgentRunner.<teamid>.xctrunner. Change it with --wda-bundle-id or wda.bundle_id.
  3. Downloads the runner from wda.unsigned_url. The default is the latest Mobilerun WebDriverAgent release.
  4. Finds or creates provisioning profiles for the runner and for every extension in it, for example Broadcast. Setup first looks for an Xcode-managed development profile that covers the bundle identifier, your team, and this phone. If there is none, setup builds a small throwaway Xcode project for that identifier with xcodebuild automatic provisioning. On your team, this registers the phone, creates the App ID, and creates a development profile. The new profile lands in Xcode’s profile folder.
  5. Signs in place with Apple’s codesign and your keychain identity. It signs the extensions first, then the runner. The private key never leaves your keychain, and setup does not export it.
  6. Installs and checks the runner. Setup installs the signed app, asks you to trust the developer on the phone, and confirms that the runner launches.
To list the identities setup can choose from:

Free Apple Accounts

A free (personal-team) account works, with Apple’s limits:
  • Its profiles expire after 7 days. When they expire, the runner stops launching. Renew it with mobilerun-ios setup <udid> --reinstall --backend xcode.
  • Apple limits how many App IDs a free account can register in a week, and how many apps it can sign for one phone.
  • It cannot use Network Extensions, so it cannot sign the VPN tunnel runner.

Unattended Xcode signing

For auto, reset, and setup --non-interactive, set the identity in ~/.mobilerun-ios/config.yaml:
identity accepts the certificate’s SHA-1 fingerprint, the Apple account, or the full identity name. Without identity, non-interactive signing needs exactly one identity in the keychain. The keychain must be unlocked for the user that runs the CLI. On a headless Mac, unlock the login keychain in that user’s session.

App Store Connect

Prepare an API key

  1. In App Store Connect, open Users and Access → Integrations → App Store Connect API.
  2. Create a team key that can manage certificates, devices, identifiers, and profiles. The Admin role gives this access. If you cannot create keys, ask your team’s Account Holder or an Admin.
  3. Record the Key ID and Issuer ID, and download the .p8 file. Apple lets you download it only once.
Store the key privately on the host:

Run it

If no account is configured, setup asks for a name, the key ID, the issuer ID, and the path to the .p8 file. It saves them under signing.accounts in ~/.mobilerun-ios/config.yaml. The key file stays where you put it. To configure the account yourself, add this to the file:
Saving an account with an existing name replaces that entry. With more than one account, set signing.account or pass --account <name>. Unattended runs have no account picker.

What setup does with App Store Connect

Every step uses the App Store Connect API on your team.
  1. Development certificate. The first time, setup generates a private key on the host and creates an Apple Development certificate for this API key. It caches both under ~/.mobilerun-ios/signing/ and reuses them until the certificate expires.
  2. Device. Setup registers the phone’s UDID on the team, or turns a disabled registration back on.
  3. App IDs. Setup registers the runner’s bundle identifier, and one for each extension in the downloaded runner. The default runner ID is ai.mobilerun.WebDriverAgentRunner.asc-<hash>.xctrunner. The hash comes from your issuer ID, so it stays the same when you rotate the key. For the VPN tunnel runner, setup also turns on the Network Extensions capability for the runner and tunnel App IDs.
  4. Profiles. For the runner and each extension, setup reuses an active development profile that contains the certificate and this phone. Otherwise it creates one, named after the phone. Apple does not allow changes to profiles, so adding a phone means that setup deletes that phone’s profile and creates it again.
  5. Signs, installs, and checks. Setup signs the runner and its extensions on the host without Xcode, which is why this backend also works on Linux. Then it installs the runner, asks you to trust the developer on the phone, and confirms that the runner launches.
This backend changes your Apple team. It uses device slots and creates App IDs, certificates, and profiles. Use a team, or a key, that you have set aside for automation.

VPN tunnel runner

Proxy support on the phone uses the tunnel-enabled runner. It has an extra packet-tunnel extension. To use it, point setup at the tunnel artifact and sign with a paid team:
To make it the default for this host, set wda.unsigned_url to the same URL. Both backends then request Network Extensions access with packet-tunnel-provider:
  • App Store Connect turns on the capability for the runner and tunnel App IDs.
  • Xcode reuses only profiles that include the grant, and creates missing ones through automatic provisioning with packet-tunnel entitlements.
If the team cannot get the capability, signing stops with an error. It does not install the runner without the extension. The first time the phone uses the VPN, it can ask you to approve it on screen. The host command mobilerun-ios tunnel start is not related to this runner. That command carries native video on iOS 27 and later.

Bundle identifiers

Let setup choose the identifier unless you already own a registration you want to reuse:
  • App Store Connect: ai.mobilerun.WebDriverAgentRunner.asc-<hash>.xctrunner, from your issuer ID.
  • Xcode: ai.mobilerun.WebDriverAgentRunner.<teamid>.xctrunner, from your team ID.
  • Reinstall: --reinstall keeps the identifier of a custom Mobilerun runner that is already installed.
To choose one yourself, pass --wda-bundle-id, set wda.bundle_id, or set MOBILERUN_IOS_WDA_BUNDLE_ID. The portal uses the same value to find the runner to launch. An identifier must contain WebDriverAgentRunner and end in .xctrunner. Extensions get the same prefix, such as <id>.broadcast and <id>.tunnel. App IDs are unique across all Apple teams, so do not copy another team’s identifier.

Runner source precedence

setup, auto (when a runner is missing), and reset choose the runner source in this order:
  1. A signing selection (signing.backend, signing.account, signing.identity, or the matching setup flags): the CLI downloads wda.unsigned_url and signs it. This applies even when wda.signed_url is set. If signing fails, the CLI never falls back to the pre-signed artifact.
  2. No signing selection, and wda.signed_url is set: the CLI installs that pre-signed IPA as it is.
  3. Neither: interactive setup asks you to choose a backend. Non-interactive runs use App Store Connect with the only configured account.
To pin a fleet to one WDA version, set wda.unsigned_url to a versioned release URL. For example, use https://github.com/droidrun/WebDriverAgent/releases/download/v1.3.1/WebDriverAgentRunner-Runner.zip.

Pre-signed runners

If your own build system signs the runner for your phones, configure the artifact and leave signing.* unset:
For one setup run, pass --wda-signed-url <url> instead. The artifact must already contain valid signatures and profiles for the runner and every extension, and those profiles must include the target phone’s UDID. The CLI checks that the runner installs and launches. Downloading the same artifact again does not fix an expired profile, a missing UDID, or missing developer trust. Treat signed download URLs as secrets. The default wda.unsigned_url release is not signed. Do not use it as wda.signed_url.

Renew or repair signing

Setup does not re-sign an installed runner by itself, and auto keeps installed runners. To renew an expired signature or replace a runner, stop whatever owns the phone, then reinstall:
--reinstall implies --wda and uses your configured backend. Add --backend, --account, or --identity to override it. The phone needs internet access so iOS can check the developer profile with Apple. If prompted, open Settings → General → VPN & Device Management, select the developer, and trust it. A valid signature on the host does not prove that iOS accepted it. verify --deep launches the runner to prove it.

Troubleshooting