Hardened runtime for macOS

From Lazarus wiki

English (en)


This article applies to macOS only.

See also: Multiplatform Programming Guide


The hardened runtime was introduced by Apple in macOS 10.14 (Mojave) and while it is optional for applications, it is required in order to notarize your application.

The hardened runtime, along with System Integrity Protection (SIP), protects the runtime integrity of your application software by preventing certain classes of exploits, like code injection, dynamically linked library hijacking, and process memory space tampering. If your application relies on a capability that the hardened runtime restricts, you need to add an entitlement to disable an individual protection. You should only add the entitlements that are absolutely necessary for your applications functionality.

Sandboxing and the hardened runtime prevent an application from doing things it would ordinarily have had permission to do. It should be noted that these two protections are overlapping. The sandbox and the hardened runtime could prevent the same action, so even if the hardened runtime would allow the action, the sandbox may prevent it, and vice versa. See the external links to Apple's lists of hardened runtime entitlements and sandboxing entitlements below.

Hardening your application

The hardening of an application is done during code signing. To harden your application, open a Terminal and run this command:

codesign -f -o runtime --timestamp -s "Developer ID Application: YOUR NAME (TEAM_ID)" /path/to/bundle.app

Hardened runtime entitlements

To allow your application to do something that is now prevented by your hardened runtime, you need to give it that entitlement. You do this by creating an entitlements plist file like this:

<?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">

This would allow your application to capture movies and still images using the built-in camera. To verify you have a valid plist file, open a Terminal and run the following command:

plutil entitlements.plist

If the file is properly formatted, the output of that command should be:

entitlements.plist: OK

To add this entitlement to your application, you need to add it to your code signing command like this:

codesign -f -o runtime --timestamp --entitlements entitlements.plist -s "Developer ID Application: YOUR NAME (TEAM_ID)" /path/to/bundle.app

Verifying hardening

To verify that you have successfully hardened your application, open a Terminal and run this command:

codesign --display --verbose

The output of that command should be similar to:

Format=app bundle with Mach-O thin (x86_64)
CodeDirectory v=20500 size=101470 flags=0x10000(runtime) hashes=3164+3 location=embedded
Signature size=9063
Timestamp=7 Dec 2019 at 18:36:08
Info.plist entries=16
TeamIdentifier=<10 alpha numerical digits>
Runtime Version=10.14.0
Sealed Resources version=2 rules=13 files=45
Internal requirements count=1 size=180

The (runtime) flag in the "CodeDirectory" line indicates that your application is hardened.

To check whether the required hardened runtime entitlements are available, open a Terminal and run the following command:

codesign --display --entitlements /path/to/bundle.app

which should result in the following output:

<?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">

See also

External links