| name | macos-sandbox |
| description | macOS Sandbox security expert. Use this skill whenever the user asks about macOS sandboxing, sandbox profiles, SBPL, sandbox-exec, container inspection, sandbox extensions, or any macOS security isolation mechanism. Trigger for questions about sandbox bypasses, profile creation, process inspection, or debugging sandboxed applications. |
macOS Sandbox Security
A comprehensive guide to understanding, working with, and debugging macOS Sandbox security mechanisms.
What is macOS Sandbox?
macOS Sandbox (originally called Seatbelt) limits applications to only the allowed actions specified in their Sandbox profile. This ensures applications access only expected resources.
Key facts:
- Any app with entitlement
com.apple.security.app-sandbox runs inside the sandbox
- All App Store apps have this entitlement
- Apple binaries are usually sandboxed
- Uses MACF (Mandatory Access Control Framework) hooks for most syscalls
Core Components
| Component | Path | Purpose |
|---|
| Kernel Extension | /System/Library/Extensions/Sandbox.kext | Core sandbox enforcement |
| Private Framework | /System/Library/PrivateFrameworks/AppSandbox.framework | Sandbox APIs |
| Daemon | /usr/libexec/sandboxd | Userland sandbox manager |
| Containers | ~/Library/Containers | App-specific isolated directories |
Understanding Containers
Every sandboxed application has its own container:
ls -l ~/Library/Containers
cd ~/Library/Containers/{CFBundleIdentifier}
ls -la
Container structure:
.com.apple.containermanagerd.metadata.plist - Container configuration
Data/ - App data directory (mimics home folder structure)
Important: Even with symlinks to Desktop, Downloads, etc., the app needs explicit permissions in the .plist file's RedirectablePaths to access them.
Sandbox Profiles (SBPL)
Sandbox profiles use Sandbox Profile Language (SBPL), based on Scheme:
(version 1) ; Profile version
(deny default) ; Default action when no rule matches
(allow network*) ; Allow all network operations
(allow file-read* ; Allow file reads from:
(subpath "/Users/username/")
(literal "/tmp/afile")
(regex #"^/private/etc/.*")
)
(allow mach-lookup ; Allow specific Mach port
(global-name "com.apple.analyticsd")
)
Common operations:
file* - All file operations
file-read* - File read operations
file-write* - File write operations
process* - Process execution
network* - Network operations
mach-lookup - Mach port access
Creating and Testing Sandbox Profiles
Basic Profile Creation
cat > /tmp/test.sb << 'EOF'
(version 1)
(deny default)
(allow file* (literal "/tmp/test.txt"))
(allow process* (literal "/usr/bin/touch"))
(allow file-read-data (literal "/"))
EOF
sandbox-exec -f /tmp/test.sb /usr/bin/touch /tmp/test.txt
Common Profile Patterns
Minimal network access:
(version 1)
(deny default)
(allow network-client-connect)
(allow file-read* (subpath "~/"))
File server (read-only):
(version 1)
(deny default)
(allow network-server)
(allow file-read* (subpath "/var/www/"))
Development with temp access:
(version 1)
(deny default)
(allow file* (subpath "/tmp/"))
(allow file* (subpath "~/Downloads/"))
(allow process-exec (subpath "/usr/bin/"))
Inspecting Sandboxed Processes
Using sbtool
sbtool <pid> file /tmp
sbtool <pid> mach
sbtool <pid> inspect
sbtool <pid> all
Using log show
log show --style syslog --predicate 'eventMessage contains[c] "sandbox"' --last 30s
log show --predicate 'processImagePath contains "AppName" and eventMessage contains "sandbox"' --last 1h
Container Configuration
plutil -convert xml1 ~/Library/Containers/{bundle-id}/.com.apple.containermanagerd.metadata.plist -o -
Sandbox Tracing
Via Profile
cat > /tmp/trace.sb << 'EOF'
(version 1)
(trace /tmp/trace.out)
EOF
sandbox-exec -f /tmp/trace.sb /bin/ls
cat /tmp/trace.out
Via Command Line
sandbox-exec -t /tmp/trace.out -p "(version 1)" /bin/ls
System Sandbox Profiles
Locations:
/usr/share/sandbox/ - System profiles
/System/Library/Sandbox/Profiles/ - Application profiles
/System/Library/Sandbox/rootless.conf - SIP platform profile
Common profiles:
application.sb - Default App Store app profile
platform.sb - Platform policy (SIP)
*.sb - Various system daemon profiles
Sandbox Extensions
Extensions grant additional privileges to sandboxed processes:
Extension types:
sandbox_extension_issue_file - File access
sandbox_extension_issue_mach - Mach port access
sandbox_extension_issue_iokit_user_client_class - I/O Kit access
sandbox_extension_issue_generic - Generic extension
Key points:
- Extensions are usually granted by allowed processes (e.g.,
tccd for photos)
- Extension tokens are long hex strings encoding permissions
- Tokens can be consumed by multiple processes
- Related to entitlements - some entitlements auto-grant extensions
Debugging Sandbox Issues
Common Problems and Solutions
Problem: Command fails with "deny(1) process-exec*"
Solution: Add (allow process* (literal "/path/to/command"))
Problem: File access denied
Solution: Add appropriate file permission:
(allow file-read-data (literal "/path/to/file"))
(allow file-write-data (literal "/path/to/file"))
Problem: Dynamic library loading fails
Solution: Add dyld and library paths:
(allow file-read-data (literal "/usr/lib/dyld"))
(allow file-read-data (literal "/usr/lib/"))
Debug Workflow
-
Check the denial:
log show --predicate 'eventMessage contains "sandbox"' --last 1m
-
Identify the operation:
process-exec* - Need process permission
file-read-metadata - Need file read permission
file-read-data - Need file data permission
-
Add minimal permission:
Start with (deny default) and add only what's needed
-
Test incrementally:
Add one permission at a time to identify what's required
Security Considerations
Quarantine Attribute
Files created/modified by sandboxed apps get the quarantine attribute, preventing Gatekeeper bypass:
xattr -l /path/to/file | grep com.apple.quarantine
xattr -d com.apple.quarantine /path/to/file
Entitlements
Key entitlements:
com.apple.security.app-sandbox - Enables sandboxing
com.apple.security.network.server - Network server access
com.apple.security.temporary-exception.sbpl - Custom SBPL (Apple-approved only)
keychain-access-groups - Keychain access
SIP Integration
System Integrity Protection uses sandbox:
- Platform profile in
/System/Library/Sandbox/rootless.conf
- Protects system directories
- Cannot be disabled without boot flags
Quick Reference
| Task | Command |
|---|
| Run with profile | sandbox-exec -f profile.sb /path/to/app |
| Run with inline profile | sandbox-exec -p "(version 1)..." /path/to/app |
| Trace sandbox checks | sandbox-exec -t trace.out -f profile.sb /path/to/app |
| Inspect process | sbtool <pid> inspect |
| View sandbox logs | log show --predicate 'eventMessage contains "sandbox"' |
| List containers | ls ~/Library/Containers |
| View container config | plutil -convert xml1 container/.com.apple.containermanagerd.metadata.plist -o - |
Best Practices
- Start restrictive: Begin with
(deny default) and add permissions as needed
- Use literals over wildcards: More specific = more secure
- Test incrementally: Add one permission at a time
- Check logs: Always verify what's being denied
- Document profiles: Comment your SBPL files
- Review extensions: Understand what extensions your app needs
References