macOS Code Signing: Complete Guide

macOS code signing is Apple's mechanism for digitally signing applications, executables, bundles, and other supported software so macOS can verify their integrity and associate them with a signing identity. The signing process uses a private key and an Apple-issued signing certificate, while macOS uses the resulting signature as part of its security and software-trust mechanisms.

Code signing is not notarization. Code signing establishes a cryptographic signature and signing identity. Notarization is a separate Apple service, while Gatekeeper evaluates downloaded software against macOS security policies.

codesignDeveloper IDKeychainEntitlementsNotarizationGatekeeper
Application SignatureSigned identity verified
Nested code checked
Distribution status evaluated
Signing IdentityCertificate + private key
codesignSign, inspect and verify code
GatekeeperSystem security assessment

What macOS Code Signing Actually Does

macOS code signing gives software a cryptographic signature that macOS and Apple tooling can inspect. The signature associates the code with a signing identity and allows the system to detect changes to signed code.

For a Mac application, signing is often more involved than signing one executable. An application bundle can contain frameworks, dynamic libraries, helper applications, plug-ins, and other executable components. Those components can have their own signatures and must be handled as part of the overall release workflow.

Code signing is one layer of Apple's software security model. It does not, by itself, mean that an application has been notarized, came from the Mac App Store, or is safe from vulnerabilities.

Code signing does not prove

  • The application is bug-free or malware-free.
  • The software has never been compromised.
  • Notarization has occurred.
  • The application came from the Mac App Store.
  • Gatekeeper will necessarily allow the application to run without further assessment.

macOS Code Signing at a Glance

The Apple signing ecosystem becomes easier to reason about when identity, signing, verification, notarization, and Gatekeeper are kept as separate stages.

1
Apple IdentityDeveloper identity and account context
2
CertificateApple-issued signing credential
3
Private KeySecret cryptographic material
4
codesignSigns application code
5
Signed AppBundle and nested code
6
VerifySignature and identity checks
7
NotarizeApple distribution security service
8
GatekeepermacOS security assessment

What Can Be Code-Signed on macOS?

macOS signing applies to multiple types of executable code. The application bundle is often the visible release artifact, but the bundle can contain several separately signed components.

Application

.app bundles

A Mac application commonly contains an executable, resources, frameworks, helpers, and other nested components.

Executable

Mach-O code

Executable code can be signed independently as part of development, packaging, or a larger application signing workflow.

Nested code

Frameworks & plug-ins

Frameworks, dynamic libraries, plug-ins, and helper applications may require their own appropriate signing treatment.

Distribution

Installer components

Application signing and installer or package signing are separate concerns and should not be treated as automatically interchangeable.

The important Apple concept is that a Mac application can be a hierarchy of code. A signing problem in a nested component can affect the verification or distribution workflow for the overall application.

How macOS Code Signing Works

The signing lifecycle begins with a finalized build and ends with verification and, where applicable, notarization and distribution assessment.

Step 01

Build software

Create the application bundle and its executable components. The artifact should be close to its final release state before signing.

Step 02

Select identity

The build environment accesses the appropriate certificate and corresponding private key through its signing identity.

Step 03

Sign code

codesign applies the signature to the relevant executable and bundle components according to the release workflow.

Step 04

Verify

Inspect the signature, identity, nested code, requirements, and entitlements as applicable.

Step 05

Notarize

For applicable outside-App-Store distribution, submit the release artifact through the appropriate notarization workflow.

Step 06

Validate

Staple or otherwise validate distribution evidence as required by the release process.

Step 07

Distribute

Publish the signed release through the intended distribution channel.

Step 08

macOS evaluates

Gatekeeper and other platform security mechanisms assess the application when users obtain and launch it.

What Is an Apple Code Signing Certificate?

An Apple signing certificate is part of the cryptographic identity used by Apple's development and distribution tooling. It should be distinguished from the developer account, private key, code signature, and notarization service.

Certificate + Private KeyThe certificate provides identity and public-key information. The private key performs the signing operation.
→
Signing IdentityThe available certificate and corresponding private key form the identity that Apple tooling can use for signing.

A signing identity is therefore not simply another name for an Apple Developer account. The account provides access to Apple's developer ecosystem, while the certificate and private key are the cryptographic material used by the signing process.

