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
- Install Xcode from the Mac App Store and open it once to finish installing its components.
- In Xcode → Settings → Accounts, click +, choose Apple Account, and sign in. Xcode creates an Apple Development certificate in your login keychain.
-
Run setup:
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.- 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. - Chooses the bundle identifier. The default is
ai.mobilerun.WebDriverAgentRunner.<teamid>.xctrunner. Change it with--wda-bundle-idorwda.bundle_id. - Downloads the runner from
wda.unsigned_url. The default is the latest Mobilerun WebDriverAgent release. - 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
xcodebuildautomatic 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. - Signs in place with Apple’s
codesignand your keychain identity. It signs the extensions first, then the runner. The private key never leaves your keychain, and setup does not export it. - 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.
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
Forauto, 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
- In App Store Connect, open Users and Access → Integrations → App Store Connect API.
- 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.
- Record the Key ID and Issuer ID, and download the
.p8file. Apple lets you download it only once.
Run it
.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:
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.- 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. - Device. Setup registers the phone’s UDID on the team, or turns a disabled registration back on.
- 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. - 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.
- 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.
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: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.
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:
--reinstallkeeps the identifier of a custom Mobilerun runner that is already installed.
--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:
- A signing selection (
signing.backend,signing.account,signing.identity, or the matchingsetupflags): the CLI downloadswda.unsigned_urland signs it. This applies even whenwda.signed_urlis set. If signing fails, the CLI never falls back to the pre-signed artifact. - No signing selection, and
wda.signed_urlis set: the CLI installs that pre-signed IPA as it is. - Neither: interactive
setupasks you to choose a backend. Non-interactive runs use App Store Connect with the only configured account.
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 leavesigning.* unset:
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, andauto 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.