After the Gatekeeper Fail-Open Report: The October 2026 Retest
The original report documented a fail-open that let a revoked-certificate app execute. Re-tested on macOS 26.7.1 and 27.0.1, the app did not execute — in any condition. This report maps what changed, what it means, and what remains unresolved.
Companion page: the original report (August 2026) → · Full paper + evidence: github.com/aimarketingflow/macos-gatekeeper-revocation-bypass · Change discovered incidentally while testing OpenDLP against macOS 27's reworked EndpointSecurity framework — not through targeted follow-up on the original report.
UseCRLite is disabled) at the time of the original testing, is now
active on macOS 27.0.1 (UseCRLite is enabled (via feature flags)).The Questions the Retest Asked
- Does the fail-open still execute? With the revocation responder unreachable, does a revoked-certificate app still run — as it did in July?
- Is the verdict stored — and where? If blocked, which local store held the revoked status, and can removing it restore execution?
- Does the memory of revocation expire? A cached OCSP response has a
nextUpdatedeadline. Is it still enforced weeks past that deadline, offline? - Did the dormant layer wake up? The paper documented CRLite present but disabled. Is it still disabled — and does it change the outcome?
Results at a Glance
| Historical (July 2026 capture) | Pro — 26.7.1 (25G241) | Air — 27.0.1 (26A434) | |
|---|---|---|---|
| DMG container | Opened | Refused at open (malware-class dialog, reported) | Opened in most runs; later runs refused at open |
| App execution | Executed (fail-open) | Refused | Refused |
| CRLite switch | Disabled | Disabled (reported) | Enabled — enforcement observed |
| Revocation data on device | Present, unused | Not found | Filters present |
| Cause of the block | — (no block) | source unresolved | cached OCSP verdict |
Historical and current tests used differing cache conditions and artifact versions — this is not a matched comparison of builds. "DMG opened" and "app executed" are separate enforcement stages and are reported separately throughout.

The Machine Remembers the Verdict
The central technical lesson of the retest: "the cache" is not one thing. Revocation verdicts persist in several independent local stores, and — unlike a speed cache — they are enforced offline, without any responder contact. That is precisely why the historical fail-open no longer reproduces: an unreachable responder used to mean "no answer"; now it means "enforce the last answer on file."

ocspcache.sqlite3 | Per-certificate OCSP responses | Held the target's revoked verdict on both machines — enforced far past its own nextUpdate |
Bulk validity data (e.g. valid.sqlite3) | Bulk serial/hash lists + CRLite metadata | Rebuilt itself while offline on the Pro; its exact enforcement semantics remain open |
TrustStore.sqlite3 | Trust anchors / policy state | Exonerated as the verdict source in the Pro investigation |
| ExecPolicy + notarization tickets | Prior decisions, stapled state | Consulted by evaluators; not the target's verdict source |
Resetting one store is not resetting the machine's memory of the verdict.
Pro Investigation (26.7.1): Clearing the Cache Didn't Restore Execution
Recovery-mode surgery identified and removed the target's revoked OCSP response
(ocspcache.sqlite3, certStatus=1) and cleared bulk validity data. On retest
with a fresh trustd process, the app was still refused — some other local
source held the verdict. Live queries found the certificate's serial and SHA-256 absent from the
73,711-row bulk valid list; whether that absence is itself an enforcement input (an absence-based
fail-closed mechanism) remains a hypothesis — absence from one queried
table does not establish the lookup path.
Source: reports/2026-10-09_TEST_RESULTS_CONSOLIDATED.md, reports/2026-10-09_FRESH_STATE_VERDICT.md in the evidence repository.
Air Investigation (27.0.1): The Stale Verdict, Enforced
The Air's cached-state test produced the cleanest mechanism evidence of the retest:
OCSPSingleResponse: nextUpdate 65.74 days ago
OCSP status revoked=1 definitive=1 fetchFailed=0 timedOut=0
cert[0]: Revocation =(leaf)[force]> 6
Trust evaluate failure: [leaf Revocation6]The stored answer was ~66 days past its own freshness date, the responder was unreachable, and the
system enforced the last answer on file anyway: the app launch was refused. The October 16 sysdiagnose
shows the same cached verdict at 72.96 days past nextUpdate — still enforced, with sibling
evaluations showing fetchFailed=1 (responder unreachable at eval time).
Source: evidence/air-2026-10-09_offline-retest-evidence.txt, evidence/air-2026-10-16_dmg-block-evidence.txt.