Signing Identity Explained

Apple tooling exposes signing identities because signing requires a usable relationship between a certificate and its corresponding private key.

CertificateIdentifies the signer and provides the public key used during signature verification.
Private KeySecret key material used to create the cryptographic signature.
KeychainmacOS credential storage where certificates and private keys can be managed.
codesignUses an available signing identity to sign, inspect, or verify code.
signature inspection
$ codesign -dvvv MyApp.app
Identifier=MyApp
Authority=Apple Development / Distribution identity
TeamIdentifier=...
Signature information available

The exact identity displayed depends on the certificates installed and the build environment. In CI/CD, this makes keychain preparation and access control part of the signing architecture rather than an afterthought.

The codesign Tool

codesign is Apple's command-line utility for signing code and inspecting or verifying signatures. It is central to both local release workflows and automated macOS build systems.

OperationExamplePurpose
Signcodesign --sign ...Apply a code signature using an available signing identity.
Verifycodesign --verify ...Check whether code's signature and integrity can be verified.
Displaycodesign --display ...Inspect signature, identifier, authority, requirements, and related information.
Nested codeSigning workflow dependentHandle frameworks, helpers, plug-ins, and other code inside the application bundle.

This page uses codesign to explain the signing model, not as a complete command reference. A dedicated Apple codesign Guide can cover flags, identities, requirements, entitlements, and advanced inspection in greater depth.

How to Sign a macOS Application

A reliable application signing process accounts for nested code and release configuration rather than treating the outer .app directory as one flat file.

1
BuildCompile app
2
IdentitySelect signer
3
Nested CodeSign components
4
BundleSign application
5
VerifyInspect result
6
NotarizeSubmit release
7
ValidateStaple/check
8
DistributeRelease software

The exact signing order and commands depend on the bundle structure and build workflow. The important principle is that nested executable code must be correctly handled before the release artifact is considered ready for distribution.

Nested Code and macOS Code Signing

A Mac application can contain multiple executable components. Each can participate in the signing hierarchy, which makes nested code one of the most important differences between macOS application signing and a simple single-file executable model.

MyApp.app
│
├── Contents/MacOS/
│ └── MyApp
├── Contents/Frameworks/
│ └── Framework.framework
├── Contents/PlugIns/
│ └── Plugin.bundle
└── Contents/Helpers/
└── Helper.app

Why nested code matters

The outer application is not the only code that can require signing. Frameworks, helper applications, plug-ins, and dynamic libraries may have their own executable code and signatures.

A nested component with an invalid signature, incorrect identity, or unexpected modification can become the reason an otherwise apparently correct application fails verification or distribution checks.

The practical model is:

Nested codeFrameworks, helpers, plug-ins
SignApply appropriate identities
Parent appComplete bundle signing
VerifyInspect the hierarchy

How macOS Verifies a Code Signature

macOS signing verification is not a single certificate-validity test. Multiple layers can contribute to the result presented by Apple's tooling and security mechanisms.

Layer 01

Signature structure

Determine whether the code has a recognizable and valid signature structure.

Layer 02

Code integrity

Check whether signed code corresponds to the data that was originally signed.

Layer 03

Signing identity

Establish which certificate and identity are associated with the signature.

Layer 04

Certificate chain

Evaluate certificate relationships and applicable Apple trust infrastructure.

Layer 05

Requirements

Evaluate designated requirements and other applicable code identity rules.

Layer 06

Entitlements

Inspect capabilities encoded into the signed application where relevant.

Layer 07

Nested code

Check executable components inside the application bundle.

Layer 08

Platform policy

Gatekeeper and related macOS mechanisms can apply additional distribution security decisions.

codesign --verify Explained

Signature verification and system security assessment are related but different operations. Use each tool for the question it is designed to answer.

signature verification
$ codesign --verify --deep --strict --verbose=2 MyApp.app
code object is valid
Signature structure and integrity checked.
signature inspection
$ codesign --display --verbose=4 MyApp.app
Identifier=MyApp
Authority=...
Entitlements=...
Detailed signature information displayed.

The --deep option should not be presented as a universal replacement for correctly signing nested components. It can be useful for verification and certain workflows, but release pipelines should deliberately sign the application's nested code rather than relying on one broad flag to repair an incorrectly structured bundle.

Certificate Chain and Trust on macOS

