Last active
July 11, 2026 15:32
-
-
Save PermeationLoop/2a078d6c9e700a8b9128d55dbe0fd932 to your computer and use it in GitHub Desktop.
Put Draw&Guess into macOS Sandbox
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" | |
| echo "Running Draw_Guess in sandbox..." | |
| sandbox-exec -f "$SCRIPT_DIR/game-sandbox.scm" -D HOME="$HOME" "$SCRIPT_DIR/Draw_Guess_launcher" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (version 1) | |
| (deny default) | |
| ;; ============================================================================== | |
| ;; Sandbox Profile — Draw & Guess (Unity / Steam) | |
| ;; ============================================================================== | |
| ;; | |
| ;; Overview: | |
| ;; - Deny-all baseline. Only explicitly listed operations are allowed. | |
| ;; - Designed for a Unity macOS game launched through the Steam client. | |
| ;; - The launch wrapper runs the sandbox with -D HOME="$HOME" so that | |
| ;; all home-directory paths use the (param "HOME") variable below — | |
| ;; no hardcoded usernames. | |
| ;; | |
| ;; Security posture: | |
| ;; - User documents (~/Documents, ~/Desktop, ~/.ssh, ~/.gnupg) are | |
| ;; ***not*** included in any allow rule, so a compromised game process | |
| ;; cannot exfiltrate personal files. | |
| ;; - Network access is broad (online multiplayer game), but all Mach | |
| ;; lookups are scoped to specific global-name / xpc-service-name filters. | |
| ;; - IOKit access is scoped to exactly four user-client classes needed | |
| ;; for GPU rendering, input, and power management. | |
| ;; | |
| ;; Notes for maintainers: | |
| ;; - When Steam updates the app, verify that `app-bundle`, `app-contents`, | |
| ;; and `app-data` still point at the correct beta/stable path. | |
| ;; - To add a new Mach service: grep the sandbox log for "deny(1) | |
| ;; mach-lookup" and scope it with (global-name "...") or | |
| ;; (xpc-service-name "..."). | |
| ;; - To debug future denials: use the iteration workflow documented in | |
| ;; the macos-sandbox-policy skill. | |
| ;; ============================================================================== | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 1. PATH CONFIGURATION | |
| ;; ----------------------------------------------------------------------------- | |
| ;; All home-relative paths are built from (param "HOME") at runtime so the | |
| ;; profile is portable across machines and user accounts. | |
| ;; | |
| ;; app-contents – MacOS & Resources dirs inside the .app bundle (executables) | |
| ;; app-bundle – the .app bundle root (assets, libs) | |
| ;; app-data – Steam-installed game data directory (save files) | |
| ;; app-support – per-app Application Support folder (Unity prefs) | |
| ;; app-log – logging directory (Unity logs) | |
| ;; app-local – XDG-style local data store (Wine compat) | |
| ;; work-save – exported/saved pictures from the drawing game | |
| ;; steam-bundle – Steam client itself (needed for Steamworks API overlays) | |
| ;; ----------------------------------------------------------------------------- | |
| (define home (param "HOME")) | |
| (define app-contents (string-append home "/Library/Application Support/Steam/steamapps/common/Draw & Guess/beta/Draw&Guess.app/Contents")) | |
| (define app-bundle (string-append home "/Library/Application Support/Steam/steamapps/common/Draw & Guess/beta/Draw&Guess.app")) | |
| (define app-data (string-append home "/Library/Application Support/Steam/steamapps/common/Draw & Guess")) | |
| (define app-support (string-append home "/Library/Application Support/com.Acureus.DrawGuess")) | |
| (define app-log (string-append home "/Library/Logs/Acureus")) | |
| (define app-local (string-append home "/.local/share/Draw&Guess")) | |
| (define work-save (string-append home "/Pictures/Draw&Guess")) | |
| (define home-fonts (string-append home "/Library/Fonts")) | |
| (define app-pref-plist (string-append home "/Library/Preferences/com.Acureus.DrawGuess.plist")) | |
| (define steam-bundle (string-append home "/Library/Application Support/Steam/Steam.AppBundle")) | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 2. PROCESS CONTROL | |
| ;; ----------------------------------------------------------------------------- | |
| ;; fork – needed for NSTask / posix_spawn and Steam child processes. | |
| ;; exec – allows launching binaries from within the app bundle only. | |
| ;; ----------------------------------------------------------------------------- | |
| (allow process-fork) | |
| (allow process-exec | |
| (subpath app-contents)) | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 3. SYSTEM-LEVEL OPERATIONS | |
| ;; ----------------------------------------------------------------------------- | |
| ;; sysctl-read – kernel version, page-size, host-info queries (safe). | |
| ;; system-fsctl – filesystem ioctl commands issued by dyld & frameworks. | |
| ;; Each _IO command is a specific operation; blanket allow | |
| ;; would be dangerous, so these are scoped. | |
| ;; iokit-open-user-client – GPU rendering (IOSurface, AGX), input (IOHIDParam), | |
| ;; and power-management / prevent-sleep (RootDomain). | |
| ;; ----------------------------------------------------------------------------- | |
| (allow sysctl-read) | |
| (allow system-fsctl | |
| (fsctl-command (_IO "J" 102)) ;; dyld shared-cache map | |
| (fsctl-command (_IO "J" 67)) ;; dyld shared-cache verification | |
| (fsctl-command (_IO "h" 47))) ;; HFS / APFS volume status query | |
| (allow iokit-open-user-client | |
| (iokit-user-client-class "RootDomainUserClient") ;; power management / sleep prevention | |
| (iokit-user-client-class "IOHIDParamUserClient") ;; keyboard & mouse parameter tuning | |
| (iokit-user-client-class "IOSurfaceRootUserClient") ;; GPU framebuffer / texture sharing | |
| (iokit-user-client-class "AGXDeviceUserClient")) ;; Apple GPU command submission | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 4. PREFERENCES (CFPreferences / User Defaults) | |
| ;; ----------------------------------------------------------------------------- | |
| ;; user-preference-read/write – Use preference-domain filters (NEVER literal). | |
| ;; com.acureus.drawguess – the game's own preference domain | |
| ;; kcfpreferencesanyapplication – read any app's preferences (needed by Steam overlay) | |
| ;; com.apple.hitoolbox – keyboard layout / input source configs | |
| ;; ----------------------------------------------------------------------------- | |
| (allow user-preference-read user-preference-write | |
| (preference-domain "com.acureus.drawguess")) | |
| (allow user-preference-read | |
| (preference-domain "kcfpreferencesanyapplication") | |
| (preference-domain "com.apple.hitoolbox")) | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 5. FILESYSTEM — METADATA | |
| ;; ----------------------------------------------------------------------------- | |
| ;; file-read-metadata – stat() / lstat() calls that read inode info but NOT | |
| ;; file contents. Safe to allow broadly on system dirs. | |
| ;; ----------------------------------------------------------------------------- | |
| (allow file-read-metadata) | |
| (allow file-read-metadata | |
| (subpath "/var") | |
| (subpath "/etc") | |
| (subpath "/private/var") | |
| (subpath "/private/etc") | |
| (subpath "/usr")) | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 6. FILESYSTEM — READ / WRITE | |
| ;; ----------------------------------------------------------------------------- | |
| ;; Device files – /dev/null, /dev/zero, /dev/urandom, /dev/random | |
| ;; System temp – /private/var/folders (per-user Darwin temp dirs) | |
| ;; App-owned paths – preferences plist, game data, logs, saves, exports | |
| ;; | |
| ;; IMPORTANT: No read access to ~/Documents, ~/Desktop, ~/.ssh, or ~/.gnupg. | |
| ;; This is the primary data-exfiltration defence. | |
| ;; ----------------------------------------------------------------------------- | |
| (allow file-read* file-write* | |
| (literal "/dev/null") | |
| (literal "/dev/zero") | |
| (literal "/dev/urandom") | |
| (literal "/dev/random") | |
| (subpath "/private/var/folders") ;; Darwin user temp directory | |
| (literal app-pref-plist) ;; game preferences plist | |
| (subpath app-data) ;; Steam game data | |
| (subpath app-log) ;; Unity player logs | |
| (subpath app-local) ;; XDG local data | |
| (subpath app-support) ;; Application Support | |
| (subpath work-save)) ;; exported pictures | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 7. FILESYSTEM — READ-ONLY (Libraries, Frameworks, Fonts) | |
| ;; ----------------------------------------------------------------------------- | |
| ;; These paths are essential for loading system frameworks, dynamic libraries, | |
| ;; fonts, and the app's own resources. None contain user documents. | |
| ;; ----------------------------------------------------------------------------- | |
| (allow file-read* | |
| ;; macOS system | |
| (subpath "/System") ;; /System/Library/Frameworks etc. | |
| (subpath "/usr/lib") ;; system dynamic libraries | |
| (subpath "/usr/share") ;; locale, terminfo, zoneinfo | |
| (subpath "/private/var/db/dyld") ;; dyld shared cache | |
| (subpath "/Library/Apple/usr") ;; Apple internal libs | |
| ;; App & Steam bundles | |
| (subpath app-bundle) ;; .app bundle: Frameworks, PlugIns, Resources | |
| (subpath steam-bundle) ;; Steam client bundle (overlay) | |
| ;; Fonts | |
| (subpath "/Library/Fonts") ;; system fonts | |
| (subpath home-fonts) ;; user-installed fonts | |
| ;; Root & timezone (read-metadata / read-xattr only would suffice, | |
| ;; but root-dir listing is needed by some frameworks) | |
| (literal "/") | |
| (subpath "/private/var/db/timezone")) | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 8. FILESYSTEM — ADDITIONAL READ-DATA PERMISSIONS | |
| ;; ----------------------------------------------------------------------------- | |
| ;; Preferences – system and user preference plist files | |
| ;; Input Methods – /Library/Input Methods (system IMEs) and | |
| ;; ~/Library/Input Methods (user-installed IMEs like Squirrel). | |
| ;; Required for CJK and other non-Latin text input. | |
| ;; Audio Plug-Ins – HAL audio drivers for capture/monitoring devices | |
| ;; Eligibility – system eligibility DB (OS feature flags) | |
| ;; Caches – user caches (icon cache, etc.) | |
| ;; mds – Spotlight metadata server messages | |
| ;; ----------------------------------------------------------------------------- | |
| (allow file-read-data | |
| (subpath (string-append home "/Library/Preferences")) ;; user prefs | |
| (subpath "/Library/Preferences") ;; system prefs | |
| ;; IME / Input Methods — CRITICAL for non-English keyboard input | |
| (subpath "/Library/Input Methods") | |
| (subpath (string-append home "/Library/Input Methods")) | |
| (literal "/private/var/db/eligibilityd/eligibility.plist") ;; system eligibility | |
| (literal (string-append home "/Library/Caches")) ;; user caches | |
| (subpath "/Library/Audio/Plug-Ins") ;; audio HAL drivers | |
| (subpath "/private/var/db/mds")) ;; Spotlight messages | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 9. NETWORK & IPC | |
| ;; ----------------------------------------------------------------------------- | |
| ;; signal – POSIX signals (SIGTERM, SIGINT, etc.) | |
| ;; ipc-posix-shm-* – POSIX shared memory (Darwin notification center, | |
| ;; AppleDatabaseChanged for disk arbitration) | |
| ;; system-socket – local IPC socket (domain AF_LOCAL=32, type SOCK_STREAM=2) | |
| ;; network* – full network access (required for online multiplayer). | |
| ;; If the game only needs outbound, scope with (remote ip ...) | |
| ;; ----------------------------------------------------------------------------- | |
| (allow signal) | |
| (allow ipc-posix-shm-read* | |
| (ipc-posix-name "apple.shm.notification_center")) | |
| (allow ipc-posix-shm-read* ipc-posix-shm-write* | |
| (ipc-posix-name "com.apple.AppleDatabaseChanged")) | |
| (allow system-socket | |
| (socket-domain 32) ;; AF_LOCAL / AF_UNIX | |
| (socket-type 2)) ;; SOCK_STREAM | |
| (allow network*) | |
| ;; ----------------------------------------------------------------------------- | |
| ;; 10. MACH SERVICES (Lookup & Registration) | |
| ;; ----------------------------------------------------------------------------- | |
| ;; global-name – bootstrap-registered Mach services | |
| ;; xpc-service-name – XPC services (launched on demand by launchd) | |
| ;; local-name – per-process Mach ports the app registers itself | |
| ;; | |
| ;; Grouped by subsystem for readability. | |
| ;; ----------------------------------------------------------------------------- | |
| (allow mach-lookup | |
| ;; === Logging & Diagnostics === | |
| (global-name "com.apple.logd") | |
| (global-name "com.apple.logd.events") | |
| (global-name "com.apple.diagnosticd") | |
| (global-name "com.apple.analyticsd") | |
| ;; === Window Server & Rendering === | |
| (global-name "com.apple.windowserver.active") ;; connection to WindowServer | |
| (global-name "com.apple.windowmanager.server") ;; window management | |
| (global-name "com.apple.window_proxies") ;; window proxy ports | |
| (global-name "com.apple.CARenderServer") ;; Core Animation render server | |
| (global-name "com.apple.dock.server") ;; Dock integration | |
| (global-name "com.apple.dock.fullscreen") ;; fullscreen transitions | |
| (xpc-service-name "com.apple.ViewBridgeAuxiliary") ;; NSView bridging | |
| ;; === Metal / GPU === | |
| (xpc-service-name "com.apple.MTLCompilerService") ;; Metal shader compilation | |
| ;; === HID / Input === | |
| (global-name "com.apple.iohideventsystem") ;; IOHID event system | |
| (global-name "com.apple.backboard.hid-services.xpc") ;; backboard HID relay | |
| (xpc-service-name "com.apple.backboard.BKSEndpointProviderService") ;; event dispatcher | |
| ;; === Text Input / IME === | |
| (xpc-service-name "com.apple.TextInputUI.xpc.CursorUIViewService") ;; candidate window | |
| (global-name "com.apple.inputmethodkit.connection") ;; IMK connection broker | |
| (global-name "com.apple.inputmethodkit.getxpcendpoint") ;; IMK XPC endpoint | |
| (global-name "com.apple.inputmethodkit.launchagent") ;; IMK daemon launcher | |
| (global-name "com.apple.inputmethodkit.launcher") ;; IMK per-app launcher | |
| (xpc-service-name "com.apple.inputmethodkit.xpc.servicemanager") ;; IMK service manager | |
| (global-name "com.apple.tsm.uiserver") ;; Text Services Manager UI | |
| ;; === Audio === | |
| (global-name "com.apple.audio.audiohald") ;; Core Audio HAL daemon | |
| (global-name "com.apple.audio.AudioComponentRegistrar") ;; AudioUnit registry | |
| (global-name "com.apple.audio.AudioSession") ;; audio session management | |
| (global-name "com.apple.audioanalyticsd") ;; audio analytics | |
| (xpc-service-name "com.apple.audio.SandboxHelper") ;; audio sandbox IPC | |
| ;; === System Configuration & Directory === | |
| (global-name "com.apple.SystemConfiguration.configd") ;; network config, hostname | |
| (global-name "com.apple.system.opendirectoryd.libinfo") ;; user/group lookups | |
| (global-name "com.apple.system.opendirectoryd.membership") ;; group membership | |
| (global-name "com.apple.system.notification_center") ;; CFNotificationCenter | |
| (global-name "com.apple.distributed_notifications@Uv3") ;; distributed notifications | |
| (global-name "com.apple.bsd.dirhelper") ;; directory helper | |
| ;; === Power Management === | |
| (global-name "com.apple.PowerManagement.control") ;; prevent sleep, power events | |
| ;; === Launch Services === | |
| (global-name "com.apple.coreservices.launchservicesd") ;; app registration / URL handling | |
| (global-name "com.apple.lsd.mapdb") ;; LaunchServices database (read) | |
| (global-name "com.apple.lsd.open") ;; open URLs / files | |
| (global-name "com.apple.lsd.modifydb") ;; LaunchServices database (write) | |
| (global-name "com.apple.lsd.advertisingidentifiers") ;; ad identifier | |
| ;; === Disk Arbitration === | |
| (global-name "com.apple.DiskArbitration.diskarbitrationd") ;; volume mount/unmount events | |
| ;; === Security & Privacy === | |
| (global-name "com.apple.SecurityServer") ;; keychain, code-signing | |
| (global-name "com.apple.trustd.agent") ;; certificate trust evaluation | |
| (global-name "com.apple.tccd") ;; privacy consent daemon | |
| (global-name "com.apple.tccd.system") ;; system TCC | |
| (global-name "com.apple.coreservices.quarantine-resolver") ;; file quarantine | |
| (global-name "com.apple.cmio.registerassistantservice.system-extensions") ;; camera access | |
| ;; === Apple Events === | |
| (global-name "com.apple.coreservices.appleevents") ;; AppleEvents (AppleScript IPC) | |
| (global-name "com.apple.CoreServices.coreservicesd") ;; CoreServices broker | |
| ;; === Miscellaneous System === | |
| (global-name "com.apple.appkit.restoration_storage") ;; NSWindow state restoration | |
| (global-name "com.apple.touchbarserver.mig") ;; Touch Bar server | |
| (global-name "com.apple.fonts") ;; font registration | |
| (global-name "com.apple.spotlight.IndexAgent") ;; Spotlight metadata | |
| (global-name "com.apple.storekitagent") ;; StoreKit IAP | |
| (global-name "com.apple.uiintelligencesupport.agent") ;; Apple Intelligence | |
| (global-name "com.apple.pasteboard.1") ;; clipboard (system pasteboard) | |
| (global-name "com.apple.mDNSResponder") ;; multicast DNS / Bonjour | |
| ;; === Game Controller === | |
| (global-name "com.apple.GameController.gamecontrollerd.app") | |
| ;; === Steam Integration === | |
| (global-name "com.valvesoftware.steam.ipctool") ;; Steam IPC tool | |
| (global-name "com.valvesoftware.steam.other") ;; Steam secondary IPC | |
| ;; === Safari / WebKit (used by Steam overlay) === | |
| (xpc-service-name "com.apple.SafariPlatformSupport.Helper") | |
| (xpc-service-name "com.apple.hiservices-xpcservice")) | |
| ;; Allow opening files / URLs via LaunchServices (Opening broser uses this). | |
| (allow lsopen) | |
| (allow ipc-sysv-sem) | |
| (allow file-issue-extension | |
| (extension-class "com.apple.app-sandbox.read")) | |
| ;; === Mach Port Registration (per-process) === | |
| ;; local-name ports are registered by the sandboxed process itself. | |
| (allow mach-register | |
| (local-name "com.apple.tsm.portname") ;; Text Services Manager (IME input) | |
| (local-name "com.apple.axserver") ;; Accessibility server | |
| (local-name "com.apple.coredrag")) ;; drag-and-drop clipboard |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment