Define the security boundary

Enable Hardened Runtime

Adopt runtime protections for distributed code and grant exceptions only for behavior the application can justify and test.

12 minute lesson

~~~

The Hardened Runtime is a set of protections your app opts into at signing time. It blocks code injection, loading of unsigned or tampered libraries, and debugger attachment in shipped builds. You’re telling macOS: this process should never be modified at runtime — enforce that.

You need it. Notarization requires the Hardened Runtime on every executable in a Developer ID distribution. No hardened runtime, no notarization, no smooth installs.

In Xcode, add the Hardened Runtime capability under Signing & Capabilities for the app target and every helper or bundled tool target. If you sign manually in a script, it’s the --options runtime flag:

codesign --force --options runtime \
  --sign "Developer ID Application: Flavio Copes (ABCDE12345)" \
  Notes.app

Verify it took. The flags line must include runtime:

codesign -d --verbose=2 Notes.app

Look for flags=0x10000(runtime) in the output.

The runtime has escape hatches: exceptions for just-in-time compilation, unsigned executable memory, debugging, and library validation. Some apps genuinely need one — an app embedding a JavaScript engine with JIT, for example. But every exception switches off one specific protection, so treat them like sandbox entitlements: none by default, each one justified by a feature you can name.

When a third-party dependency crashes under the hardened runtime, investigate before reaching for an exception. Often the real problem is a badly signed framework, and the right fix is re-signing or updating the dependency, not disabling library validation for your whole app.

And check that debug entitlements are gone. com.apple.security.get-task-allow must not survive into a shipping build.

The failure you’ll actually meet: a scripted build that signs without --options runtime. Everything works locally. Then notarytool returns Invalid, and the log says the executable does not have the hardened runtime enabled. Recognize that message, add the flag, re-sign, resubmit.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →