Files
git.stella-ops.org/docs/airgap/macos-offline.md
StellaOps Bot d040c001ac
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
up
2025-11-28 19:23:54 +02:00

6.7 KiB

macOS Offline Kit Integration

Owner: Scanner Guild, Offline Kit Guild Related tasks: SCANNER-ENG-0020..0023

Overview

This document describes the offline operation requirements for macOS package scanning, including Homebrew formula metadata, pkgutil receipts, and application bundle analysis.

Homebrew Offline Mirroring

Required Tap Mirrors

For comprehensive macOS scanning in offline environments, mirror the following Homebrew taps:

Tap Path Est. Size Update Frequency
homebrew/core /opt/stellaops/mirror/homebrew-core ~400MB Weekly
homebrew/cask /opt/stellaops/mirror/homebrew-cask ~150MB Weekly
Custom taps As configured Varies As needed

Mirroring Procedure

# Clone or update homebrew-core
git clone --depth 1 https://github.com/Homebrew/homebrew-core.git \
    /opt/stellaops/mirror/homebrew-core

# Clone or update homebrew-cask
git clone --depth 1 https://github.com/Homebrew/homebrew-cask.git \
    /opt/stellaops/mirror/homebrew-cask

# Create manifest for offline verification
stellaops-cli offline create-manifest \
    --source /opt/stellaops/mirror/homebrew-core \
    --output /opt/stellaops/mirror/homebrew-core.manifest.json

Formula Metadata Extraction

The scanner extracts metadata from INSTALL_RECEIPT.json files in the Cellar. For policy evaluation, ensure the following fields are preserved:

  • tap - Source tap identifier
  • version and revision - Package version info
  • poured_from_bottle - Build source indicator
  • source.url, source.checksum - Provenance data
  • runtime_dependencies, build_dependencies - Dependency graph

pkgutil Receipt Data

Receipt Location

macOS pkgutil receipts are stored in /var/db/receipts/. The scanner reads:

  • *.plist - Receipt metadata (installer, version, date)
  • *.bom - Bill of Materials (installed files)

Offline Considerations

pkgutil receipts are system-local and don't require external mirroring. However, for policy enforcement against known package identifiers, maintain a reference database of:

  • Apple system package identifiers (com.apple.pkg.*)
  • Xcode component identifiers
  • Third-party installer identifiers

Application Bundle Inspection

Code Signing & Notarization

For offline notarization verification, prefetch:

  1. Apple Root Certificates

    • Apple Root CA
    • Apple Root CA - G2
    • Apple Root CA - G3
  2. WWDR Certificates

    • Apple Worldwide Developer Relations Certification Authority
    • Developer ID Certification Authority
  3. CRL/OCSP Caches

    # Prefetch Apple CRLs
    curl -o /opt/stellaops/cache/apple-crl/root.crl \
        https://www.apple.com/appleca/root.crl
    

Entitlement Taxonomy

The scanner classifies entitlements into capability categories for policy evaluation:

Category Entitlements Risk Level
network com.apple.security.network.client, .server Low
camera com.apple.security.device.camera High
microphone com.apple.security.device.microphone High
filesystem com.apple.security.files.* Medium
automation com.apple.security.automation.apple-events High
code-execution com.apple.security.cs.allow-* Critical
debugging com.apple.security.get-task-allow High

High-Risk Entitlement Alerting

The following entitlements trigger elevated policy warnings by default:

com.apple.security.device.camera
com.apple.security.device.microphone
com.apple.security.cs.allow-unsigned-executable-memory
com.apple.security.cs.disable-library-validation
com.apple.security.get-task-allow
com.apple.security.files.all
com.apple.security.automation.apple-events

Policy Predicates

Available Predicates

The following SPL predicates are available for macOS components:

# Bundle signing predicates
macos.signed                              # Bundle has code signature
macos.signed("TEAMID123")                 # Signed by specific team
macos.signed("TEAMID123", true)           # Signed with hardened runtime
macos.sandboxed                           # App sandbox enabled
macos.hardened_runtime                    # Hardened runtime enabled

# Entitlement predicates
macos.entitlement("com.apple.security.network.client")
macos.entitlement_any(["com.apple.security.device.camera", "..."])
macos.category("network")                 # Has any network entitlement
macos.category_any(["camera", "microphone"])
macos.high_risk_entitlements              # Has any high-risk entitlement

# Package receipt predicates
macos.pkg_receipt("com.apple.pkg.Safari")
macos.pkg_receipt("com.apple.pkg.Safari", "17.1")

# Metadata accessors
macos.bundle_id                           # CFBundleIdentifier
macos.team_id                             # Code signing team ID
macos.min_os_version                      # LSMinimumSystemVersion

Example Policy Rules

# Block unsigned third-party apps
rule block_unsigned_apps priority 3 {
  when sbom.any_component(
    macos.bundle_id != "" and
    not macos.signed and
    not macos.bundle_id.startswith("com.apple.")
  )
  then status := "blocked"
  because "Unsigned third-party macOS applications are not permitted."
}

# Warn on high-risk entitlements
rule warn_high_risk_entitlements priority 4 {
  when sbom.any_component(macos.high_risk_entitlements)
  then status := "warn"
  because "Application requests high-risk entitlements (camera, microphone, etc.)."
}

# Require hardened runtime for non-Apple apps
rule require_hardened_runtime priority 5 {
  when sbom.any_component(
    macos.signed and
    not macos.hardened_runtime and
    not macos.bundle_id.startswith("com.apple.")
  )
  then status := "warn"
  because "Third-party apps should enable hardened runtime."
}

Disk Space Requirements

Component Estimated Size Notes
Homebrew core tap snapshot ~400MB Compressed git clone
Homebrew cask tap snapshot ~150MB Compressed git clone
Apple certificate cache ~5MB Root + WWDR chains
CRL/OCSP cache ~10MB Periodic refresh needed
Total ~565MB Per release cycle

Validation Scripts

Verify Offline Readiness

# Check Homebrew mirror integrity
stellaops-cli offline verify-homebrew \
    --mirror /opt/stellaops/mirror/homebrew-core \
    --manifest /opt/stellaops/mirror/homebrew-core.manifest.json

# Verify Apple certificate chain
stellaops-cli offline verify-apple-certs \
    --cache /opt/stellaops/cache/apple-certs \
    --require wwdr

References

  • docs/modules/scanner/design/macos-analyzer.md - Analyzer design specification
  • docs/airgap/mirror-bundles.md - General mirroring patterns
  • Apple Developer Documentation: Code Signing Guide