Skip to content

Add permissive-ipc guard and built-in xcode capability#4

Draft
nithyanatarajan wants to merge 6 commits intojskswamy:mainfrom
nithyanatarajan:feat/permissive-ipc-and-xcode-capability
Draft

Add permissive-ipc guard and built-in xcode capability#4
nithyanatarajan wants to merge 6 commits intojskswamy:mainfrom
nithyanatarajan:feat/permissive-ipc-and-xcode-capability

Conversation

@nithyanatarajan
Copy link
Copy Markdown

Summary

  • Add enable_guard field to CapabilityDef so user-defined capabilities can activate opt-in guards from YAML config
  • Add permissive-ipc guard — reusable opt-in guard that broadly allows non-filesystem operations (Mach lookups, IOKit, signals, notifications,
    preferences, job creation, fsctl)
  • Add xcode-simulator guard — Xcode-specific home directory filesystem paths
  • Register both guards in the guard registry
  • Add built-in xcode capability that enables both guards, activated via --with xcode
  • Auto-detect Xcode projects (.xcodeproj, .xcworkspace, Package.swift with platform markers)

Motivation

Complex toolchains like Xcode use dozens of Mach services, IOKit classes, and IPC operations that vary by version. Enumerating them individually is
impractical — filesystem paths are the real security boundary. The permissive-ipc guard captures this insight and is reusable by any capability.

Test plan

  • All existing tests pass
  • 10 tests for permissive-ipc guard
  • 5 tests for xcode-simulator guard
  • Registry tests updated (14 guards, 3 opt-in)
  • Built-in xcode capability test
  • 5 Xcode detection tests
  • Verified sandbox profile and guard listing

nithyanatarajan and others added 6 commits March 31, 2026 13:09
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jskswamy
Copy link
Copy Markdown
Owner

jskswamy commented Apr 1, 2026

Review: Extend the capability model instead of adding guards

The permissive-ipc guard works mechanically, but architecturally it's doing something different from every other guard — it only opens permissions rather than restricting them. Every existing capability (k8s, docker, ssh, aws, etc.) declares what it needs via Readable, Writable, and EnvAllow, and the existing filesystem guard translates those into Seatbelt rules. No capability today creates a guard.

The issue is that the capability model currently only has vocabulary for filesystem and env operations. There's no field for "allow mach-lookup" or "allow iokit-open".


Update: Allow field is now implemented on main

The capability model enhancement has been merged to main in two commits:

  • 9a2178b — Add Allow []string field through the full chain: CapabilityDefCapabilityResolvedCapabilitySandboxOverridesSandboxPolicyPolicyContext
  • 5142df4 — Filesystem guard reads ctx.ExtraAllow and emits (allow <op>) Seatbelt rules

What this means for this PR

Rebase onto main to pick up the new Allow field, then rewrite the xcode capability in builtin.go:

"xcode": {
    Name:        "xcode",
    Description: "Xcode, Simulator, and xcodebuild",
    Writable: []string{
        "/Applications/Xcode.app",
        "~/Library/Logs/CoreSimulator",
        "~/Library/Developer",
        "~/Library/Caches/com.apple.dt.Xcode",
        "~/Library/org.swift.swiftpm",
        "~/.swiftpm",
    },
    Readable: []string{
        "~/Library/Preferences",
        "~/.CFUserTextEncoding",
    },
    Allow: []string{
        "mach-lookup", "iokit-open", "signal", "job-creation",
        "distributed-notification-post", "user-preference-read",
        "user-preference-write", "system-fsctl",
    },
},

What to keep

  • Auto-detection logic (.xcodeproj, .xcworkspace, Package.swift with platform markers) — great work
  • enable_guard on CapabilityDef (YAML schema) — this PR added it so users can reference opt-in guards from .aide.yaml. That's useful for guards with runtime logic (like git-remote which inspects SSH_AUTH_SOCK, checks filesystem existence, emits conditional rules). EnableGuard on the Go Capability struct already existed since v1.4.0 for git-remote; this PR just exposed it to YAML config.

