Code signing is the cryptographic step that proves a binary came from a specific Apple Developer team and has not been modified since signing. Every app shipped on iOS, iPadOS, macOS, tvOS, watchOS, and visionOS must be signed, and the operating system verifies the signature before it launches the binary. Skipping or breaking the signature is the single biggest cause of release-day surprises in Apple development.
macOS and OS X code signing are the same thing
Apple renamed OS X to macOS in 2016, but the signing machinery kept its names: the same codesign tool, the same certificate types, the same _CodeSignature layout. Older write-ups spell it OSX code signing or OS X code signing, and all of it still applies to current macOS unchanged. Where macOS genuinely differs from iOS is what happens after signing: Mac apps distributed outside the App Store also need notarization to satisfy Gatekeeper, which has no iOS equivalent.
What actually gets signed
- The Mach-O binary inside the .app bundle.
- Frameworks, app extensions, and other nested bundles, each signed independently.
- The bundle's resources (Info.plist, asset catalogs, localized strings) via a
_CodeSignature/CodeResourcesmanifest. - Entitlements, embedded inside the signature blob.
What it takes to sign a build
- A valid code signing certificate (Apple Development, Apple Distribution, Developer ID, etc.).
- The matching private key in a keychain or PKCS#12 bundle.
- A provisioning profile that authorizes that certificate for the App ID and entitlements you are using.
- A correctly-configured Xcode project: DEVELOPMENT_TEAM, CODE_SIGN_IDENTITY, and PROVISIONING_PROFILE_SPECIFIER set to values the signing material satisfies.
How verification happens
On every launch, the OS uses the public key inside the certificate to verify the signature, walks the chain through the WWDR intermediate to the Apple Root CA, checks the embedded provisioning profile is valid and matches the binary, and confirms the entitlements claimed at launch are a subset of what the profile granted. A failure at any step is what produces 'unable to verify your provisioning profile' and similar runtime errors.