krz/domain-dig

an ios app for DNS & SSL analysis

clone: git clone https://gitbay.org/krz/domain-dig.git

df69393f7e556dccfacfb05378fcce5c9ffc125b

verified · cmc

author: Christian Cleberg <hello@cleberg.net> · 2026-08-22T08:02:40Z

Do not touch CloudKit from a build without entitlements

The app aborted before its first screen on any unsigned build, which is what CI
produces: xcodebuild ... CODE_SIGNING_ALLOWED=NO embeds no entitlements, so
CKContainer.default() could not resolve the iCloud container from them. It does
not return an error in that case — it raises an Objective-C exception from
inside a dispatch_once, which Swift cannot catch, so the existing do/catch never
had a chance and the process took SIGABRT. Every AccessibilityAuditTests case
then failed as 'application is not running'.

An explicit CKContainer(identifier:) crashes the same way; CloudKit validates
against entitlements either way. So the fix is to not ask. The App Group is
declared in the same entitlements file and stripped by the same mechanism, but
asking for its container returns nil rather than raising, which answers the
question CloudKit will not: does this process have entitlements at all.

Signed builds are unaffected — the container resolves, the guard passes, owner
resolution runs as before. This is why the audit job has failed since
2026-07-25; the run on krz-rebrand shows the same crash three weeks before this
branch existed.
 DomainDig/OwnerAccess.swift | 23 +++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/DomainDig/OwnerAccess.swift b/DomainDig/OwnerAccess.swift
index eca2bab..e209d2a 100644
--- a/DomainDig/OwnerAccess.swift
+++ b/DomainDig/OwnerAccess.swift
@@ -14,10 +14,29 @@ enum OwnerAccess {
 
     static var isConfigured: Bool { !ownerUserRecordID.isEmpty }
 
+    /// Whether this build actually carries its entitlements.
+    ///
+    /// Touching CloudKit without the iCloud container entitlement does not
+    /// return an error — it raises an Objective-C exception from inside a
+    /// `dispatch_once`, which Swift cannot catch, so the process aborts before
+    /// the first screen draws. That is what any unsigned build does, including
+    /// CI: `xcodebuild ... CODE_SIGNING_ALLOWED=NO` embeds no entitlements.
+    ///
+    /// The App Group is declared in the same entitlements file and is stripped
+    /// by the same mechanism, but asking for its container returns nil rather
+    /// than raising. So it answers the question CloudKit will not: does this
+    /// process have its entitlements at all?
+    private static var hasEntitlements: Bool {
+        FileManager.default.containerURL(
+            forSecurityApplicationGroupIdentifier: DomainDigWidgetStore.appGroupID
+        ) != nil
+    }
+
     /// The current iCloud user's record name for this app's container, or nil if
-    /// it is unavailable (not signed into iCloud, restricted, or offline before
-    /// the first fetch).
+    /// it is unavailable (not signed into iCloud, restricted, offline before the
+    /// first fetch, or running from a build without entitlements).
     static func currentUserRecordName() async -> String? {
+        guard hasEntitlements else { return nil }
         do {
             return try await CKContainer.default().userRecordID().recordName
         } catch {