What to remove

  • permissive-ipc guard — a static list of allow statements with no runtime logic. The Allow field on capabilities does the same thing declaratively.
  • xcode-simulator guard — a static list of filesystem paths. Those go directly into Writable/Readable on the capability.
  • EnableGuard: []string{"permissive-ipc", "xcode-simulator"} from the xcode builtin — replaced by Allow and Writable/Readable above.

The distinction

Guards with runtime logic (env var inspection, filesystem checks, conditional rules, diagnostics) belong as guards activated via enable_guard. Static lists of operations or paths belong on the capability directly via Allow, Writable, Readable.

@jskswamy jskswamy marked this pull request as draft April 1, 2026 02:47
@jskswamy jskswamy self-requested a review April 1, 2026 02:48
@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Apr 1, 2026

Greptile Summary

This PR introduces a permissive-ipc opt-in guard (broad non-filesystem IPC allowances), an xcode-simulator opt-in guard (Xcode home-directory filesystem paths), and a built-in xcode capability that activates both — filling a practical gap for users working on iOS/macOS/Swift projects where exhaustively enumerating Mach services or IOKit classes is infeasible.

Key changes:

  • CapabilityDef.EnableGuard added to both the config schema and the capability struct, allowing YAML-defined capabilities to activate opt-in guards
  • permissive-ipc guard allows mach-lookup, iokit-open, signal, job-creation, distributed-notification-post, user-preference-read/write, and system-fsctl; filesystem and network boundaries are explicitly left to other guards
  • xcode-simulator guard grants file-read* file-write* subpath access to ~/Library/Developer, ~/Library/Preferences, ~/Library/Caches/com.apple.dt.Xcode, ~/Library/org.swift.swiftpm, ~/.swiftpm, and the .CFUserTextEncoding literal
  • Built-in xcode capability also lists /Applications/Xcode.app and ~/Library/Logs/CoreSimulator as Writable paths; the prior review flagged that /Applications/Xcode.app should be Readable — this remains unresolved
  • Auto-detection in DetectProject recognises .xcodeproj/.xcworkspace directory packages and Package.swift files containing Apple platform markers (.iOS, .macOS, .watchOS, .tvOS, .visionOS)
  • Test coverage is solid: 10 tests for permissive-ipc, 5 for xcode-simulator, 5 for Xcode detection, registry totals updated

Confidence Score: 4/5

Mostly safe to merge; one unresolved prior issue (/Applications/Xcode.app listed as Writable) and one new P2 suggestion on ~/Library/Preferences write scope remain

The architecture is sound and well-tested. The /Applications/Xcode.app Writable issue flagged in the previous review is not yet addressed. There is one new P2 suggestion (scoping ~/Library/Preferences writes). Neither of these are blockers for the primary user path, but the Xcode.app writable grant is a meaningful security mis-classification that should be fixed before merge.

internal/capability/builtin.go (/Applications/Xcode.app should be Readable) and pkg/seatbelt/guards/guard_xcode_simulator.go (~/Library/Preferences write scope)

Important Files Changed

