JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 25
  • Score
    100M100P100Q49432F
  • License MIT

A command-line interface (CLI) to interact with the Apple App Store Connect API.

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (appstore-cli) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    AppStoreServices CLI

    A command-line interface (CLI) to interact with the Apple App Store Connect API. The tool provides commands for managing apps, builds, TestFlight beta testing, and downloading reports.

    Installation

    1. Clone the repository:

      git clone https://github.com/your-username/appstore-cli.git
      cd appstore-cli
    2. Install the dependencies:

      npm install
    3. Build the project:

      npm run build
    4. Link the CLI to make it accessible globally:

      npm link

    Configuration

    To interact with the App Store Connect API, you must provide your API credentials. This tool provides two secure methods for storing your credentials:

    Method 1: OS Keychain Storage (Default)

    The CLI securely stores your private key in your operating system's keychain:

    • macOS: Uses Keychain Access
    • Windows: Uses Credential Vault
    • Linux: Uses libsecret

    Method 2: Environment Variables

    You can provide your credentials through environment variables, which is useful for CI/CD pipelines and containerized deployments:

    export APPSTORE_KEY_ID="YOUR_KEY_ID"
    export APPSTORE_ISSUER_ID="YOUR_ISSUER_ID"
    export APPSTORE_PRIVATE_KEY="YOUR_PRIVATE_KEY_CONTENT"

    Or in a single command:

    APPSTORE_KEY_ID="YOUR_KEY_ID" APPSTORE_ISSUER_ID="YOUR_ISSUER_ID" APPSTORE_PRIVATE_KEY="YOUR_PRIVATE_KEY_CONTENT" appstore-cli apps list

    Setting Up Your Credentials

    Before you can use the CLI, you need to set up your App Store Connect API key. You have several options for configuring your credentials:

    The easiest way to set up your credentials is using the provided helper script. You can provide your private key in two ways:

    Option A: Provide a path to your private key file

    node setup-config.js --keyId <your-key-id> --issuerId <your-issuer-id> --privateKeyPath <path-to-your-private-key-file>

    Example:

    node setup-config.js --keyId LS76K9LCHB --issuerId 69a6de8b-0aac-47e3-e053-5b8c7c11a4d1 --privateKeyPath ./AuthKey_LS76K9LCHB.p8

    You can also use the short form:

    node setup-config.js -k LS76K9LCHB -i 69a6de8b-0aac-47e3-e053-5b8c7c11a4d1 -p ./AuthKey_LS76K9LCHB.p8

    Option B: Provide the private key content directly

    node setup-config.js --keyId <your-key-id> --issuerId <your-issuer-id> --privateKey <your-private-key-content>

    Example:

    node setup-config.js -k LS76K9LCHB -i 69a6de8b-0aac-47e3-e053-5b8c7c11a4d1 -P "-----BEGIN PRIVATE KEY-----
    MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAK...
    -----END PRIVATE KEY-----"

    Method 2: Using the CLI Directly

    You can also configure your credentials using the CLI directly:

    Providing Private Key Content Directly:

    appstore-cli config set --keyId <your-key-id> --issuerId <your-issuer-id> --privateKey '-----BEGIN PRIVATE KEY-----
    [paste your private key content here]
    -----END PRIVATE KEY-----'

    Providing a Path to Your Private Key File:

    appstore-cli config set --keyId <your-key-id> --issuerId <your-issuer-id> --privateKeyPath <path-to-your-private-key-file>

    Example:

    appstore-cli config set --keyId LS76K9LCHB --issuerId 69a6de8b-0aac-47e3-e053-5b8c7c11a4d1 --privateKeyPath ./AuthKey_LS76K9LCHB.p8

    Providing a Fastlane Token:

    appstore-cli config set --fastlane-token <your-fastlane-token>

    Providing a Username:

    appstore-cli config set --username <your-apple-id>

    Authentication Flow Consolidation

    As of version 1.0.8, the CLI has consolidated authentication flows. The separate build auth command has been removed in favor of the unified configuration approach. All authentication should now be configured using the appstore-cli config set command:

    # For API key authentication:
    appstore-cli config set --keyId <key-id> --issuerId <issuer-id> --privateKey <private-key>
    
    # For Fastlane token authentication:
    appstore-cli config set --fastlane-token <token>
    
    # For username:
    appstore-cli config set --username <username>

    Precedence Order

    The CLI uses credentials in the following precedence order:

    1. Environment variables (if set)
    2. Securely stored configuration (keychain/file encryption)

    How Authentication Works

    The CLI exclusively uses a JSON Web Token (JWT) for all interactions with the App Store Connect API. When you first configure the tool with your API Key, Issuer ID, and Private Key, it securely stores these credentials.

    For security, your private key is stored in the OS keychain or encrypted on the file system (depending on your platform). The configuration file (~/.appstore-cli/config.json) only contains non-sensitive information (key ID and issuer ID).

    For each command, the CLI automatically generates a short-lived JWT using the ES256 algorithm, which is used to authenticate with the API. The private key is retrieved from secure storage and converted to a proper cryptographic key object using Node.js's crypto.createPrivateKey() to ensure compatibility with the JWT library.

    This JWT-based approach provides a secure and consistent authentication flow, as your private key is never sent over the network, and access tokens are valid for a limited time (20 minutes).

    Viewing Your Configuration

    To view your current configuration (excluding the private key for security reasons), run:

    appstore-cli config get

    Note that your private key is stored securely and is not displayed by this command.

    Usage

    Apps

    • List all apps:

      appstore-cli apps list
    • Get app details:

      appstore-cli apps get <app-id>
    • Create a new app:

      appstore-cli apps create-app --name <name> --bundle-id <bundle-id> --sku <sku> --primary-locale <locale> --version-string <version>

    Builds

    • List all builds for an app:

      appstore-cli builds list --app-id <app-id>
    • Get build details:

      appstore-cli builds get <build-id>
    • Upload a new build:

      appstore-cli builds upload --app-id <app-id> --path <path-to-ipa>
    • Upload a new build with credentials:

      appstore-cli builds upload --app-id <app-id> --path <path-to-ipa> --provisioning-profile <path-to-profile> --certificate-path <path-to-cert> --certificate-password <password>
    • Upload a new build and submit to App Store:

      appstore-cli builds upload --app-id <app-id> --path <path-to-ipa> --submit-to-app-store
    • Upload a new build with Fastlane token:

      appstore-cli builds upload --app-id <app-id> --path <path-to-ipa> --fastlane-token <token>
    • Submit a build for App Store review:

      appstore-cli builds submit-build --build-id <build-id> --app-id <app-id>
    • Submit a build for App Store review with credentials:

      appstore-cli builds submit-build --build-id <build-id> --app-id <app-id> --provisioning-profile <path-to-profile> --certificate-path <path-to-cert> --fastlane-token <token>

    Build Phase Commands

    • Configure build settings:

      appstore-cli build configure --scheme <scheme> --workspace <workspace-path> --configuration <config>

      or

      appstore-cli build configure --scheme <scheme> --project <project-path> --configuration <config>
    • Configure build settings with custom variables:

      appstore-cli build configure --scheme <scheme> --workspace <workspace-path> --configuration <config> --variable KEY1=VALUE1 --variable KEY2=VALUE2
    • Set authentication for build process:

      appstore-cli config set --keyId <key-id> --issuerId <issuer-id>

      or

      appstore-cli config set --fastlaneToken <token>
    • Configure export settings:

      appstore-cli build export configure --method <method> --team-id <team-id>
    • Run the build process:

      appstore-cli build run
    • Export IPA after building:

      appstore-cli build export run --archive-path <archive-path>

    Common Build Workflows

    Debug Build for Testing

    appstore-cli build configure --scheme "MyApp" --workspace "./MyApp.xcworkspace" --configuration "Debug" --variable API_URL=https://api.dev.example.com --variable DEBUG=true
    appstore-cli build run

    App Store Release

    appstore-cli build configure --scheme "MyApp" --workspace "./MyApp.xcworkspace" --configuration "Release"
    appstore-cli config set --keyId "YOUR_KEY_ID" --issuerId "YOUR_ISSUER_ID"
    appstore-cli build export configure --method "app-store" --team-id "YOUR_TEAM_ID"
    appstore-cli build run
    appstore-cli build export run --archive-path "./build/MyApp.xcarchive"

    Ad Hoc Distribution

    appstore-cli build configure --scheme "MyApp" --workspace "./MyApp.xcworkspace" --configuration "Release"
    appstore-cli config set --fastlaneToken "YOUR_FASTLANE_TOKEN"
    appstore-cli build export configure --method "ad-hoc" --team-id "YOUR_TEAM_ID" --provisioning-profiles "com.example.app:PROFILE_UUID"
    appstore-cli build run
    appstore-cli build export run --archive-path "./build/MyApp.xcarchive" --output-path "./build/MyApp.ipa"

    Custom Build Variables

    The AppStoreServices CLI supports custom build variables that allow you to pass environment-specific configuration to your builds. This feature is useful for:

    • Configuring different API endpoints for development, staging, and production environments
    • Enabling or disabling features with feature flags
    • Setting build-specific metadata
    • Customizing builds for different customers or brands

    To use custom variables, add the --variable option to the build configure command:

    appstore-cli build configure --scheme "MyApp" --workspace "./MyApp.xcworkspace" --configuration "Debug" --variable API_URL=https://api.example.com --variable DEBUG=true

    You can specify multiple variables by using the --variable option multiple times. Variables should be in KEY=VALUE format. Values containing spaces should be quoted:

    appstore-cli build configure --scheme "MyApp" --workspace "./MyApp.xcworkspace" --configuration "Debug" --variable "APP_NAME=My App" --variable API_URL=https://api.example.com

    The custom variables will be made available during the build process and can be accessed in your build scripts and application code.

    Beta Testers

    • List all beta testers:

      appstore-cli testers list
    • Add a new beta tester:

      appstore-cli testers add --email <email> --firstName <first> --lastName <last>
    • Remove a beta tester:

      appstore-cli testers remove <tester-id>

    Beta Groups

    • List all beta groups:

      appstore-cli groups list
    • Add a tester to a group:

      appstore-cli groups add-tester --group-id <group-id> --tester-id <tester-id>
    • Create a new beta group:

      appstore-cli groups create-beta-group --name <name> --app-id <app-id> [--is-internal]

    Reports

    • Download sales and trends reports:

      appstore-cli reports download-sales --vendor <vendor> --report-type <type> --frequency <freq> --report-date <date>
    • Download financial reports:

      appstore-cli reports download-financial --vendor <vendor> --region-code <code> --report-date <date>

    Credential Management

    The AppStoreServices CLI provides comprehensive support for managing iOS app signing credentials, including provisioning profiles, signing certificates, certificate passwords, and Fastlane authentication tokens.

    Provisioning Profiles

    Provisioning profiles (.mobileprovision files) authorize your app's installation and distribution. They are tied to your app's Bundle ID, your signing certificate, and include entitlements like push notifications.

    • Using a provisioning profile with build upload:

      appstore-cli builds upload --app-id <app-id> --path <path-to-ipa> --provisioning-profile <path-to-profile.mobileprovision>
    • Using a provisioning profile with build submission:

      appstore-cli builds submit-build --build-id <build-id> --app-id <app-id> --provisioning-profile <path-to-profile.mobileprovision>

    Signing Certificates

    Signing certificates (.p12, .cer files) digitally sign your app so devices and the App Store recognize it as coming from a trusted developer.

    • Using a signing certificate with build upload:

      appstore-cli builds upload --app-id <app-id> --path <path-to-ipa> --certificate-path <path-to-cert.p12> --certificate-password <password>
    • Using a signing certificate with build submission:

      appstore-cli builds submit-build --build-id <build-id> --app-id <app-id> --certificate-path <path-to-cert.p12> --certificate-password <password>

    Fastlane Auth Tokens

    Fastlane auth tokens (spaceauth sessions) provide temporary Apple account access for Fastlane-based signing and provisioning tasks.

    • Using a Fastlane token with build upload:

      appstore-cli builds upload --app-id <app-id> --path <path-to-ipa> --fastlane-token <your-fastlane-token>
    • Using a Fastlane token with build submission:

      appstore-cli builds submit-build --build-id <build-id> --app-id <app-id> --fastlane-token <your-fastlane-token>
    • Using environment variables for Fastlane tokens:

      export FASTLANE_TOKEN="your-fastlane-token"
      appstore-cli builds upload --app-id <app-id> --path <path-to-ipa>

    Credential Validation

    The CLI automatically validates all provided credentials:

    • File existence and readability
    • Correct file extensions (.mobileprovision, .p12, .cer)
    • Provisioning profile content and expiration
    • Certificate format
    • Fastlane token format

    If any credential fails validation, the CLI provides detailed error messages and troubleshooting tips.

    Security

    All credentials are handled securely:

    • Sensitive data is stored in encrypted memory only during processing
    • Passwords and tokens are never logged or displayed in output
    • Credentials are automatically cleaned up after use
    • File permissions are checked to ensure secure access

    Security

    The AppStoreServices CLI has been enhanced with robust security features:

    Private Key Security

    • Private keys are securely stored using OS keychain (keytar) when available
    • Falls back to AES-256-CBC encryption with machine-specific keys when keytar is not available
    • No private keys are logged or exposed in error messages
    • Secure functions for storing, retrieving, and deleting private keys

    JWT Token Security

    • Configuration validation prevents invalid token generation
    • Sanitized error messages prevent information disclosure
    • Payload validation ensures proper token structure
    • Expiration time validation prevents overly long-lived tokens (20 minutes)
    • No tokens are logged or exposed in any way

    For detailed information about security features and best practices, see SECURITY.md.

    Troubleshooting

    Common Issues

    "secretOrPrivateKey must have a value" Error

    This error occurs when the private key is not properly configured. Solutions:

    1. Use the helper script (recommended):

      # Option A: Provide a path to your private key file
      node setup-config.js --keyId <key-id> --issuerId <issuer-id> --privateKeyPath <path-to-p8-file>
      
      # Option B: Provide the private key content directly
      node setup-config.js --keyId <key-id> --issuerId <issuer-id> --privateKey <your-private-key-content>
    2. Use the CLI with a file path:

      appstore-cli config set --keyId <key-id> --issuerId <issuer-id> --privateKeyPath <path-to-p8-file>
    3. Check your private key format: Ensure your private key contains a valid ECDSA private key in PEM format starting with -----BEGIN PRIVATE KEY-----

    4. Avoid shell escaping issues: Don't paste multiline private keys directly in double quotes. Use single quotes or the helper script instead.

    5. Provide exactly one private key option: When using the CLI, you must provide exactly one of --privateKey or --privateKeyPath, not both.

    "Invalid private key format" Error

    This indicates the private key cannot be parsed as a valid ECDSA key:

    1. Verify your .p8 file is a valid App Store Connect API private key
    2. Check file encoding - ensure the file is UTF-8 encoded
    3. Re-download the key from App Store Connect if necessary

    401 Authentication Error

    If you get a 401 error after successful JWT generation:

    1. Verify your Key ID and Issuer ID are correct
    2. Check key permissions in App Store Connect - ensure the key has the required scopes
    3. Confirm the key is active and not expired in App Store Connect

    Credential Validation Errors

    When using provisioning profiles, certificates, or Fastlane tokens, you may encounter validation errors:

    1. Provisioning Profile Issues:

      • Ensure the file has a .mobileprovision extension
      • Verify the profile hasn't expired
      • Check that the profile matches your app's bundle identifier
      • Confirm the profile includes the correct devices (for development profiles)
    2. Certificate Issues:

      • Ensure the file has a .p12 or .cer extension
      • Verify the certificate hasn't expired
      • For .p12 files, ensure you're providing the correct password
      • Make sure the certificate matches your provisioning profile
    3. Fastlane Token Issues:

      • Generate a new Fastlane session token using 'fastlane spaceauth'
      • Ensure the token hasn't expired (tokens typically expire after a few hours)
      • Check that you haven't accidentally included extra characters or whitespace

    Development Mode

    For development, you can run commands directly without building:

    # Run in development mode
    ts-node src/appstore-cli.ts <command>
    
    # Example
    ts-node src/appstore-cli.ts apps list

    Testing

    Run the test suite:

    npm test

    Building

    Build the TypeScript source:

    npm run build

    Project Status

    The AppStoreServices CLI has successfully achieved all of its core goals and now supports the complete automated workflow for iOS app management in App Store Connect:

    1. Create app in App Store Connect - Using create-app command
    2. Upload IPA file - Using builds upload command
    3. Create internal test group - Using create-beta-group command
    4. Add user to internal test group - Using testers add and groups add-tester commands
    5. Push build to App Store - Using submit-build command or builds upload --submit-to-app-store
    6. Credential Management - Comprehensive support for provisioning profiles, signing certificates, and Fastlane tokens

    The implementation is robust, secure, and well-tested. For information about ongoing improvements and next steps, see the task tracking files in the .tasks directory.