Complete guide to configuring ClearanceKit's file access policies, app protections, jail rules, process ancestry, allowlists, and MDM deployment.
After dragging ClearanceKit to your Applications folder, open it and navigate to the Setup tab in the sidebar. Two steps are required:
opfilter system extension. Click the link in the Setup tab to open System Settings → Privacy & Security → Full Disk Access, and enable opfilter.The Setup tab shows real-time connection status. A green indicator means the GUI is connected to the system extension via XPC. If it shows red, click Resync.
The system extension runs independently of the GUI app. Closing the GUI does not stop enforcement. To update the extension after installing a new version of ClearanceKit, open Setup and click Update Extension. If jail rules are active, a warning dialog lists all currently jailed processes and explains that enforcement will pause briefly during the update.
A typical workflow for protecting an application's data:
The Events tab shows a live feed of file access events processed by the system extension.
Each event row shows the file path, the decision (allowed or denied), a timestamp, and the operation type if it is not a file open (rename, unlink, create, truncate, copy, readdir, link, exchangedata, or clone). Click a row to expand it and see:
When viewing an expanded denied event, code signatures for the process and its ancestors appear as clickable links. Clicking a signature opens a dialog to add it to the global allowlist or as an allowed process for the relevant rule. This is the fastest way to build policy from observed behaviour.
// note: Baseline and managed events. Events matched by baseline (built-in Apple process) or managed (MDM-delivered) rules are collapsed into compact rows with a baseline or managed badge. Expand them to see the full decision context.
The Processes tab provides two views of active enforcement:
A hierarchical tree of all processes currently confined by jail rules. Each entry shows:
Processes grouped by signing identity that have been denied file access by policy rules. Each group shows the process name, Team ID, Signing ID, and event count. Expand a group to see individual denied events. Click the + button to add the process to the global allowlist.
Use Clear Inactive in the toolbar to remove entries for processes that have exited.
A searchable, sortable table of every running process known to the system extension. Columns include PID, PPID, process name, executable path, Signing ID, Team ID, UID, and GID. Search by any of these fields.
Click any process row to open a wizard sheet with three options:
Real-time performance dashboard for the system extension's event pipeline.
Five gauges show 10-second rolling averages and peak rates:
A 60-second rolling chart plots events per second for each category, letting you correlate spikes in file access with specific activity on your machine.
Policy rules are the core building block of ClearanceKit. Each rule protects a path prefix and specifies which processes are allowed to access files under it.
| Tier | Source | Editable |
|---|---|---|
baseline | Compiled into the app | No |
managed | Delivered via MDM configuration profile | No |
| User | Created in the GUI | Yes |
All tiers are active simultaneously. Rules are evaluated in merged order; the first matching rule determines the outcome.
| Field | Description |
|---|---|
protectedPathPrefix | The path pattern to protect. Supports wildcards. Any file access under this prefix triggers policy evaluation. |
allowedProcessPaths | Exact executable paths that are allowed. No wildcards. |
allowedSignatures | Code signatures (Team ID + Signing ID) that are allowed. |
allowedAncestorProcessPaths | If any ancestor in the process chain has this exact executable path, access is allowed. |
allowedAncestorSignatures | If any ancestor has a matching code signature, access is allowed. |
If all allowed* fields are empty, only processes on the global allowlist can access files under the protected path — every other process is denied. If a file matches the protected path and at least one criterion is defined, but no criterion matches the process, access is denied.
/Users/*/Library/Safari).The Policy tab toolbar has Import Rules and Export Rules buttons. Rules are serialised as JSON. This lets you share rule sets between machines without MDM, or back up your configuration.
App Protections group related policy rules under a named application. Instead of managing individual rules, you enable or disable protection for an entire app with a single toggle.
Navigate to App Protections. The Built-in section lists all presets. Toggle any preset on to immediately protect that app's data. Touch ID is required.
If a preset shows update available, its active rules have drifted from the built-in definition — either because a newer version of ClearanceKit ships updated rules, or because you have modified the preset's rules manually. Click Update to reset the preset to the current built-in definition, or use Update All in the toolbar.
.app from Finder onto the list).When ClearanceKit cannot auto-detect an app's file paths, a 60-second discovery session begins. During this session:
In the review screen, you can remove paths that should not be protected and add allowed processes for each path. Click Create Protection to save.
Click the edit button on any custom app protection to modify its protected paths, add or remove allowed process signatures, or delete individual path entries.
ClearanceKit ships with curated presets for popular applications. Each preset protects the app's local data directories and allows only the app's own processes (identified by code signature) to access them.
| Preset | Protected paths | Rules |
|---|---|---|
| Safari |
~/Library/Safari~/Library/Containers/com.apple.Safari~/Library/Group Containers/group.com.apple.safari
|
3 |
~/Library/Mail~/Library/Containers/com.apple.mail~/Library/Group Containers/group.com.apple.mail.shared
|
3 | |
| Messages | ~/Library/Messages |
1 |
| Contacts |
~/Library/Application Support/AddressBook~/Library/Containers/com.apple.AddressBook
|
2 |
| Notes | ~/Library/Group Containers/group.com.apple.notes |
1 |
| Signal | ~/Library/Application Support/Signal |
1 |
| Slack |
~/Library/Application Support/Slack~/Library/Caches/com.tinyspeck.slackmacgap
|
2 |
| Discord |
~/Library/Application Support/discord~/Library/Caches/com.hnc.Discord~/Library/Caches/com.hnc.Discord.ShipIt
|
3 |
| Chrome |
~/Library/Application Support/Google~/Library/Caches/Google
|
2 |
| HEY | ~/Library/Application Support/HEY |
1 |
| Mullvad VPN | ~/Library/Application Support/Mullvad VPN |
1 |
// note: Path notation. Paths shown as ~/Library/... are stored as /Users/*/Library/... in the actual rules, using the * wildcard to match any username.
Each preset allows access only to processes signed by the app's developer. For example, the Safari preset allows apple:com.apple.Safari, apple:com.apple.WebKit.WebContent, apple:com.apple.Safari.History, and other Apple-signed Safari components. A trojanised binary or unrelated process attempting to read Safari's cookies will be denied.
Jail rules confine a process to a specific set of path prefixes. Unlike policy rules (which protect specific paths from unauthorised processes), jail rules restrict where a jailed process can access anything at all. Any file access outside the allowed set is denied, regardless of other policy rules.
// warning: Wildcards are not supported in jail signatures. The jailed process signature must be exact. You cannot use * as the Signing ID in a jail rule. Wildcards are supported in the allowed path prefixes.
Allowed path prefixes in jail rules support three wildcard patterns:
| Pattern | Meaning | Example |
|---|---|---|
* |
Matches any single path component (does not cross /) |
/Users/*/Documents matches /Users/alice/Documents |
** |
Matches zero or more path components at any depth | /tmp/** matches /tmp/foo/bar/baz |
*** |
Matches any characters within a single path component (suffix/prefix matching) | /dev/ttys*** matches /dev/ttys001, /dev/ttysA |
The Jail tab has an Import / Export button. Select which rules to export, then save as JSON. Import rules from a JSON file on another machine.
The global allowlist is a list of processes that bypass all policy rules entirely. Any process matching an allowlist entry is allowed to access any file, regardless of policy rules or jail rules.
| Tier | Source | Editable |
|---|---|---|
baseline | 34 essential Apple system processes (Finder, Spotlight, apfsd, etc.) compiled into the app | No |
managed | Delivered via MDM configuration profile | No |
| User | Created in the GUI | Yes |
In addition to the compiled baseline, ClearanceKit automatically discovers XProtect remediator executables at startup and adds them to the allowlist. It also monitors for XProtect updates and refreshes the allowlist entries to ensure Apple's malware remediation is never impeded.
Each allowlist entry matches by one of two criteria:
* as the Signing ID to match any app from a specific team.An entry can also be marked as Platform Binary, which restricts it to Apple-signed binaries only.
In addition to the regular allowlist, ClearanceKit supports ancestor allowlist entries. These match against any process in the calling chain, not just the immediate process. If any ancestor matches, the immediate process bypasses all policy rules.
This is useful for:
Add ancestor entries via the Add Ancestor Entry button in the Allowlist toolbar.
If you run other endpoint security or network monitoring tools alongside ClearanceKit, add them to the global allowlist. These products need to inspect files across the entire file system to function correctly, and ClearanceKit's policy rules will otherwise block them from reading protected paths.
// warning: Add your security tools to the allowlist. Without an allowlist entry, security products will be denied access to files in protected directories, which may prevent them from detecting threats or monitoring network connections associated with those files.
Common examples:
| Product | Signing ID | Team ID |
|---|---|---|
| BlockBlock | com.objective-see.blockblock | VBG97UB4TA |
| Little Snitch Network Monitor | at.obdev.littlesnitch.networkmonitor | MLZF7K7B5R |
To add one of these, navigate to Allowlist, click Add Entry, select Signing ID, enter the Signing ID and Team ID from the table above, and save. You can also use the Pick from running processes button to find other security products running on your machine and add them directly.
Different parts of ClearanceKit support different wildcard syntax. This table summarises what is available where.
The protectedPathPrefix field supports glob-style wildcards:
| Pattern | Meaning | Example |
|---|---|---|
* |
Any characters within a single path component | /Users/*/Library/Safari matches /Users/alice/Library/Safari/Cookies.db |
** |
Zero or more path components at any depth | /Users/**/secrets matches /Users/alice/projects/secrets |
? |
Any single character within a component | /data/v?/file matches /data/v1/file but not /data/v12/file |
// note: Component-boundary matching. Paths without wildcards are matched as prefixes at component boundaries. /Library/App/clearancekit matches /Library/App/clearancekit/store.db but does not match /Library/App/clearancekit-extra/file. The match stops at the / separator.
The allowedProcessPaths and allowedAncestorProcessPaths fields require exact matches. No wildcards or prefix matching is supported.
The allowedSignatures and allowedAncestorSignatures fields support a single wildcard:
* as the Signing ID matches any app from the specified Team ID. For example, EQHXZ8M8AV:* matches any Google-signed binary.com.example.*) is supported; it would be treated as a literal string.See jail wildcard patterns above. Jail rules support *, **, and the additional *** (intra-component match).
Allowlist entries that match by process path require an exact match. No wildcards.
Allowlist entries that match by Signing ID support * to match any Signing ID from a given Team ID, identical to policy rule signatures.
| Context | * | ** | ? | *** | Prefix | Exact |
|---|---|---|---|---|---|---|
| Policy protected path | Yes | Yes | Yes | No | Yes | Yes |
| Policy allowed process path | No | No | No | No | No | Yes |
| Policy signature (Signing ID) | Yes (* only) | No | No | No | No | Yes |
| Jail allowed path | Yes | Yes | No | Yes | Yes | Yes |
| Jail signature | No | No | No | No | No | Yes |
| Allowlist process path | No | No | No | No | No | Yes |
| Allowlist Signing ID | Yes (* only) | No | No | No | No | Yes |
ClearanceKit identifies processes by their macOS code signature, which consists of two parts:
EQHXZ8M8AV for Google, U68MSDN6DR for Signal). Apple platform binaries use apple as their Team ID.com.apple.Safari, org.whispersystems.signal-desktop).Signatures are written in teamID:signingID format. For example:
apple:com.apple.Safari # Safari
EQHXZ8M8AV:com.google.Chrome # Google Chrome
U68MSDN6DR:org.whispersystems.signal-desktop # Signal
53Q6R32WPB:com.hnc.Discord # Discord
EQHXZ8M8AV:* # Any Google-signed binary
Code signatures cannot be spoofed without access to the developer's private signing key. A trojanised replacement binary carries a different signature (or no valid signature at all) and is immediately denied. Unlike file hashes, signatures remain valid across all future updates from the same developer.
ClearanceKit maintains a live, in-memory tree of every running process with cached ancestor chains. This lets policy rules make decisions based not just on who is accessing a file, but on who launched them.
Many legitimate workflows involve generic system tools — cp, ditto, shove — that access protected paths on behalf of a trusted parent process. App updaters use these tools to replace application bundles. Anti-malware software and MDM agents spawn them to perform remediation or policy enforcement. Without ancestry, you would need to globally allowlist these tools (weakening your policy) or ask every vendor to change their update mechanism.
With ancestry, you can allow these tools to work only when launched by a trusted parent, without any changes from the vendor:
ditto and cp to write to a protected app's data directory only when their ancestor chain includes the app's own updater, signed by the app vendor.When a policy rule has allowedAncestorProcessPaths or allowedAncestorSignatures set, ClearanceKit walks the process's ancestor chain (parent, grandparent, and so on) looking for a match. If any ancestor matches, the access is allowed.
Ancestry evaluation is lazy. The system extension classifies each event into one of three categories:
This means ancestry lookup (which is more expensive) only happens when a rule actually requires it.
// warning: Performance note. Rules with ancestor criteria require the system extension to look up the process tree and may add latency compared to process-level-only rules. The GUI warns you about this when adding ancestor criteria to a rule. For most workloads this is imperceptible, but avoid adding ancestry criteria to rules that match very high-frequency paths.
Each ancestor record includes:
The ancestor chain is visible in the Events tab when you expand an event row, shown as a tree structure from the immediate parent up to the root process.
When a process attempts to access a file, ClearanceKit evaluates policy in this order. The first match wins.
allowedProcessPaths.allowedSignatures.allowedAncestorProcessPaths.allowedAncestorSignatures.Jail rules are evaluated by a separate, dedicated Endpoint Security client and operate independently of the above. A process confined by a jail rule is denied access to any path outside the jail's allowed set, regardless of policy rules.
All policy mutations — creating, editing, or deleting rules, allowlist entries, jail rules, and app protections — require Touch ID authentication. This prevents malware from programmatically modifying your policy to grant itself access.
The user policy database is also cryptographically signed. If the signature is invalid on load (indicating potential tampering), ClearanceKit shows a dialog listing the suspect entries. You can choose to:
ClearanceKit supports enterprise deployment via Apple Configuration Profiles (mobileconfig). Managed policies are read from the uk.craigbass.clearancekit preferences domain and can be delivered by any MDM that supports managed preferences (Jamf, Kandji, Mosyle, etc.).
| Key | Type | Description |
|---|---|---|
FAAPolicy | Array | File access policy rules |
GlobalAllowlist | Array | Global allowlist entries |
JailRules | Array | Jail rules |
AppProtections | Array | App protection groupings (for GUI display) |
Each entry in the FAAPolicy array:
{
"ID": "optional-uuid-string",
"ProtectedPathPrefix": "/Users/*/Library/Safari",
"AllowedProcessPaths": ["/usr/bin/example"],
"AllowedSignatures": ["apple:com.apple.Safari", "TEAM:*"],
"AllowedAncestorProcessPaths": ["/usr/bin/parent"],
"AllowedAncestorSignatures": ["TEAM:com.example.runner"],
"EnforceOnWriteOnly": false
}
If ID is omitted, it is derived deterministically from the ProtectedPathPrefix.
When EnforceOnWriteOnly is true, the rule only fires for write operations (rename, unlink, link, create, truncate, copyfile, exchangedata, clone, and opens with FWRITE / O_APPEND / O_TRUNC). Read-only opens fall through to the next rule. Use this for tamper-protection of config files like /etc/pam.d, /etc/ssh, or audio plugin bundles, where any process should be able to read the file but only specific processes should be able to modify it. Defaults to false.
{
"ID": "optional-uuid-string",
"SigningID": "com.example.app",
"ProcessPath": "",
"PlatformBinary": false,
"TeamID": "EQHXZ8M8AV"
}
Match by SigningID or ProcessPath (not both). If PlatformBinary is true, only Apple-signed binaries match.
{
"ID": "optional-uuid-string",
"Name": "Confine Node.js",
"JailedSignature": "TEAM:com.nodejs.node",
"AllowedPathPrefixes": ["/tmp/**", "/Users/*/Projects/**"]
}
The JailedSignature must be exact (no wildcards). Name is required and displayed in the GUI.
{
"ID": "optional-uuid-string",
"AppName": "Safari",
"BundleID": "com.apple.Safari",
"RuleIDs": ["uuid-of-rule-1", "uuid-of-rule-2"]
}
RuleIDs must reference IDs of rules defined in the FAAPolicy array.
The preferences must be delivered inside a com.apple.ManagedClient.preferences payload targeting the uk.craigbass.clearancekit domain. See the GitHub repository for a complete example mobileconfig file.
Managed rules appear in the GUI with a managed badge and cannot be edited or deleted by the end user.
ClearanceKit can export policies as Apple Configuration Profiles for deployment to other machines.
Navigate to the ClearanceKit (.mobileconfig) export tab. A three-step wizard lets you select:
Navigate to the Santa export tab. This generates a Santa-compatible mobileconfig from your ClearanceKit rules. The wizard warns you about two limitations:
ClearanceKit includes an optional Model Context Protocol (MCP) server that allows AI coding agents to query policy state. This is disabled by default.
Navigate to MCP Agents in the sidebar and toggle the server on. A security warning explains that this increases the attack surface. Disable the server when not in use.
The MCP Agents tab shows all connected agents with their client name, version, connection time, and tool call count. Click Revoke to disconnect an agent.
The MCP socket path is displayed in the toolbar for configuring your AI agent's connection.