macOS Notarization

VerifiedCaution

Archive, export, and notarize macOS apps for distribution outside the App Store with Developer ID signing and Apple notarization.

Sby Skills Guide Bot
DevOpsAdvanced
7/28/2026
Claude CodeCursorCodex
#macos#notarization#code-signing#xcodebuild#app-distribution

Recommended for

Automated summary

Automates archiving, Developer ID export, and Apple notarization submission for a macOS app using xcodebuild and the asc CLI.

Strengths

  • Covers the whole release path: archive, Developer ID export, ditto ZIP, submission, status polling, and fetching the developer log on failure
  • Includes a useful preflight on signing identity and a fix for keychain trust-setting errors such as « Invalid trust settings » and errSecInternalComponent
  • Provides exact verification commands (authority chain, timestamp) plus fire-and-forget, --wait, and custom polling submission modes
  • States the real prerequisites: Xcode, asc authentication, and a Developer ID Application certificate already in the keychain

Limitations

  • Assumes the asc tool is installed and authenticated, and that an Apple Developer account and Developer ID certificate already exist
  • Scheme names, paths, and TEAM_ID are placeholders that must be edited by hand
  • Does not address edge cases like sandboxed apps with extensions, nested bundles, or .pkg installers
When to use it

When you need to ship a macOS app outside the Mac App Store and must produce a Developer ID-signed archive that Apple has notarized.

When not to use it

When you are targeting the Mac App Store, or when you need a full end-to-end CI release pipeline rather than a local notarization procedure.

Security analysis

Caution
Quality score80/100

The skill is a legitimate Apple code-signing/notarization workflow. It runs privileged-but-standard developer tooling (xcodebuild, codesign, ditto, hdiutil, stapler, the `asc` CLI) and network calls only to Apple endpoints or a notarization log URL. There is no credential exfiltration, no curl|sh, and no obfuscation, but it does alter keychain trust settings and force-resign bundles, so it warrants a caution rating rather than safe.

Findings
  • •`security remove-trusted-cert` modifies the user's keychain trust settings system-wide and is presented as a routine fix; a mistake here can break code signing for other apps on the machine.
  • •`codesign --deep --force` is applied to an arbitrary app path in the verification step, which re-signs/overwrites signatures rather than just verifying them.
  • •Instructions trust external log URLs and pipe the response into `curl -sL` and `python3 -m json.tool`; benign but involves network fetch of a user-supplied URL.
  • •Relies on `asc` CLI and `ASC_*` environment variables (auth credentials) without describing their scope or how to protect them.
How this analysis is made

Examples

Notarize a macOS app
Notarize my macOS app « Foobar » for distribution outside the App Store: archive it with xcodebuild, export with Developer ID, create the ZIP, and submit it with asc notarization, waiting for the result.
Fix signing failure
xcodebuild export fails with « Invalid trust settings » / errSecInternalComponent for my Developer ID Application certificate. Check the trust settings and certificate chain and fix it before re-exporting.
Inspect a failed submission
My notarization submission failed. Run asc notarization list to find the latest submission, fetch its developer log, and tell me what needs to change.

name: asc-notarization description: Archive, export, and notarize macOS apps using xcodebuild and asc. Use when you need to prepare a macOS app for distribution outside the App Store with Developer ID signing and Apple notarization.

macOS Notarization

Use this skill when you need to notarize a macOS app for distribution outside the App Store.

Preconditions

  • Xcode installed and command line tools configured.
  • Auth is configured (asc auth login or ASC_* env vars).
  • A Developer ID Application certificate in the local keychain.
  • The app's Xcode project builds for macOS.

Preflight: Verify Signing Identity

Before archiving, confirm a valid Developer ID Application identity exists:

security find-identity -v -p codesigning | grep "Developer ID Application"

If no identity is found, create one at https://developer.apple.com/account/resources/certificates/add (the App Store Connect API does not support creating Developer ID certificates).

Fix Broken Trust Settings

If codesign or xcodebuild fails with "Invalid trust settings" or "errSecInternalComponent", the certificate may have custom trust overrides that break the chain:

# Check for custom trust settings
security dump-trust-settings 2>&1 | grep -A1 "Developer ID"

