211 lines
6.7 KiB
Markdown
211 lines
6.7 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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**
|
|
```bash
|
|
# 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:
|
|
|
|
```spl
|
|
# 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
|
|
|
|
```spl
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|