-
Notifications
You must be signed in to change notification settings - Fork 0
Add macOS sandbox support for notifications #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
984cb5b
bdd71b6
7cfce99
4e9631e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,6 +35,7 @@ export interface MacOSSandboxParams { | |
| allowGitConfig?: boolean | ||
| enableWeakerNetworkIsolation?: boolean | ||
| allowClipboard?: boolean | ||
| allowNotifications?: boolean | ||
| binShell?: string | ||
| } | ||
|
|
||
|
|
@@ -332,6 +333,7 @@ function generateSandboxProfile({ | |
| allowGitConfig = false, | ||
| enableWeakerNetworkIsolation = false, | ||
| allowClipboard = false, | ||
| allowNotifications = false, | ||
| logTag, | ||
| }: { | ||
| readConfig: FsReadRestrictionConfig | undefined | ||
|
|
@@ -346,6 +348,7 @@ function generateSandboxProfile({ | |
| allowGitConfig?: boolean | ||
| enableWeakerNetworkIsolation?: boolean | ||
| allowClipboard?: boolean | ||
| allowNotifications?: boolean | ||
| logTag: string | ||
| }): string { | ||
| const profile: string[] = [ | ||
|
|
@@ -367,6 +370,8 @@ function generateSandboxProfile({ | |
| '', | ||
| '; Mach IPC - specific services only (no wildcard)', | ||
| '(allow mach-lookup', | ||
| ' (global-name "com.apple.audio.AudioComponentRegistrar")', | ||
| ' (global-name "com.apple.audio.audiohald")', | ||
| ' (global-name "com.apple.audio.systemsoundserver")', | ||
| ' (global-name "com.apple.distributed_notifications@Uv3")', | ||
| ' (global-name "com.apple.FontObjectsServer")', | ||
|
|
@@ -499,6 +504,21 @@ function generateSandboxProfile({ | |
| ) | ||
| } | ||
|
|
||
| // Notification access - SCOPED TO TERMINAL-NOTIFIER ONLY using signing-identifier | ||
| if (allowNotifications) { | ||
| profile.push( | ||
| '; Notification access - scoped to terminal-notifier via signing-identifier', | ||
| '; Minimal set: only core notification pipeline services', | ||
| '(with-filter (signing-identifier "terminal-notifier")', | ||
| ' (allow mach-lookup', | ||
| ' (global-name "com.apple.usernoted.client")', | ||
| ' (global-name "com.apple.windowserver.active")', | ||
| ' )', | ||
| ')', | ||
| '', | ||
| ) | ||
|
Comment on lines
+507
to
+519
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: On macOS, Seatbelt/App Sandbox policies can match a process by its code signing identifier via the SBPL predicate Why this is spoofable (especially with ad-hoc signing)
Consequence: If a sandbox/Seatbelt rule gates privilege using only What does provide a stronger boundaryTo avoid spoofing, policies/authorization should not rely on identifier alone; they should also bind to something that can’t be forged by ad-hoc signing, such as:
Related: “same identifier” makes components indistinguishableApple documentation notes that giving multiple components the same code signing identifier (via matching 🌐 Web query:
💡 Result: Apple doesn’t publish official/public documentation for SBPL (Seatbelt) filter predicates like What’s available instead:
If you share what exact SBPL snippet you’re looking at (e.g., where you saw Sources Citations:
🌐 Web query:
💡 Result:
Strength (security binding)From strongest (most specific) to weakest (most permissive):
Practical guidance
Sources: Apple Entitlements Troubleshooting (TN2415) [1], Apple Platform Security (team identifier for code validation) [2], Apple Code Signing Requirement Language (the Use certificate-based requirement (Team ID + code signing) instead of
🤖 Prompt for AI Agents |
||
| } | ||
|
|
||
| profile.push( | ||
| '; File I/O on device files', | ||
| '(allow file-ioctl (literal "/dev/null"))', | ||
|
|
@@ -655,6 +675,7 @@ export function wrapCommandWithSandboxMacOS( | |
| allowGitConfig = false, | ||
| enableWeakerNetworkIsolation = false, | ||
| allowClipboard = false, | ||
| allowNotifications = false, | ||
| binShell, | ||
| } = params | ||
|
|
||
|
|
@@ -688,6 +709,7 @@ export function wrapCommandWithSandboxMacOS( | |
| allowGitConfig, | ||
| enableWeakerNetworkIsolation, | ||
| allowClipboard, | ||
| allowNotifications, | ||
| logTag, | ||
| }) | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a way we can add SOME, BUT NOT COMPLETE safety around limiting restrictions to certain processes. With processes that are better signed than terminal-notifier, we can check the signing against a team id. As I mention in the pr description, there is a hole in this security posture, but I deem it acceptable.