# If overrides exist, export the cert and remove them
security find-certificate -c "Developer ID Application" -p ~/Library/Keychains/login.keychain-db > /tmp/devid-cert.pem
security remove-trusted-cert /tmp/devid-cert.pem

Verify Certificate Chain

After fixing trust settings, verify the chain is intact:

codesign --deep --force --options runtime --sign "Developer ID Application: YOUR NAME (TEAM_ID)" /path/to/any.app 2>&1

The signing must show the chain: Developer ID Application → Developer ID Certification Authority → Apple Root CA.

Step 1: Archive

xcodebuild archive \
  -scheme "YourMacScheme" \
  -configuration Release \
  -archivePath /tmp/YourApp.xcarchive \
  -destination "generic/platform=macOS"

Step 2: Export with Developer ID

Create an ExportOptions plist for Developer ID distribution:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>developer-id</string>
    <key>signingStyle</key>
    <string>automatic</string>
    <key>teamID</key>
    <string>YOUR_TEAM_ID</string>
</dict>
</plist>

Export the archive:

xcodebuild -exportArchive \
  -archivePath /tmp/YourApp.xcarchive \
  -exportPath /tmp/YourAppExport \
  -exportOptionsPlist ExportOptions.plist

This produces a .app bundle signed with Developer ID Application and a secure timestamp.

Verify the Export

codesign -dvvv "/tmp/YourAppExport/YourApp.app" 2>&1 | grep -E "Authority|Timestamp"

Confirm:

  • Authority chain starts with "Developer ID Application"
  • A Timestamp is present

Step 3: Create a ZIP for Notarization

ditto -c -k --keepParent "/tmp/YourAppExport/YourApp.app" "/tmp/YourAppExport/YourApp.zip"

Step 4: Submit for Notarization

Fire-and-forget

asc notarization submit --file "/tmp/YourAppExport/YourApp.zip"

Wait for result

asc notarization submit --file "/tmp/YourAppExport/YourApp.zip" --wait

Custom polling

asc notarization submit --file "/tmp/YourAppExport/YourApp.zip" --wait --poll-interval 30s --timeout 1h

Step 5: Check Results

Status

asc notarization status --id "SUBMISSION_ID" --output table

Developer Log (for failures)

asc notarization log --id "SUBMISSION_ID"

Fetch the log URL to see detailed issues:

curl -sL "LOG_URL" | python3 -m json.tool

List Previous Submissions

asc notarization list --output table
asc notarization list --limit 5 --output table

Step 6: Staple (Optional)

After notarization succeeds, staple the ticket so the app works offline:

xcrun stapler staple "/tmp/YourAppExport/YourApp.app"

For DMG or PKG distribution, staple after creating the container:

# Create DMG
hdiutil create -volname "YourApp" -srcfolder "/tmp/YourAppExport/YourApp.app" -ov -format UDZO "/tmp/YourApp.dmg"
xcrun stapler staple "/tmp/YourApp.dmg"

Supported File Formats

| Format | Use Case | |--------|----------| | .zip | Simplest; zip a signed .app bundle | | .dmg | Disk image for drag-and-drop install | | .pkg | Installer package (requires Developer ID Installer certificate) |

PKG Notarization

To notarize .pkg files, you need a Developer ID Installer certificate (separate from Developer ID Application). This certificate type is not available through the App Store Connect API — create it at https://developer.apple.com/account/resources/certificates/add.

Sign the package:

productsign --sign "Developer ID Installer: YOUR NAME (TEAM_ID)" unsigned.pkg signed.pkg

Then submit:

asc notarization submit --file signed.pkg --wait

Troubleshooting

"Invalid trust settings" during export

The Developer ID certificate has custom trust overrides. See the Preflight section above to remove them.

"The binary is not signed with a valid Developer ID certificate"

The app was signed with a Development or App Store certificate. Re-export with method: developer-id in ExportOptions.plist.

"The signature does not include a secure timestamp"

Add --timestamp to manual codesign calls, or use xcodebuild -exportArchive which adds timestamps automatically.

Upload timeout for large files

Set a longer upload timeout:

ASC_UPLOAD_TIMEOUT=5m asc notarization submit --file ./LargeApp.zip --wait

Notarization returns "Invalid" but signing looks correct

Fetch the developer log for specific issues:

asc notarization log --id "SUBMISSION_ID"