Filename Overview
internal/capability/builtin.go Adds built-in xcode capability with EnableGuard for permissive-ipc and xcode-simulator; /Applications/Xcode.app is listed as Writable (flagged in prior review — should be Readable)
pkg/seatbelt/guards/guard_permissive_ipc.go New opt-in guard broadly allowing non-filesystem IPC operations; (allow signal) and (allow job-creation) breadth was flagged in prior review; design trade-off is explicitly documented in the package comment
pkg/seatbelt/guards/guard_xcode_simulator.go New opt-in guard granting Xcode home-directory filesystem access; ~/Library/Preferences subpath write is broader than needed and could allow modifying any application's preferences
internal/capability/detect.go Adds Xcode project auto-detection via .xcodeproj/.xcworkspace directory extension and Package.swift platform marker substrings; hasDirWithExtension correctly handles the directory-package nature of .xcodeproj
internal/config/schema.go Adds EnableGuard field to CapabilityDef with yaml:"enable_guard,omitempty"; straightforward schema extension
internal/capability/config.go Passes EnableGuard through from YAML config def to capability struct; simple, complete wiring change
pkg/seatbelt/guards/registry.go Registers PermissiveIPCGuard and XcodeSimulatorGuard in the opt-in section of the guard registry; correct placement

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["--with xcode<br/>or auto-detect (.xcodeproj / Package.swift)"] --> B["builtin xcode capability"]
    B --> C["Writable: /Applications/Xcode.app<br/>Writable: ~/Library/Logs/CoreSimulator"]
    B --> D["EnableGuard: permissive-ipc"]
    B --> E["EnableGuard: xcode-simulator"]

    D --> F["permissive-ipc guard (opt-in)"]
    F --> F1["(allow mach-lookup)"]
    F --> F2["(allow iokit-open)"]
    F --> F3["(allow signal)"]
    F --> F4["(allow job-creation)"]
    F --> F5["(allow distributed-notification-post)"]
    F --> F6["(allow user-preference-read/write)"]
    F --> F7["(allow system-fsctl)"]

    E --> G["xcode-simulator guard (opt-in)"]
    G --> G1["file-read* file-write*<br/>~/Library/Developer"]
    G --> G2["file-read* file-write*<br/>~/Library/Preferences ⚠️"]
    G --> G3["file-read* file-write*<br/>~/Library/Caches/com.apple.dt.Xcode"]
    G --> G4["file-read* file-write*<br/>~/Library/org.swift.swiftpm<br/>~/.swiftpm"]
    G --> G5["file-read* file-write*<br/>~/.CFUserTextEncoding"]
Loading

Reviews (2): Last reviewed commit: "Auto-detect Xcode projects and suggest x..." | Re-trigger Greptile

Comment on lines +152 to +154
Writable: []string{
"/Applications/Xcode.app",
"~/Library/Logs/CoreSimulator",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 /Applications/Xcode.app should be Readable, not Writable

/Applications/Xcode.app is listed under Writable, which grants the sandboxed agent write access to the entire Xcode application bundle — including its toolchain binaries, SDK headers, and frameworks. Normal Xcode build operations never need to write into the application bundle itself; artifacts go to ~/Library/Developer/Xcode/DerivedData (already covered by xcode-simulator guard's ~/Library/Developer subpath), simulator data to ~/Library/Developer/CoreSimulator, and caches to ~/Library/Caches/com.apple.dt.Xcode. Granting write access here would allow the agent to modify the Xcode IDE installation.

This path should be Readable (or even omitted if the toolchain executables are accessed via xcrun//usr/bin symlinks rather than directly from the app bundle):

Suggested change
Writable: []string{
"/Applications/Xcode.app",
"~/Library/Logs/CoreSimulator",
Readable: []string{
"/Applications/Xcode.app",
},
Writable: []string{
"~/Library/Logs/CoreSimulator",
},

Comment on lines +44 to +46
seatbelt.SectionAllow("Process control"),
seatbelt.AllowRule("(allow signal)"),
seatbelt.AllowRule("(allow job-creation)"),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 (allow signal) and (allow job-creation) are broader than necessary

(allow signal) without a target qualifier permits sending any signal to any process on the system, not just the agent's own children. Xcode toolchain processes (compiler workers, simulator daemons) only need to signal their own child processes. Apple's SBPL supports scoping this with (target children):

(allow signal (target children))

Similarly, (allow job-creation) allows registering arbitrary persistent launchd jobs, which survive beyond the sandbox session. If the intent is only to allow spawning sub-processes for xcodebuild/simctl, a more targeted rule would reduce the blast radius.

Since this guard is explicitly opt-in and named "permissive", this is a heads-up rather than a blocker, but it's worth documenting the decision in a comment so future readers understand why the broad form was chosen over scoped alternatives.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants