App Store Connect API Key
This guide explains how to create an App Store Connect API key for automated iOS app deployment with MobileCtl.
Overview
An App Store Connect API key is required to:
- Upload IPA files to TestFlight
- Submit apps to App Store review
- Manage app metadata programmatically
- Add testers and manage builds
- Automate iOS deployment
Prerequisites
Before you begin, make sure you have:
- Apple Developer Program membership ($99/year)
- App Store Connect access
- Account Holder or Admin role (required to create API keys)
- An app created in App Store Connect
Step 1: Access App Store Connect
1.1 Log In
- Go to App Store Connect
- Sign in with your Apple ID
- Complete two-factor authentication if prompted
1.2 Verify Permissions
- Click your name in the top right
- Select Users and Access
- Find your account
- Verify you have Admin or Account Holder role
Permissions Required
Only Account Holder or Admin users can create API keys. If you don't have these permissions, ask your account administrator.
Step 2: Generate API Key
2.1 Navigate to API Keys
- Click Users and Access in the top menu
- Click the Keys tab
- You'll see App Store Connect API section
2.2 Request Access (First Time Only)
If this is your first time accessing API keys:
- Click Request Access
- Review the terms and conditions
- Click Generate API Key
2.3 Create New Key
Click the + button (or Generate API Key)
Fill in the details:
- Name:
MobileCtl Deployment(or any descriptive name) - Access: Select appropriate level:
- Admin: Full access (recommended for automation)
- App Manager: Can manage apps and submissions
- Developer: Limited access
- Marketing: Read-only for most features
- Name:
Click Generate
Access Levels
- Admin: Full access to all features (recommended)
- App Manager: Can manage apps, TestFlight, and submissions
- Developer: Can't submit apps to review or manage testers
- Choose Admin or App Manager for MobileCtl
Step 3: Download API Key
3.1 Download the Key
After creating the key, you'll see key details:
- Issuer ID: Your team identifier (e.g.,
12345678-abcd-1234-abcd-123456789012) - Key ID: The key identifier (e.g.,
ABC123DEF) - Download API Key button
Download Only Once!
You can only download the API key once. If you lose it, you must revoke and create a new one.
- Click Download API Key
- Save the file (e.g.,
AuthKey_ABC123DEF.p8)
3.2 Copy Key Information
You'll need three pieces of information:
- Issuer ID: Found at the top of the Keys page
- Key ID: Shows next to your key name (e.g.,
ABC123DEF) - Key File: The downloaded
.p8file
Save This Information
Write down or screenshot:
- Issuer ID:
12345678-abcd-1234-abcd-123456789012 - Key ID:
ABC123DEF - Key File:
AuthKey_ABC123DEF.p8
You'll need all three for MobileCtl configuration.
Step 4: Create JSON Configuration
MobileCtl expects a JSON file with your API key information.
4.1 Create JSON File
Create a file named app-store-connect-api-key.json:
{
"key_id": "ABC123DEF",
"issuer_id": "12345678-abcd-1234-abcd-123456789012",
"key": "-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY_HERE\n-----END PRIVATE KEY-----",
"key_filepath": "AuthKey_ABC123DEF.p8"
}4.2 Add Private Key Content
You need to add the content of the .p8 file to the JSON:
Option 1: Copy content directly
# View the key content
cat AuthKey_ABC123DEF.p8
# Copy the entire output including:
# -----BEGIN PRIVATE KEY-----
# ... key content ...
# -----END PRIVATE KEY-----Paste it into the key field with \n for line breaks:
{
"key_id": "ABC123DEF",
"issuer_id": "12345678-abcd-1234-abcd-123456789012",
"key": "-----BEGIN PRIVATE KEY-----\nMIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg...\n-----END PRIVATE KEY-----"
}Option 2: Reference file path
{
"key_id": "ABC123DEF",
"issuer_id": "12345678-abcd-1234-abcd-123456789012",
"key_filepath": "credentials/AuthKey_ABC123DEF.p8"
}4.3 Store Files Securely
# Create credentials directory
mkdir -p credentials
# Move files
mv ~/Downloads/AuthKey_ABC123DEF.p8 credentials/
mv app-store-connect-api-key.json credentials/
# Set secure permissions
chmod 600 credentials/AuthKey_ABC123DEF.p8
chmod 600 credentials/app-store-connect-api-key.jsonStep 5: Find Your Team ID and Bundle ID
5.1 Get Team ID
- Go to App Store Connect
- Click your name → View Membership
- Your Team ID is shown (10-character alphanumeric, e.g.,
ABC123DEF)
Or from Apple Developer:
- Go to Apple Developer
- Click Membership
- Team ID is displayed
5.2 Get Bundle ID
- In App Store Connect, select your app
- Go to App Information
- Bundle ID is shown (e.g.,
com.example.myapp)
Or:
- In Xcode, open your project
- Select your app target
- Go to General tab
- Bundle Identifier is shown
Step 6: Configure MobileCtl
6.1 Update mobileops.yaml
Add the iOS deployment configuration:
deploy:
ios:
testflight:
enabled: true
api_key_path: credentials/app-store-connect-api-key.json
bundle_id: com.example.myapp
team_id: ABC123DEF # Your Team ID (NOT the numeric Issuer ID)
app_store:
enabled: false # Enable when ready for App Store submission
api_key_path: credentials/app-store-connect-api-key.json
bundle_id: com.example.myapp
team_id: ABC123DEFTeam ID vs Issuer ID
- Team ID: 10-character code (e.g.,
ABC123DEF) - use this inmobileops.yaml - Issuer ID: UUID format (e.g.,
12345678-abcd-...) - use this in API key JSON - They are different! Don't confuse them.
6.2 Test Configuration
# Build your iOS app
mobilectl build ios
# Upload to TestFlight
mobilectl deploy --platform ios --destination testflightStep 7: Verify Setup
7.1 Check File Structure
credentials/
├── app-store-connect-api-key.json
└── AuthKey_ABC123DEF.p87.2 Verify JSON Format
# Check JSON is valid
cat credentials/app-store-connect-api-key.json | jq .
# Should show:
{
"key_id": "ABC123DEF",
"issuer_id": "12345678-abcd-...",
"key_filepath": "credentials/AuthKey_ABC123DEF.p8"
}7.3 Test Upload
# Dry run
mobilectl deploy --platform ios --destination testflight --dry-run
# Actual upload
mobilectl deploy --platform ios --destination testflightCheck App Store Connect → TestFlight to see your build!
Troubleshooting
Error: "Invalid API key"
Solution:
- Verify Key ID matches the downloaded file
- Check Issuer ID is correct (from Keys page)
- Ensure the
.p8file content is correctly formatted - Re-download the key if corrupted
Error: "Not authorized"
Solution:
- Verify the API key has Admin or App Manager access
- Check that the key hasn't been revoked
- Wait a few minutes for permissions to propagate
- Ensure your Apple Developer Program membership is active
Error: "Bundle ID mismatch"
Solution:
- Verify Bundle ID in
mobileops.yamlmatches App Store Connect - Check Xcode project Bundle Identifier
- Ensure the app is registered in App Store Connect
- Verify provisioning profile matches Bundle ID
Error: "Team ID not found"
Solution:
- Use the 10-character Team ID (not Issuer ID)
- Find it in App Store Connect → View Membership
- Or Apple Developer → Membership
- Format:
ABC123DEF(10 chars, NOT UUID format)
Error: "File not found" for .p8 file
Solution:
- Check
key_filepathpath is correct - Use relative path from project root
- Verify file exists:
ls -l credentials/AuthKey_*.p8 - Check file permissions:
chmod 600 credentials/AuthKey_*.p8
Can't create API key - "Request Access" button missing
Solution:
- Ensure you have Admin or Account Holder role
- Verify your Apple Developer Program membership is active
- Check if your organization already has API access enabled
- Contact your Account Holder to grant access
Security Best Practices
1. Never Commit Keys to Version Control
Add to .gitignore:
# .gitignore
credentials/
*.p8
**/AuthKey_*.p82. Restrict Key Permissions
Use least privilege:
✓ App Manager: For TestFlight and app management
✗ Admin: Only if you need full access
✗ Developer: Can't upload to TestFlight3. Rotate Keys Annually
# Every year or when compromised:
# 1. Revoke old key in App Store Connect
# 2. Generate new key
# 3. Update mobileops.yaml
# 4. Test deployment
# 5. Update CI/CD secrets4. Secure Storage
# Set restrictive permissions
chmod 600 credentials/app-store-connect-api-key.json
chmod 600 credentials/AuthKey_*.p8
# Verify
ls -l credentials/
# Should show: -rw------- (owner read/write only)5. Monitor Key Usage
Check activity regularly:
- App Store Connect → Users and Access → Keys
- View when keys were last used
- Review for suspicious activity
- Revoke unused keys
CI/CD Integration
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy to TestFlight
on:
push:
tags:
- 'v*'
jobs:
deploy:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Set up Xcode
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: 'latest-stable'
- name: Build IPA
run: mobilectl build ios
- name: Deploy to TestFlight
env:
APP_STORE_CONNECT_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY }}
APP_STORE_CONNECT_P8: ${{ secrets.APP_STORE_CONNECT_P8_KEY }}
run: |
echo "$APP_STORE_CONNECT_KEY" > /tmp/asc-api-key.json
echo "$APP_STORE_CONNECT_P8" > /tmp/AuthKey.p8
mobilectl deploy --platform ios --destination testflight -yAdd secrets in GitHub:
- Settings → Secrets → New repository secret
APP_STORE_CONNECT_API_KEY: Paste JSON contentAPP_STORE_CONNECT_P8_KEY: Paste.p8file content
GitLab CI
# .gitlab-ci.yml
deploy_testflight:
stage: deploy
tags:
- macos
script:
- echo "$APP_STORE_CONNECT_KEY" > /tmp/asc-api-key.json
- echo "$APP_STORE_CONNECT_P8" > /tmp/AuthKey.p8
- mobilectl deploy --platform ios --destination testflight -y
only:
- tagsMultiple Apps
Same Team, Different Apps
Use one API key for all apps in your team:
deploy:
ios:
# App 1
app1:
api_key_path: credentials/app-store-connect-api-key.json
bundle_id: com.example.app1
team_id: ABC123DEF
# App 2
app2:
api_key_path: credentials/app-store-connect-api-key.json
bundle_id: com.example.app2
team_id: ABC123DEFDifferent Teams
Use separate API keys for different teams:
deploy:
ios:
# Personal team
personal:
api_key_path: credentials/asc-personal.json
team_id: ABC123DEF
# Company team
company:
api_key_path: credentials/asc-company.json
team_id: XYZ789GHIRelated Documentation
- Deploy Command - Using TestFlight deployment
- Setup Wizard - Automated credential configuration
- Google Play Service Account - For Android
- Firebase Service Account - For Firebase
- CI/CD Integration - Automating deployments
- Configuration Reference - All deployment options
Useful Links
Quick Reference
TL;DR:
- App Store Connect → Users and Access → Keys → Generate API Key
- Download
.p8file (only chance!) - Note Issuer ID, Key ID, and Team ID
- Create JSON with key info
- Add to
mobileops.yaml:api_key_path: credentials/asc-api-key.json - Test:
mobilectl deploy --platform ios --destination testflight