Three concepts should remain separate: whether the cryptographic signature is valid, whether the certificate chain is trusted, and whether macOS accepts the software under its security policies.

Signing CertificateAssociates the public key with the signing identity.
→
Apple Certificate HierarchyProvides the certificate path used for applicable trust evaluation.
→
Trusted Apple RootActs as a trust anchor within the applicable system trust model.
Cryptographic signature validity

Asks whether the signature can be mathematically verified against the signed code and public-key material.

macOS security acceptance

Can involve identity, trust, notarization, quarantine, Gatekeeper, and other platform security policies.

macOS Code Signing and Keychain

macOS Keychain is important because certificates and private keys used by signing workflows are commonly managed there. A secure build process must also control which identities are available to the signing operation.

CertificatesPublic identity information used with signing and verification.
Private KeysSecret cryptographic material that must be protected from unauthorized use.
Access PermissionsControls can restrict which processes or users can use signing credentials.
CI Build EnvironmentAutomated runners need a controlled way to access the intended signing identity.

A developer workstation and a production signing runner have different risk profiles. CI/CD signing pipelines should avoid making a broadly accessible developer keychain the long-term security boundary for production signing.

macOS Code Signing and Entitlements

Entitlements describe capabilities or permissions associated with signed code. They are part of Apple's application security model and can affect how an application behaves and what it is allowed to access.

ApplicationBundle and executable code
→
EntitlementsCapabilities encoded into the signing configuration
→
Signed CodeEntitlement information becomes part of the signed application state
✓
Application capabilities can depend on entitlement configuration.
✓
Keychain-related access can involve entitlements.
✓
App Sandbox configuration can involve entitlements.
✓
Hardened Runtime-related capabilities can involve entitlements.

Changing entitlements can affect the signed application state. Entitlements should therefore be treated as part of the release signing configuration rather than as a harmless post-signing edit.

Hardened Runtime and Code Signing

Hardened Runtime provides additional runtime protections for modern macOS applications. It works alongside code signing rather than replacing it.

Code SigningEstablishes signed code, cryptographic identity, and integrity information.
+
Hardened RuntimeAdds runtime security controls and works within Apple's application security model.

Modern macOS distribution workflows can involve code signing, Hardened Runtime configuration, entitlements, and notarization together. They address different parts of application security and should not be collapsed into one feature.

Code Signing vs Notarization

These terms are frequently used together, but they describe different stages of Apple's software distribution security model.

AreaCode signingNotarization
Primary purposeSign software and establish signing identity and integrity.Apple's software review and distribution trust service.
Uses signing identityYes. A private key and certificate are central to signing.Works with the signed release as part of the distribution workflow.
Creates the code signatureYes.No. Notarization is not a replacement code signature.
Replaces the other?No.No.
SignEstablish code identity and integrity
NotarizeSubmit applicable release
DistributeDeliver software to users
GatekeeperEvaluate software on macOS

Code Signing and Gatekeeper

Gatekeeper is not the same thing as codesign. Code signing creates and verifies signature information, while Gatekeeper is part of macOS's assessment of software obtained through distribution channels.

Signature layer

What is the code?

codesign can inspect the signature, signer identity, requirements, entitlements, and integrity of the application.

System assessment

Should macOS accept it?

Gatekeeper can consider Developer ID signing, notarization, quarantine state, user/system security decisions, and other relevant signals.

This is why a valid signature alone should not be described as a guarantee that a downloaded application will open without a security warning.

Developer ID and macOS Distribution

Developer ID is associated with distributing Mac software outside the Mac App Store. The distribution workflow can involve different identities for application code and installer-related artifacts.

Developer ID Application

Used conceptually for signing applications and executable code intended for distribution outside the Mac App Store.

The application can then proceed through the applicable verification and notarization workflow.

Developer ID Installer

Used for applicable installer/package distribution scenarios. It should not be assumed that signing the application automatically signs every installer artifact.

Mac App Store distribution follows a different Apple distribution model. It should therefore be treated separately from the Developer ID workflow described here.

macOS Code Signing for Installers

Application signing and installer or package signing are related release activities, but they are not automatically the same operation.

Application

Sign the .app

Sign the application bundle and its executable components according to the distribution workflow.

Installer

Sign package artifact

