# macOS Analyzer Design Brief (Draft) > Owners: Scanner Guild, Policy Guild, Offline Kit Guild > Related backlog (proposed): SCANNER-ENG-0020..0023, DOCS-SCANNER-BENCH-62-002 > Status: Draft pending demand validation (see `docs/benchmarks/scanner/windows-macos-demand.md`) ## 1. Scope & objectives - Deliver deterministic inventory coverage for macOS container and VM images, focusing on Homebrew, Apple/pkgutil receipts, and `.app` bundles. - Preserve StellaOps principles: per-layer provenance, offline parity, policy explainability, and signed evidence pipelines. - Provide capability signals (entitlements, hardened runtime, launch agents) to enable Policy Engine gating. Out of scope (Phase 1): - Dynamic runtime tracing of macOS services (deferred to Zastava/EntryTrace). - iOS/tvOS/visionOS package formats (will reuse bundle inspection where feasible). - Direct notarization ticket validation (delegated to Policy Engine unless otherwise decided). ## 2. High-level architecture ``` Scanner.Worker (macOS profile) ├─ Surface.Validation (enforce allowlists, bundle size limits) ├─ Surface.FS (layer/materialized filesystem) ├─ HomebrewCollector (new) -> LayerComponentFragment (brew) ├─ PkgutilCollector (new) -> LayerComponentFragment (pkgutil) ├─ BundleInspector (new) -> Capability records + component fragments ├─ LaunchAgentMapper (optional) -> Usage hints └─ MacOsAggregator (new) -> merges fragments, emits ComponentGraph & capability overlays ``` - Each collector runs deterministically against the mounted filesystem; results persist in `ScanAnalysisStore` under dedicated keys before being normalized by `MacOsComponentMapper`. - Layer digests follow existing `LayerComponentFragment` semantics to maintain diff/replay parity. ## 3. Collectors & data sources ### 3.1 Homebrew collector - Scan `/usr/local/Cellar/**` and `/opt/homebrew/Cellar/**` for `INSTALL_RECEIPT.json` and `*.rb` formula metadata. - Output fields: `tap`, `formula`, `version`, `revision`, `poured_from_bottle`, `installed_with`: []. - Store `bottle.sha256`, `source.url`, and `tapped_from` metadata for provenance. - Map to PURL: `pkg:brew//@?revision=`. - Guardrails: limit traversal depth, ignore caches (`/Caskroom` optional), enforce 200MB per formula cap (configurable). ### 3.2 pkgutil receipt collector - Parse `/var/db/receipts/*.plist` for pkg identifiers, version, install time, volume, installer domain. - Use `.bom` files to enumerate installed files; capture path hashes via `osx.BomParser`. - Emit `ComponentRecord`s keyed by `pkgutil:` with metadata: `bundleIdentifier`, `installTimeUtc`, `volume`. - Provide dependency mapping between pkg receipts and Homebrew formulae when overlapping file hashes exist (optional Phase 2). ### 3.3 Bundle inspector - Traverse `/Applications`, `/System/Applications`, `/Users/*/Applications`, `/Library/Application Support`. - For each `.app`: - Read `Info.plist` (bundle id, version, short version, minimum system). - Extract code signing metadata via `codesign --display --xml` style parsing (Team ID, certificate chain, hardened runtime flag). - Parse entitlements (`archived-entitlements.xcent`) and map to capability taxonomy (network, camera, automation, etc.). - Hash `CodeResources` manifest to support provenance comparisons. - Link `.app` bundles to receipts and Homebrew formulae using bundle id or install path heuristics. - Emit capability overlays (e.g., `macos.entitlement("com.apple.security.network.server") == true`). ### 3.4 Launch agent mapper (optional Phase 1 extension) - Inspect `/Library/Launch{Agents,Daemons}` and user equivalents. - Parse `plist` for program arguments, run conditions, sockets, environment. - Feed derived runtime hints into EntryTrace (`UsageHints`) to mark active binaries vs dormant installations. ## 4. Aggregation & output - `MacOsComponentMapper` converts collector results into: - `LayerComponentFragment` arrays keyed by synthetic digests (`sha256:stellaops-os-macbrew`, etc.). - `ComponentMetadata` entries capturing tap origin, Team ID, entitlements, notarization flag (when available). - Capability overlays stored under `ScanAnalysisKeys.capability.macOS`. - Export Center enhancements: - Include Homebrew metadata manifests and CodeResources hashes in attested bundles. - Provide optional notarization proof attachments if Policy Engine later requires them. ## 5. Policy & governance integration - Predicates to introduce: - `macos.bundle.signed(teamId?, hardenedRuntime?)` - `macos.entitlement(name)` - `macos.pkg.receipt(identifier, version?)` - `macos.notarized` (pending Security decision). - Lattice guidance: - Unsigned/unnotarized third-party apps default to `warn`. - High-risk entitlements (camera, screen capture) escalate severity unless whitelisted. - Waiver model similar to existing EntryTrace/Secrets: require bundle hash + Team ID to avoid broad exceptions. ## 6. Offline kit considerations - Mirror required Homebrew taps (`homebrew/core`, `homebrew/cask`) and freeze metadata per release. - Bundle notarization cache instructions (CRL/OCSP) so operators can prefetch without Apple connectivity. - Package Apple certificate chain updates (WWDR) and provide verification script to ensure validity. - Document disk space impacts (Homebrew cellar snapshots ~500MB per tap snapshot). ## 7. Testing strategy - Unit tests with fixture directories: - Sample Cellar tree with multiple formulas (bottled vs source builds). - Synthetic pkg receipts + BOM files. - `.app` bundles with varying signing states (signed/notarized/unsigned). - Integration tests: - Build macOS rootfs tarballs via CI job (runner requiring macOS) that mimic layered container conversion. - Verify deterministic output by re-running collectors and diffing results (CI gating). - Offline compliance tests: - Ensure rule bundles and caches load without network by running integration suite in sealed environment. ## 8. Dependencies & open items | Item | Description | Owner | Status | | --- | --- | --- | --- | | Demand threshold | Need ≥3 qualified customer asks to justify engineering investment | Product Guild | Active (DOCS-SCANNER-BENCH-62-002) | | macOS rootfs fixtures | Require automation to produce macOS layer tarballs for tests | Scanner Guild | Pending design | | Notarization validation | Decide whether scanner performs `spctl --assess` or defers | Security Guild | TBD | | Entitlement taxonomy | Finalize capability grouping for Policy Engine | Policy Guild | TBD | ## 9. Proposed backlog entries | ID (proposed) | Title | Summary | | --- | --- | --- | | SCANNER-ENG-0020 | Implement Homebrew collector and fragment mapper | Parse cellar manifests, emit brew component records, integrate with Surface.FS/Validation. | | SCANNER-ENG-0021 | Implement pkgutil receipt collector | Parse receipts/BOM, output installer component records with provenance. | | SCANNER-ENG-0022 | Implement macOS bundle inspector & capability overlays | Extract plist/signing/entitlements, produce capability evidence and merge with receipts. | | SCANNER-ENG-0023 | Policy & Offline integration for macOS | Define predicates, CLI toggles, Offline Kit packaging, and documentation. | ## 10. References - `docs/benchmarks/scanner/deep-dives/macos.md` — competitor snapshot and roadmap summary. - `docs/benchmarks/scanner/windows-macos-demand.md` — demand capture log. - `docs/modules/scanner/design/surface-secrets.md`, `surface-fs.md`, `surface-validation.md` — surface contracts leveraged by collectors. Further reading: `../../api/scanner/windows-coverage.md` (summary) and `../../api/scanner/windows-macos-summary.md` (metrics dashboard). Policy readiness alignment: see `../policy/secret-leak-detection-readiness.md` (POLICY-READINESS-0001). Upcoming milestone: Northwind Health Services demo on 2025-11-10 to validate notarization/entitlement outputs before final policy sign-off.