Skip to content

tcc: fail-safe SIP detection for hosts in Custom Configuration - #1259

Open
rcurranmoz wants to merge 1 commit into
masterfrom
fix-sip-detection-regex
Open

rcurranmoz wants to merge 1 commit into
masterfrom
fix-sip-detection-regex

Conversation

@rcurranmoz

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #1152. Inverts the default in the SIP detection block of tcc_perms.sh and add_tcc_perms.sh so anything other than a clean System Integrity Protection status: enabled. is treated as SIP-off (legacy behavior).

The current logic:

SIP_DISABLED=false
if csrutil status 2>/dev/null | grep -qi "disabled"; then
    SIP_DISABLED=true
fi

misses hosts whose csrutil status returns "unknown (Custom Configuration)". Those hosts silently fall through to the SIP-on code path and the legacy system-DB writes they rely on get skipped.

Where this was observed

During validation of #1152, two production staging r8 hosts (macmini-r8-109, macmini-r8-154) reported this state:

% csrutil status
System Integrity Protection status: unknown (Custom Configuration).

Neither is actively broken today — the entries from previous master-branch puppet runs persist. But if either loses its system TCC.db (EACS, OS reinstall, sqlite reset), the next puppet run wouldn't re-apply them.

The fix

Invert the default so ambiguity falls through to the legacy path:

SIP_DISABLED=true
if csrutil status 2>/dev/null | grep -qiE "status:[[:space:]]*enabled\.?$"; then
    SIP_DISABLED=false
fi

Clean SIP-off (disabled.) and clean SIP-on (enabled.) hosts behave the same as before. Only ambiguous / edge-case output changes behavior — and it changes to the safer (write the legacy entries) direction.

Test plan

  • Regex hand-checked against the three real csrutil status outputs observed in the fleet:
    • System Integrity Protection status: enabled. → matches → SIP_DISABLED=false ✓
    • System Integrity Protection status: disabled. → doesn't match → SIP_DISABLED=true ✓
    • System Integrity Protection status: unknown (Custom Configuration). → doesn't match → SIP_DISABLED=true ✓ (fail-safe to legacy)
  • Puppet apply on macmini-r8-109 or macmini-r8-154 (Custom Configuration) — expect the system-DB writes to happen this time.
  • Puppet apply on a cleanly-SIP-disabled host (any m4-{111,112,113}, r8-{246,361,375}, r8-1015) — should behave identically to today.

🤖 Generated with Claude Code

The SIP detection in tcc_perms.sh and add_tcc_perms.sh (added in #1152)
matched output containing "disabled" to decide whether to write the
legacy system-DB TCC entries. Hosts whose `csrutil status` returns
`"unknown (Custom Configuration)"` (observed on r8-109 and r8-154
during PR #1152 validation) don't match that regex — they get treated
as SIP-on, and the system-DB writes their configuration actually
depends on get silently skipped.

Existing entries persist as long as nothing clears TCC.db, so this
hasn't broken anything today. But if a Custom-Configuration host ever
gets its system TCC.db cleared (EACS, OS reinstall, manual reset), the
next puppet run wouldn't re-apply the entries.

Fix: invert the default. Treat the host as SIP-off unless csrutil
clearly says "enabled" (matching the canonical
`System Integrity Protection status: enabled.` line). Fail-safe to
the legacy path — anything ambiguous preserves the write path the
existing fleet has always relied on.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@rcurranmoz
rcurranmoz requested a review from a team July 1, 2026 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant