Skip to content

Latest commit

 

History

History
196 lines (138 loc) · 5.8 KB

macos-build.md

File metadata and controls

196 lines (138 loc) · 5.8 KB

macOS Build Guide

Alpha: The ESF+NE build path is in Alpha. Build steps, signing requirements, and bundle structure may change between releases.

This guide covers building agentmon for macOS using ESF (Endpoint Security Framework) + NE (Network Extension).

Install via Homebrew

The easiest way to install on macOS:

brew tap canyonroad/tap
brew install --cask agentmon

After installation, approve the system extension in System Settings > General > Login Items & Extensions.

Build Modes

Mode Security Score Requirements Use Case
ESF+NE 90% Xcode 15+ Full enforcement (Alpha)
Observation 25% None Testing, audit-only

ESF+NE Build (Enterprise — Alpha)

ESF+NE provides near-Linux-level enforcement using Apple's Endpoint Security Framework and Network Extension. This build path is in Alpha — expect manual setup steps and breaking changes between releases.

Prerequisites

  1. Xcode 15+ - For building Swift components
  2. Code signing identity - Developer ID or Apple Development certificate
  3. Provisioning profile - With ESF and Network Extension entitlements

Verify Prerequisites

# Check Xcode version
xcodebuild -version
# Should be 15.0 or higher

# Check Swift version
swift --version
# Should be 5.9 or higher

# List code signing identities
security find-identity -v -p codesigning

Build Steps

1. Build Go Binary for macOS

# Build for Apple Silicon (arm64)
make build-macos-go

# This creates, in build/go-local/ (arm64):
# - agentmon             (CGO enabled, `nofuse` tag — required for system extension support)
# - agentmon-shell-shim  (CGO disabled)
# - agentmon-stub        (CGO disabled)

2. Build Swift Components

# Build the System Extension and the approval dialog
make build-swift

# This builds:
# - dev.diffsec.agentmon.SysExt.systemextension
# - approval-dialog.app

3. Assemble App Bundle

# Combine Go + Swift into app bundle
make assemble-bundle

4. Sign the Bundle

# Sign with your Developer ID
SIGNING_IDENTITY="Developer ID Application: Your Name (TEAMID)" make sign-bundle

# Or for development
SIGNING_IDENTITY="Apple Development" make sign-bundle

Full Enterprise Build

# One-command build (requires all prerequisites)
SIGNING_IDENTITY="Developer ID Application" make build-macos-enterprise

The target finishes by running scripts/verify-macos-bundle.sh build/AgentMon.app, which fails the build if the provisioning profiles are missing from the bundle.

Output Structure

build/AgentMon.app/
├── Contents/
│   ├── Info.plist
│   ├── embedded.provisionprofile
│   ├── MacOS/
│   │   ├── agentmon                    # Go binary (CGO, nofuse)
│   │   ├── agentmon-shell-shim
│   │   └── agentmon-stub
│   ├── Library/
│   │   └── SystemExtensions/
│   │       └── dev.diffsec.agentmon.SysExt.systemextension/
│   │           ├── Contents/
│   │           │   ├── MacOS/
│   │           │   │   └── dev.diffsec.agentmon.SysExt  # ESF + NE
│   │           │   ├── embedded.provisionprofile
│   │           │   └── Info.plist
│   └── Resources/
│       └── approval-dialog.app/  # approvals UI (launched in approvals.mode: gui)

System Extension Approval

After installing the ESF+NE app bundle, users must approve the System Extension:

  1. First launch - macOS will prompt "System Extension Blocked"
  2. Open System Settings > General > Login Items & Extensions
  3. Allow the agentmon System Extension
  4. Restart may be required for Network Extension activation

This is a one-time approval per machine.

Graceful Fallback

The ESF+NE binary automatically detects available entitlements:

  1. With ESF + NE entitlements - Uses ESF for file/process, Network Extension for network
  2. Without entitlements - Falls back to observation-only mode

No code changes required - fallback is automatic at runtime.

Troubleshooting

Build Errors

"Xcode not found"

xcode-select --install
sudo xcode-select -s /Applications/Xcode.app

"No signing identity found"

# List available identities
security find-identity -v -p codesigning

# Use a valid identity
SIGNING_IDENTITY="Apple Development: you@email.com (TEAMID)" make sign-bundle

"Entitlement not allowed"

  • Verify the provisioning profile is embedded in the app bundle
  • Network Extension is a standard capability - enable in Xcode Signing & Capabilities

Runtime Errors

"System Extension blocked"

  • User must approve in System Settings > General > Login Items & Extensions

"Failed to connect to policy server"

  • The extension reaches the daemon over its policy socket, at ~/Library/Application Support/agentmon/policy.sock
  • Verify that the daemon is running and that the socket file exists

"ESF client initialization failed"

  • App must be signed with valid ESF entitlement and provisioning profile
  • Check code signing: codesign -dv --entitlements - AgentMon.app

Cross-Compilation

Building macOS binaries from Linux (Go only, not Swift):

GOOS=darwin GOARCH=arm64 CGO_ENABLED=0 go build -o agentmon-darwin-arm64 ./cmd/agentmon

agentmon is Apple Silicon only. darwin/amd64 is not built, released, or tested.

Note: CGO_ENABLED=0 means no ESF support. The binary will run in observation-only mode. Swift components (ESF+NE) must be built on macOS.

See Also