Where applicable, use the appropriate installer signing identity and process for the distribution artifact.

Validation

Verify both layers

Check the application and installer independently so a valid inner signature is not mistaken for a valid outer package.

Release

Distribute final artifact

Only publish the exact artifact that has completed the intended signing and validation stages.

macOS Code Signing in Xcode

Xcode integrates signing into Apple's development workflow, but development signing and distribution signing are not necessarily the same process.

Project

Signing settings

Configure the signing identity, team, and applicable application settings.

Provisioning

Development configuration

Development workflows can use provisioning and signing settings intended for testing and developer builds.

Archive

Release artifact

Create the archive that will move into the intended distribution workflow.

Distribution

Release signing

Apply the identities and distribution configuration appropriate for the target channel.

Automatic and manual signing can also produce different operational experiences. Production teams should know which identity is being selected, where the private key is stored, and which release configuration is being used.

macOS Code Signing in CI/CD

Automated signing should separate ordinary build permissions from access to production signing identities. The build runner should receive only the access required to create the intended release signature.

Source + BuildCompile, test, archive application.
→
Controlled SigningAccess signing identity through protected build credentials.
→
DistributionVerify, notarize, validate and release.
✓
Secure certificates and private keys used by release automation.
✓
Control Keychain access on CI runners.
✓
Protect notarization credentials and related secrets.
✓
Restrict which pipelines can invoke production signing.
✓
Verify signatures before notarization and release.
✓
Keep an auditable record of release signing operations.

macOS Code Signing With Hardware-Protected Keys

Hardware-backed signing reduces the exposure of private signing keys by moving the sensitive cryptographic operation into a protected environment. Depending on the architecture, this can involve an HSM or a cloud signing service.

Build / Signing ClientRequests a signature for an approved application artifact.
→
Protected Signing ServiceAuthenticates the request and applies signing controls.
→
Hardware-Protected KeyPrivate key remains protected while the signature operation is performed.

The stronger the protection around the signing key, the harder it is for an attacker who compromises an ordinary build machine to impersonate the publisher. Authentication, access controls, runner security, and audit logging still matter even when the key is hardware-protected.

What Happens If a macOS Signing Certificate Expires?

Certificate expiration affects the signing lifecycle, but it should not be reduced to the claim that every previously signed application instantly becomes unusable.

New releases

Use a current identity

New production releases normally need an appropriate active signing identity.

Existing software

Evaluate separately

Historical signatures and distribution behavior depend on Apple's verification model and the release context.

Timestamping

signing-time evidence

Timestamp information can matter when historical signature validity is evaluated.

Renewal

Replace identity

Plan certificate replacement before expiration interrupts automated release operations.

Expiration is not the same as revocation. A certificate lifecycle plan should account for both routine renewal and incident-driven replacement.

What Happens When a Code Signing Certificate Expires?

What Happens If a macOS Signing Certificate Is Revoked?

Revocation represents a change in certificate status and can have different implications from routine expiration. A compromised or otherwise invalidated signing identity should be treated as a release-security incident.

1
Status changesCertificate is revoked
2
Stop affected signingPrevent further use
3
Assess releasesReview distributed software
4
Replace identityNew key and certificate
5
RebuildProduce clean releases
6
Resume releaseControlled signing restored

The exact impact depends on certificate status, the signing context, distributed artifacts, Apple's security systems, and the release channel. Treat revocation as a separate lifecycle event rather than simply an early certificate expiration.

What Happens When a Code Signing Certificate Is Revoked?

What Happens If the Signing Private Key Is Compromised?

A compromised private key is more serious than a certificate nearing expiration because an attacker may be able to create signatures associated with the affected identity.

1
Stop signingDisable affected workflow
2
InvestigateDetermine exposure
3
RevokeHandle certificate status
4
New keyGenerate replacement
5
New certificateProvision new identity
6
RebuildReview release environment
7
Review releasesAssess distributed software

Incident response should also include reviewing CI credentials, keychain access, build logs, release artifacts, and any systems that may have had access to the compromised key.

What Happens If a Code Signing Private Key Is Compromised?

Common macOS Code Signing Errors

Classifying the failure first makes troubleshooting faster. A signing identity problem needs a different response from a nested-code problem or a Gatekeeper assessment.

