Skip to content

Per-App Signing Configuration

Each app in RunnerHub requires a signing configuration:

  • Bundle Identifier: Your app’s unique ID (e.g., com.example.myapp)
  • Signing Type: How your app should be signed (development, adhoc, appstore, or developer-id for macOS outside-App-Store distribution)
  • Apple Credential: Select which workspace-level Apple credential this app uses (required for automatic mode)

These settings tell RunnerHub which certificate and provisioning profile to use for your build.

  1. In the RunnerHub dashboard, go to AppCode Signing tab
  2. Enter:
    • Bundle Identifier: Your app’s bundle ID
    • Signing Type: Select development, adhoc, appstore, or developer-id (macOS only)
  3. Click Save

Use for development builds and testing on simulators or TestFlight.

  • Certificate: Apple Development
  • Devices: Limited to development team members
  • Provisioning: Supports up to 100 devices per team

Use for ad-hoc distribution to a limited set of devices.

  • Certificate: Apple Distribution
  • Devices: You specify which devices can run the app
  • Provisioning: Includes specific UDIDs

Use for App Store submission and production distribution.

  • Certificate: Apple Distribution
  • Devices: No device restrictions; runs on all devices that download from the App Store
  • Provisioning: Standard app store provisioning profile

Use for distributing macOS apps outside the App Store.

  • Certificate: Developer ID Application
  • Platform: macOS only (not available for iOS/iPadOS)
  • Distribution: Direct distribution to end users or third-party stores
  • Provisioning: No provisioning profile required (Developer ID signing is not provisioning-profile-based)

When your job runs, RunnerHub:

RunnerHub securely retrieves your signing credentials for the job:

  • Your API key credentials
  • Certificate private key
  • Bundle ID and signing type
  • Creates a temporary keychain for the job
  • Imports your certificate
  • Installs the provisioning profile

Your pipeline steps can access:

Terminal window
APPLE_TEAM_ID=ABC123D45E
DEVELOPMENT_TEAM=ABC123D45E
PROVISIONING_PROFILE=<profile-uuid>
CODE_SIGN_STYLE=Manual
OTHER_CODE_SIGN_FLAGS=--keychain <ephemeral-keychain-path>
APP_STORE_CONNECT_API_KEY_KEY_ID=<key-id>
APP_STORE_CONNECT_API_KEY_ISSUER_ID=<issuer-id>
RH_PROVISIONING_PROFILE_UUID=<profile-uuid>
RH_PROVISIONING_PROFILE_NAME=<profile-name>
RH_KEYCHAIN_PATH=<ephemeral-keychain-path>
RH_EXPORT_OPTIONS_PLIST=/path/to/ExportOptions.plist

Note: PROVISIONING_PROFILE_SPECIFIER and CODE_SIGN_IDENTITY are written into the Xcode project’s build settings (via pbxproj/xcconfig patching), not exported as env vars.

These variables are available to:

  • Xcode and xcodebuild
  • Fastlane and other build tools
  • Your custom scripts

RunnerHub automatically creates an ExportOptions.plist file with the correct configuration for exporting your app. The file is created in the workspace root and exposed via the RH_EXPORT_OPTIONS_PLIST environment variable.

The generated plist includes:

  • method: Your signing type (app-store-connect, ad-hoc, development, or developer-id)
  • teamID: Your Apple Team ID
  • signingStyle: manual (RunnerHub manages the signing)
  • provisioningProfiles: Bundle ID to profile UUID mapping (omitted for Developer ID flows with no provisioning profile)

You can use this in your export step:

Terminal window
xcodebuild -exportArchive \
-archivePath $PWD/build/MyApp.xcarchive \
-exportPath $PWD/build \
-exportOptionsPlist $RH_EXPORT_OPTIONS_PLIST

When is the plist generated?

  • An ExportOptions.plist is generated whenever signing certificates are installed (both manual and automatic modes)
  • For Developer ID flows with no provisioning profile, the file omits the provisioningProfiles dict
  • Only if no existing ExportOptions.plist exists in your repository root (your existing plist always takes precedence)

