Signing Unity Apps for Mac App Store Distribution

Mac App Distribution and Signing Fundamentals

Notarization Rules

  • Apps distributed via the Mac App Store do not require separate notarization, as Apple performs equivalent security checks during the review process.
  • Applications distributed outside the Mac App Store must be notarized. Without this, macOS will display warnings stating the app "may harm your computer."

Code Signing Requirements

  1. Mandatory Signing: All Mac applications must be code-signed. If you build an .app file using Unity, you must manually sign the code.

  2. Identifying Executables: Use the file command to determine if a binary is the main executable. A main executable is identified by Mach-O … executable.

    $ file /Applications/MyGame.app/Contents/PlugIns/AudioKit.bundle/Contents/MacOS/AudioKit
    /Applications/MyGame.app/Contents/PlugIns/AudioKit.bundle/Contents/MacOS/AudioKit: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit bundle x86_64] [arm64]
    # Output indicates AudioKit is a bundle, not the main executable.
    
  3. Signing Order: Sign dependencies before the components that rely on them (inside-out). For example, for a suite containing ConfigTool.app, Core.framework, Share.appex, and BackgroundDaemon:

    • Sign Core.framework first.
    • Sign Share.appex.
    • Sign ConfigTool.app.
    • BackgroundDaemon can be signed independently at any time.
  4. Entitlements: These files (.entitlements) define the permissions granted to the process at runtime.

  5. Provisioning Profile: Embed the Distribution Provisioning Profile inside the app bundle at XXX.app/Contents/ and rename it to embedded.provisionprofile.

Verification

Verify the signature details using codesign:

% codesign -d -vv /Applications/MyGame.app/Contents/PlugIns/unitypurchasing.bundle
Executable=/Applications/MyGame.app/Contents/PlugIns/unitypurchasing.bundle/Contents/MacOS/unitypurchasing
Identifier=com.unity.purchasing.unitypurchasing
Format=bundle with Mach-O universal (x86_64 arm64)
...

Signing Specific Components

Use the following syntax to sign individual binaries:

% codesign -s <Identity> <FilePath>

Example workflow:

# Signing native libraries (Do not use --entitlements here)
% codesign -f -s '3rd Party Mac Developer Application: Company Name' "/Builds/MyGame.app/Contents/Frameworks/UnityPlayer.dylib"

# Signing the main application with entitlements
% codesign -f -o runtime -s '3rd Party Mac Developer Application: Company Name' \
  --entitlements "/Builds/Game.entitlements" "/Builds/MyGame.app"

Critical Notes:

  • No Entitlements on Libraries: Do not apply .entitlements to libraries (.dylib or .bundle) as it will cause the app to crash on launch.
  • No Sudo: Do not run codesign with sudo. It relies on user-specific keychain access.
  • Avoid --deep: This flag applies the same entitlements to all nested code. If your app has helper tools requiring different permissions, --deep will break the signature.

Distribution Formats

Depending on the distribution method, choose the appropriate format:

  1. Mac App Store: Submit via Xcode or Transporter (usually .pkg or direct .app).
  2. Out side Mac App Store:
    • Zip Archive: Ensure the app is signed before zipping.
    • DMG: Standard disk image.
    • Installer Package (.pkg):
      • App Store distribution: Sign with 3rd Party Mac Developer Installer: <TeamID>.
      • Outside App Store: Sign with Developer ID Installer: <TeamID>.

Implementation Steps

If uploading directly via Xcode, manual signing is handled automatically.

1. Configure Info.plist

Modify the Info.plist inside the Unity-generated .app bundle:

  • Disable Encryption Export Prompt:
    <key>ITSAppUsesNonExemptEncryption</key>
    <false/>
    
  • Verify Package Type: Ensure it is set to APPL for applications.
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    
  • Set Category:
    <key>LSApplicationCategoryType</key>
    <string>public.app-category.games</string>
    
  • Minimum OS Version:
    <key>LSMinimumSystemVersion</key>
    <string>13.0.0</string>
    

2. Prepare Entitlements File

Generate an .entitlements file (you can use a dummy Xcode project to generate the template by enabling App Sandbox).

Add your Team ID and App ID:

<key>com.apple.developer.team-identifier</key>
<string>TEAMID12345</string>
<key>com.apple.application-identifier</key>
<string>TEAMID12345.com.mycompany.mygame</string>

Verification: Confirm sandboxing is enabled via command line:

% codesign -dvvv --entitlements - /Applications/MyGame.app

3. Embed Provisioning Profile

Place your embedded.provisionprofile file inside MyGame.app/Contents/.

4. Execution Scripts

Run the following commands in sequence:

# 1. Sign Plugins (Bundles)
$ codesign -f -s '3rd Party Mac Developer Application: Company' "MyGame.app/Contents/PlugIns/unitypurchasing.bundle"

# 2. Sign Frameworks (Libraries)
$ codesign -f -s '3rd Party Mac Developer Application: Company' "MyGame.app/Contents/Frameworks/libmonobdwgc-2.0.dylib"

# 3. Sign Main App
$ codesign -f -s '3rd Party Mac Developer Application: Company' \
  --entitlements "/Builds/Game.entitlements" "/Builds/MyGame.app"

# 4. Build and Sign Installer Package for App Store
$ productbuild --component /Builds/MyGame.app /Applications \
  --sign "3rd Party Mac Developer Installer: Company" /Builds/MyGame.pkg

Troubleshooting

Error 90869: Invalid bundle (Missing x86_64)

  • Cause: The app supports arm64 only, but the deployment target is set below 12.0.
  • Fix: Update LSMinimumSystemVersion in Info.plist to 12.0 or higher (e.g., 13.0).

Error 90236: Misssing required icon

  • Cause: The App Icon (icns) is missing or invalid.
  • Fix: Ensure the Contents/Resources folder contains a valid AppIcon.icns with 512x512 and 512x512@2x sizes.

Error ITMS-90889: Missing provisioning profile

  • Cause: The .app bundle does not contain the embedded.provisionprofile.
  • Fix:
    1. Ensure com.apple.developer.team-identifier is in the .entitlements file.
    2. Copy the provisioning profile to MyGame.app/Contents/embedded.provisionprofile.

Tags: unity macOS Code Signing App Store macOS Development

Posted on Tue, 13 Oct 2026 16:50:26 +0000 by danc81