Signing identity

  • No signing identity found
  • Certificate/private-key mismatch
  • Keychain access problem

Signature

  • Code object is not signed
  • Code signature invalid
  • Modified code

Nested code

  • Nested code not signed
  • Invalid nested signature
  • Framework/helper problem

Entitlements

  • Entitlements mismatch
  • Invalid entitlement configuration
  • Release configuration conflict

Certificate/trust

  • Certificate problem
  • Chain problem
  • Expired or revoked identity

Gatekeeper / notarization

  • Developer cannot be verified
  • Notarization rejected
  • Stapling or validation problem

How to Troubleshoot a macOS Code Signing Failure

Follow the failure outward from the application signature to nested code, identity, entitlements, certificate trust, notarization, and Gatekeeper.

1

Is the application signed?

Start with the basic question: does the application contain the expected signing information?

2

Is the main signature valid?

Use codesign --verify to separate signature or integrity failures from later distribution issues.

3

Are nested components signed?

Inspect frameworks, helpers, plug-ins, and other executable content inside the bundle.

4

Is the signing identity correct?

Inspect the certificate, authority, identifier, and identity selected by the build process.

5

Are entitlements correct?

Check whether the signed application's entitlement configuration matches the intended release.

6

Does the certificate chain validate?

Check certificate status and the applicable Apple trust path.

7

Does notarization succeed?

For applicable distribution workflows, distinguish signing success from Apple's notarization result.

8

Is the ticket or validation correct?

Inspect stapling and validation where the release workflow requires them.

9

What does Gatekeeper report?

Use system assessment output to understand the final distribution-security issue rather than assuming it is a signing failure.

Inspecting a macOS Code Signature

Apple provides different tools for different questions. Use signature tooling to inspect the code signature and system assessment tooling to understand platform policy.

macOS release diagnostics
$ codesign --display --verbose=4 MyApp.app
Identifier=MyApp
Authority=...
TeamIdentifier=...
Entitlements=...

$ codesign --verify --strict --verbose=2 MyApp.app
signature verification result

$ spctl --assess --verbose MyApp.app
system policy assessment result
codesign

Used for signature creation, signature inspection, identity information, and code-signature verification.

spctl

Used to assess software against the system's security assessment policy. It does not answer exactly the same question as codesign.

Complete macOS Signing Workflow

This final architecture connects development, signing, verification, notarization, distribution, and the system assessment a user encounters when launching software.

1
DeveloperSource and release work
2
Xcode / BuildCreate application bundle
3
IdentityCertificate + private key
4
codesignSign app and nested code
5
VerifyCheck signature
6
NotarizeApple service
7
ValidateStaple/check where applicable
8
GatekeepermacOS assessment

The user-facing result is therefore the end of a chain of technical decisions. A failure at signing, nested-code verification, certificate trust, notarization, or Gatekeeper assessment can produce different symptoms and needs a different diagnostic path.

macOS Code Signing Best Practices

Platform-specific signing discipline reduces release failures and limits the damage that can result from compromised signing credentials.

✓
Sign the final application artifact.
✓
Sign nested executable code correctly.
✓
Protect the signing private key.
✓
Use the appropriate Apple distribution identity.
✓
Verify signatures before release.
✓
Validate entitlements as part of the release process.
✓
Use Hardened Runtime where required by the distribution workflow.
✓
Include notarization where applicable.
✓
Test Gatekeeper behavior on a representative clean system.
✓
Keep signing credentials out of source repositories.
✓
Secure CI/CD signing identities and Keychain access.
✓
Maintain certificate and signing incident-response procedures.

Common macOS Code Signing Misconceptions

Most confusion comes from treating signing, notarization, entitlements, and Gatekeeper as one feature. They are connected, but each has a different role.

“macOS code signing is Apple's version of Authenticode.”
No. They are different signing ecosystems with different artifact structures and platform tooling.
“Code signing and notarization are the same.”
No. Code signing creates the cryptographic signature. Notarization is a separate Apple software-security service.
“A signed Mac app is automatically notarized.”
No. Signing and notarization are separate release stages.
“Notarization replaces code signing.”
No. Notarization does not replace the application's code signature.
“A valid signature guarantees an app is safe.”
No. A signature does not prove that software is free from malware, bugs, or vulnerabilities.
“Gatekeeper only checks the certificate.”
No. Gatekeeper can evaluate multiple security signals and system policies.
“Signing the outer .app solves every nested-code problem.”
Not necessarily. Nested executable components can require their own appropriate signing treatment.
“The certificate contains the private key.”
No. The certificate contains public identity information. The private key is separate secret material.
“Changing entitlements after signing does not matter.”
It can affect the signed application state and must be handled within the signing workflow.
“codesign --verify and spctl answer exactly the same question.”
No. codesign focuses on code-signature inspection and verification, while spctl assesses system security policy.

