macOS Hardened Runtime is only as strong as its entitlement budget
Hardened Runtime protects the integrity of a macOS process by restricting code injection and related runtime changes. Apple enables the capability as part of the distribution and notarization workflow. The security value is real, but it is easy to spend on broad exception entitlements without noticing.
What the runtime protects
Apple documents Hardened Runtime as a set of protections that, together with System Integrity Protection, reduce classes of code injection, dynamic library hijacking, and process memory tampering. One central control is library validation. By default, a program using library validation loads frameworks, plug-ins, and libraries only if they are signed by Apple or by the same Team ID as the main executable.
Apple also requires Hardened Runtime for notarization. That makes the capability a practical gate for software distributed outside the App Store. The gate is useful, but it is not a code review. Notarization checks a distribution path and malware scan status. It does not prove that the application's own logic is safe.
Exceptions are part of the attack surface
Apple's configuration guide explains the exception model. If an app relies on behavior that Hardened Runtime restricts, the developer adds a specific entitlement. Library validation can be disabled with com.apple.security.cs.disable-library-validation. Executable memory protections can be relaxed with com.apple.security.cs.disable-executable-page-protection. Debugging and JIT-related entitlements create other exceptions.
Each exception should be justified by a concrete compatibility requirement. A plug-in architecture that loads third-party code may need library validation disabled, but that decision changes the trust model. The app can now load a library from a path or signer that the base runtime would reject. The question is who controls that path and whether the plug-in is independently verified.
The exception budget should be visible during code review. A change that adds an entitlement is a security change even when the diff contains only a few XML lines. It deserves the same review as a network listener or a privileged helper.
Audit the signed product, not only the source tree
Source entitlements can differ from the entitlements in the shipped binary. Inspect the final signed application with codesign and record the output with the release artifact. A useful review includes the signing identity, hardened runtime flag, Team ID, entitlement list, and notarization ticket.
Do not infer trust from the certificate chain alone. A Developer ID signature tells you who signed the artifact and whether the signature validates. It does not tell you that the binary has no dangerous entitlement or that every loaded library is from the same trusted publisher.
For applications with plug-ins, map every load path. Confirm whether the host performs its own signature check, whether it validates the Team ID, and what happens when a plug-in fails validation. A disabled library validation entitlement plus a user-writable plug-in directory is a very different risk from a fixed, signed plug-in bundle inside the app.
Roll out as a product decision
Application owners should be able to answer why each exception exists. Security teams should be able to see which exceptions are present across the fleet and which applications have changed their entitlement set. Endpoint inventory should distinguish the base hardened runtime from an application that has several broad exceptions.
Test updates and uninstalls, not only first launch. A privileged installer or updater may be signed with a different Team ID. If the main application disables library validation to load third-party components, an update can change the effective trust boundary without changing the application's user-facing behavior.
The same review applies to extensions and helper processes. A hardened main process does not protect a helper that is separately signed with a broad entitlement. Inventory every executable in the bundle and attribute each one to a role.
The useful baseline
Enable Hardened Runtime, keep library validation on unless a documented compatibility requirement demands otherwise, and make each exception a reviewed release artifact. Treat notarization as a distribution control rather than an execution guarantee. Inspect the final binary and the loaded code paths because the source tree and the shipped app can diverge.
The practical goal is not to reach zero entitlements. It is to know which protections have been removed, why the application needs the exception, and which code can take advantage of it. Hardened Runtime is valuable when that budget is small and visible.
References
- Apple Developer Documentation, Hardened Runtime
- Apple Developer Documentation, Configuring the hardened runtime
- Apple Developer Documentation, Disable Library Validation Entitlement
Top comments (0)