Files
Jarvis/scripts/verify-codesign-settings.sh
T
james.maes 52f2bdee0d feat(01-05): add build-time codesign + entitlement verification scripts
- 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.
2026-04-22 14:21:33 -05:00

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"