Two Stages, One Verdict — and an Open Question
The builds refused the target at different stages: the Pro rejected the DMG container
itself (malware-class dialog, reported); the Air typically mounted the DMG and refused the app. Sysdiagnose
evidence from October 16 shows the Air can also fire the DMG-stage malware block
(XProtectMalwareType = 10, four evaluations that day) — so both enforcement paths exist on
27.0.1, and what varies is which stage fires.

The October 16 Run, Minute by Minute
The newest Air sysdiagnose captured the exact sequence behind the current screenshots — one evaluation chain, from mount attempt to denial, with the machine offline:
| Time (EDT) | Event |
|---|---|
| 17:33:53–54 | Disk image source attached; trustd evaluates the certificate chain |
| 17:33:54.094 | Cached OCSP response read: nextUpdate 72.96 days ago, revoked=1 definitive=1 — sibling evals show fetchFailed=1 (responder unreachable) |
| 17:33:54.094 | syspolicyd: Trust evaluate failure: [leaf Revocation6]; SecStaticCode verification fails (trust result 6) |
| 17:33:54.883 | XProtect completes executable analysis of the DMG: XProtectMalwareType = 10, XProtectShouldTranslocateDMG = 1 |
| 17:33:54+ | Kernel records repeated ES_AUTH_RESULT_DENY events; notarization daemon checks error out (offline) |
| 17:34:29 | Second DiskImageMounter launch — same revocation verdict, same refusal |
| 17:46:06 / 17:46:45 | Two more evaluations (-049 DMG from Downloads, then -013 again) — identical outcome |
Source: evidence/air-2026-10-16_dmg-block-evidence.txt, extracted from sysdiagnose_2026.10.16_17-46-55-0400_macOS_Mac_26A434.tar.gz. The evidence supports a real
denial sequence but does not by itself prove whether every denial was caused by the stale OCSP response,
CRLite, XProtect, or an interaction among them — the stale revoked OCSP result is the clearest direct
revocation input.
The Deployment Change: CRLite Is Active on 27.0.1
The paper's §5 documented CRLite as the obvious missing defense: infrastructure present, feature flag off. The retest's runtime captures show the flag state flipped between the two eras:
July 24, 2026 capture: UseCRLite is disabled (via feature flags)
Oct 9, 2026 capture: UseCRLite is enabled (via feature flags)Apple's published source (Security · SecRevocationServer.c L646–668)
shows the gate: when the enforcement predicate is false, the function returns before a CRLite "revoked"
verdict is ever applied — the verdict exists but never reaches its consequence. When true, the verdict
becomes a formal trust failure and is logged (Enforcing CRLite result).
revoked: 0).
What the Evidence Establishes
nextUpdate, applied with no network path to the responder.trustd was fresh.What Remains Unresolved
The Apple Exchange
The full ticket thread behind the original report — including Apple's July 28 "intended behavior" response (which confirmed the cached-revoked-response pinning the retest later observed directly) and the August 25 close — is preserved in the public evidence repository: Full ticket thread OE1107167498810 →
Timeline — and Why This Was Published Anyway
| When | What |
|---|---|
| ~6 years | The fail-open behavior ships; a revoked certificate plus an unreachable responder can end in execution |
| Summer 2026 | Reported; closed as intended behavior / not a security boundary. At testing time, the fix already existed on the machine — the CRLite enforcement layer sat disabled |
| October 2026 | Same artifact, same test: the flag is enabled; the artifact is refused in every recorded run — at the DMG stage or the app stage, on both tested releases |

Evidence Index
| Artifact | Location |
|---|---|
| Air evidence extracts (Oct 8, 9, 16) | evidence/ in the evidence repository |
| Air sysdiagnose archives (Oct 9, 15, 16) — local only, not committed | local archive (not published) |
| Pro test-run reports, recovery guides | reports/ in the evidence repository |
| Air revocation mechanism handoff | handoff/2026-10-08_AIR_SIDE_REVOCATION_MECHANISM.md |
| Slide assets + provenance notes | slide-assets/ in the evidence repository |
| Deck slide renders used on this page | rendered from the deck PDFs; images hosted on this site |
| Original paper + figures | macos-gatekeeper-revocation-bypass |