Follow #973's native ownership: the code-signing posture schemas move to
src/domain/native/ beside nativeInspection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
codesign prints one nested path per line, so a nested component whose name
contains a newline is split into fragments. inspect_signature now checks
that every --validated: path it reports exists, and names any that does not
in a limitation instead of trusting it as a complete path. The result stays
deterministic: codesign's progress lines arrive in no fixed order, so the raw
output is not echoed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Treat a CodeDirectory platform identifier as a platform binary only when
the signature satisfies `anchor apple`, checked with
`codesign --verify -R="anchor apple"`; otherwise the dependent facets are
unknown. Developer ID code chains to Apple Root CA but fails this check.
- Report every security facet as unknown when architecture slices differ in
signing state.
- Map an aborted signal that escapes a native helper, such as ticket
hashing, to AnalysisCancelledError instead of an output error.
- Treat a target as an app bundle only when it was opened from a bundle
directory, so a regular file named X.app is verified as a bare Mach-O.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Address review findings in inspect_signature:
- Verify with `codesign --verify --deep --strict`. Shallow verification
misses a file added inside a nested XPC service, or a modified dylib
inside a framework. verify:code-signature now tampers inside the
nested XPC service and requires `invalid`.
- Classify verification as `unsigned` only when the top-level target is
unsigned. Unsigned nested code inside a signed bundle is `invalid`.
- Report a stapled ticket that exists but cannot be read as
`unreadable`, with the error code in a new `reason` field, instead of
failing the whole signature inspection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
inspect_signature reduced the CodeDirectory to a hardened-runtime boolean
and never verified the signature. It now also reports:
- the parsed CodeDirectory: version, flags decoded from their numeric
value (runtime, library-validation, restrict, kill, adhoc,
linker-signed, unknown bits in hex), code and special slot counts,
location, hash type, platform identifier, runtime version, and
executable-segment flags;
- sealed resources (version, rules, files, or none);
- a local `codesign --verify --strict` result on the opened bundle or
Mach-O, with diagnostics and the sorted nested code it validated;
- whether a notarization ticket is stapled at Contents/CodeResources,
with its digest. The ticket and Apple's records are not checked
because that needs the network;
- derived security facets with their supporting evidence: library
validation, DYLD_* handling, debugger attach, executable-memory
policy, and App Sandbox. Facets stay unknown when flags or aggregate
entitlements are unavailable.
verify:code-signature re-signs copies of the clang-built fixture with
real codesign (ad hoc, hardened runtime, hardened runtime with relaxing
entitlements, library,restrict). It also checks a platform binary and a
tampered bundle, with CLI/MCP parity, and runs in the macOS CI job.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>