Common causes: unsigned nested binaries, missing hardened runtime, embedded libraries without timestamps.

Notes

  • The asc notarization commands use the Apple Notary API v2, not xcrun notarytool.
  • Authentication uses the same API key as other asc commands.
  • Files are uploaded directly to Apple's S3 bucket with streaming (no full-file buffering).
  • Files over 5 GB use multipart upload automatically.
  • Always use --help to verify flags: asc notarization submit --help.

From the file to a first result

The download contains exactly the content displayed on this page. This copy may differ from the latest version in the source repository.

View the source and supporting files

This download contains SKILL.md only. Any scripts, references, templates and dependencies are not included. Get the required files from the source, preserving their directory structure, before continuing.

1. Download the file

Download SKILL.md

From the root of a test project, save the file as .skill-downloads/macos-notarization-ms47vqju/SKILL.md, or use the command below. This folder is for inspecting the skill before installation.

Command for macOS/Linux or WSL: requires a POSIX shell and curl. On Windows without WSL, use the download button and create the folder manually.

mkdir -p '.skill-downloads/macos-notarization-ms47vqju' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/macos-notarization-ms47vqju/download' --output '.skill-downloads/macos-notarization-ms47vqju/SKILL.md.part' && mv '.skill-downloads/macos-notarization-ms47vqju/SKILL.md.part' '.skill-downloads/macos-notarization-ms47vqju/SKILL.md'

2. Check prerequisites

Read SKILL.md before using it. If it references scripts or external services, inspect them and prepare the required access in your test environment.

No recognized prerequisites section in this file. This does not mean it is self-contained: libraries, tools and access requirements may be mentioned elsewhere in the content or source repository.

The platforms on this page are catalog indications. The paths below follow tool documentation; they do not prove this skill has been run in those tools. No minimum tool version is confirmed for this listing.

3. Load the skill

After inspection, copy the complete folder into your project using one of the commands below, then open a new tool session. The command stops if a folder with the same name already exists: compare the files before replacing it.

Claude Code
test -f '.skill-downloads/macos-notarization-ms47vqju/SKILL.md' && test -s '.skill-downloads/macos-notarization-ms47vqju/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/asc-notarization' && cp -R '.skill-downloads/macos-notarization-ms47vqju' '.claude/skills/asc-notarization'

Cursor
test -f '.skill-downloads/macos-notarization-ms47vqju/SKILL.md' && test -s '.skill-downloads/macos-notarization-ms47vqju/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/asc-notarization' && cp -R '.skill-downloads/macos-notarization-ms47vqju' '.cursor/skills/asc-notarization'

Codex
test -f '.skill-downloads/macos-notarization-ms47vqju/SKILL.md' && test -s '.skill-downloads/macos-notarization-ms47vqju/SKILL.md' && mkdir -p '.agents/skills' && test ! -e '.agents/skills/asc-notarization' && cp -R '.skill-downloads/macos-notarization-ms47vqju' '.agents/skills/asc-notarization'

OpenSkills

OpenSkills must already be installed. The local install/read procedure is checked with OpenSkills 1.5.0, which requires Node.js ≥ 20.6.0. Catalog slugs are not resolved automatically.

Official OpenSkills installation
openskills install './.skill-downloads/macos-notarization-ms47vqju'

openskills read 'macos-notarization-ms47vqju'

Reading should display the installed file content and its base directory. It does not run the skill or install its dependencies.

For an agent that reads AGENTS.md, then sync the index. This command changes AGENTS.md: review the diff before using it.

openskills sync

Manual method or another tool: attach SKILL.md to a conversation, or open it in an agent that can read files. Include any required supporting resources. No universal folder is recognized by every tool.

4. Try a first task

Use a short, synthetic input: an API endpoint, a small document or an interface brief. In a new conversation, attach the file or give the agent its path, then adapt this request:

Read .skill-downloads/macos-notarization-ms47vqju/SKILL.md and apply its instructions to this example: [describe a test input]. Identify any missing files, dependencies or access. Produce the result requested by the skill without inventing data or running unreviewed scripts.

Expected result: output matching the skill instructions, or a precise list of missing prerequisites. A read confirmation alone does not validate a first use. If an external resource is unavailable, that path remains untested.

Related skills