- scripts/codesign.sh: deepest-first walker (find -depth) signing nested Contents/Helpers/**/*.app with per-helper .entitlements, then main app last. Never uses --deep (TN2206/Pitfall #3 guard). - scripts/verify-entitlements.sh: two-mode script per RESEARCH Open Q #8. --pre-codesign validates source + writes JarvisEntitlementsVerified=YES to unsigned Info.plist so the flag becomes part of the signed content. --post-codesign greps signed entitlements (via codesign -d --entitlements -) for MAIN_REQUIRED/MAIN_FORBIDDEN + per-helper rules; never writes. Strips XML comments before grep (self-invalidating-grep defense). - scripts/verify-codesign-settings.sh: pbxproj linter for CodeSignOnCopy = YES, --deep, and missing --options=runtime/--timestamp. - scripts/test-verify-entitlements.sh: fault-injection self-test harness that feeds good/broken/forbidden fixtures to --verify-fixture mode and asserts exit codes. - scripts/test-fixtures/{good,broken,forbidden}-entitlements.plist: fixtures exercising the happy path, missing allow-jit, and forbidden apple-events. Self-test: PASS=3 FAIL=0. Linter passes against current pbxproj. MCP-06, SEC-02, SEC-03, SEC-08 scaffolded.
48 lines
2.0 KiB
Bash
Executable File
48 lines
2.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# verify-codesign-settings.sh — pbxproj linter for codesign hygiene.
|
|
#
|
|
# Fails the build if the pbxproj carries:
|
|
# (1) CodeSignOnCopy = YES anywhere — Xcode's "Code Sign On Copy" re-signs
|
|
# nested helpers with the parent target's identity, stripping per-helper
|
|
# entitlements (MCP-06 / R1 H-B2).
|
|
# (2) --deep anywhere in codesign-adjacent settings — TN2206 / Pitfall #3.
|
|
# (3) OTHER_CODE_SIGN_FLAGS missing --options=runtime or --timestamp —
|
|
# Hardened Runtime + secure timestamp must be on every sign call.
|
|
#
|
|
# Strips NeXTSTEP-plist comments (// and /* */) before grep so the linter is
|
|
# not self-invalidated by a comment that happens to mention a forbidden flag.
|
|
set -euo pipefail
|
|
|
|
PBXPROJ="${SRCROOT:-$(pwd)}/Jarvis.xcodeproj/project.pbxproj"
|
|
if [ ! -f "$PBXPROJ" ]; then
|
|
echo "error: pbxproj not found at $PBXPROJ" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Strip // line comments and /* ... */ block comments before grep.
|
|
STRIPPED="$(/usr/bin/sed 's|//.*$||; s|/\*.*\*/||g' "$PBXPROJ")"
|
|
|
|
# Rule 1: CodeSignOnCopy = YES must NOT appear anywhere in the pbxproj.
|
|
if echo "$STRIPPED" | /usr/bin/grep -E 'CodeSignOnCopy[[:space:]]*=[[:space:]]*YES' > /dev/null; then
|
|
echo "error: pbxproj contains 'CodeSignOnCopy = YES' — forbidden (MCP-06 / R1 H-B2)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Rule 2: --deep flag must NOT appear anywhere codesign-adjacent.
|
|
if echo "$STRIPPED" | /usr/bin/grep -E -- '(--deep|"--deep")' > /dev/null; then
|
|
echo "error: pbxproj contains '--deep' flag — forbidden (TN2206 / Pitfall #3)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# Rule 3: OTHER_CODE_SIGN_FLAGS must include --options=runtime and --timestamp.
|
|
if ! echo "$STRIPPED" | /usr/bin/grep -E 'OTHER_CODE_SIGN_FLAGS.*--options=runtime' > /dev/null; then
|
|
echo "error: pbxproj OTHER_CODE_SIGN_FLAGS must include --options=runtime" >&2
|
|
exit 1
|
|
fi
|
|
if ! echo "$STRIPPED" | /usr/bin/grep -E 'OTHER_CODE_SIGN_FLAGS.*--timestamp' > /dev/null; then
|
|
echo "error: pbxproj OTHER_CODE_SIGN_FLAGS must include --timestamp" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "verify-codesign-settings: pbxproj lint passed"
|