This allows you to either:

  • Use the auto-generated plist for convenience (recommended for simple builds)
  • Maintain your own custom plist for advanced configurations

RunnerHub automatically modifies your project.pbxproj to enable manual signing:

Terminal window
CODE_SIGN_STYLE=Manual
CODE_SIGN_IDENTITY=Apple Distribution
DEVELOPMENT_TEAM=ABC123D45E
PROVISIONING_PROFILE_SPECIFIER=<profile-name>
OTHER_CODE_SIGN_FLAGS=--keychain <ephemeral-keychain-path>

This ensures your build uses the correct credentials.

Your build commands work unchanged:

Terminal window
xcodebuild archive \
-workspace MyApp.xcworkspace \
-scheme MyApp \
-configuration Release

Xcode automatically uses the provisioning profile and signing identity from the environment and project settings.

If you use Fastlane, signing works automatically. Fastlane reads environment variables and the patched build settings:

desc "Build for App Store"
lane :build_appstore do
build_app(
workspace: "MyApp.xcworkspace",
scheme: "MyApp",
configuration: "Release",
export_method: "app-store",
# Fastlane reads DEVELOPMENT_TEAM, PROVISIONING_PROFILE (UUID), CODE_SIGN_STYLE,
# OTHER_CODE_SIGN_FLAGS from the environment, plus the patched build settings in pbxproj/xcconfig
)
end

Fastlane reads DEVELOPMENT_TEAM, PROVISIONING_PROFILE (UUID), CODE_SIGN_STYLE, OTHER_CODE_SIGN_FLAGS from the environment, plus the patched build settings in pbxproj/xcconfig. No Fastlane-specific configuration is needed.

For Flutter apps, RunnerHub patches the xcconfig files instead of project.pbxproj:

Modified Files:

  • ios/Flutter/Debug.xcconfig
  • ios/Flutter/Release.xcconfig
  • ios/Flutter/Profile.xcconfig

RunnerHub adds:

CODE_SIGN_STYLE = Manual
CODE_SIGN_IDENTITY = Apple Distribution
DEVELOPMENT_TEAM = ABC123D45E
PROVISIONING_PROFILE_SPECIFIER = <profile-name>
OTHER_CODE_SIGN_FLAGS = --keychain <ephemeral-keychain-path>

Note: On Developer ID flows, the PROVISIONING_PROFILE_SPECIFIER setting is omitted (no profile required).

Your Flutter build then uses these settings automatically.

Your bundle ID must be registered in your Apple Developer account:

  1. Go to App Store Connect
  2. Click Certificates, Identifiers & Profiles
  3. Click Identifiers
  4. Verify your bundle ID is listed (or create a new one)

If your bundle ID is not registered, provisioning profile creation will fail, and your build will not be signed.

If you have multiple apps in one workspace, each can have its own signing configuration:

AppBundle IDSigning Type
MyAppcom.example.myappappstore
MyApp Devcom.example.myapp.devdevelopment
MyApp Stagingcom.example.myapp.stagingadhoc

Each app uses the same API key and certificates from the workspace, but with different bundle IDs and profiles.

To change your app’s signing configuration:

  1. Go to AppCode Signing tab
  2. Update Bundle Identifier or Signing Type
  3. Click Save

The next build will use the new configuration. No additional setup is needed.

“Bundle ID not registered”

  • Verify the bundle ID in App Settings matches your Xcode project
  • Check that the bundle ID is registered in Apple Developer

“Signing type mismatch”

  • Ensure your signing type (development/adhoc/appstore) matches your deployment target
  • For TestFlight, use appstore; for ad-hoc distribution, use adhoc

“Certificate not found”

  • Verify API key is configured at workspace level
  • Check that the workspace has valid Apple credentials

See Code Signing Troubleshooting for more help.