macOS Code Signing FAQ

What is macOS code signing?

macOS code signing is Apple's mechanism for digitally signing applications, executables, bundles, and other supported software so macOS can verify code integrity and associate software with a signing identity.

What certificate is used for macOS code signing?

An appropriate Apple signing certificate is used with its corresponding private key to establish the signing identity used by Apple's signing tools.

How does codesign work?

codesign can sign software and inspect or verify code signatures. It is commonly used in both local Apple development workflows and automated release pipelines.

How do I sign a Mac application?

A typical workflow builds the final application, selects the appropriate signing identity, signs nested code and the application bundle, verifies the signature, and then proceeds through the applicable notarization and distribution workflow.

How do I verify a macOS code signature?

You can use codesign --verify --strict --verbose=2 MyApp.app for signature verification and codesign --display --verbose=4 MyApp.app to inspect signature details.

What is a signing identity?

A signing identity is the usable certificate and corresponding private key combination that Apple's signing tooling can use to sign code.

What is the difference between a certificate and a signing identity?

The certificate provides public identity information, while the signing identity used for signing depends on the certificate and its corresponding private key being available to the signing environment.

What is Developer ID?

Developer ID is associated with distributing Mac software outside the Mac App Store. Different Developer ID identities can apply to application and installer signing scenarios.

What is the difference between Developer ID Application and Developer ID Installer?

Developer ID Application is used for applicable application and executable signing, while Developer ID Installer is used for applicable installer/package signing. They are separate distribution concerns.

What is the difference between code signing and notarization?

Code signing creates a cryptographic signature and establishes signing identity. Notarization is Apple's separate software review and distribution trust service.

What is Gatekeeper?

Gatekeeper is part of macOS's security assessment for software obtained from outside trusted distribution channels. It can consider signing, notarization, quarantine, and other security signals.

Does notarization replace code signing?

No. Notarization does not replace the application's code signature. They are separate but connected parts of an applicable distribution workflow.

What are entitlements?

Entitlements describe capabilities associated with signed code. They can affect application behavior and must be handled as part of the signing configuration.

What is Hardened Runtime?

Hardened Runtime provides additional runtime protections for macOS applications. It works alongside code signing rather than replacing it.

Why does macOS say the developer cannot be verified?

The message can result from the broader macOS security assessment rather than a simple certificate-validity problem. Signing, notarization, quarantine state, distribution context, and system policy can all matter.

Why does codesign --verify fail?

Possible causes include modified code, an invalid signature, incorrect signing identity, broken nested-code signing, entitlement problems, or another code-signature configuration issue.

Why does a nested framework cause a signing error?

A framework is executable code inside the application bundle. If its signature is missing, invalid, unexpectedly changed, or inconsistent with the release workflow, it can affect application verification.

Can macOS code signing be automated in CI/CD?

Yes. Production pipelines can build, archive, sign, verify, notarize, validate, and release applications. The signing identity and Keychain access should be tightly controlled.

Can an HSM or cloud signing service be used?

Yes, depending on the architecture and supported integration. The goal is to keep sensitive signing keys protected while providing controlled access to the signing operation.

What happens when a Mac signing certificate expires?

New releases generally need an appropriate current signing identity. Existing software is a separate evaluation, and timestamping and Apple's verification model can affect how historical signatures are interpreted.

What happens if a Mac signing private key is compromised?

Stop affected signing, investigate exposure, handle certificate revocation or replacement as appropriate, generate a new key, rebuild the signing environment, obtain a new certificate, and review distributed software.

Build a macOS signing workflow that survives release.

Keep signing identity, nested code, entitlements, notarization, Keychain access, and Gatekeeper assessment as distinct technical layers. That makes both release automation and troubleshooting much easier.

Explore Code Signing Solutions →