Skip to content

Commit ee23f98

Browse files
russellhancoxmlw
andauthored
docs: Add FAA configuration docs (#651)
Signed-off-by: Russell Hancox <russellhancox@users.noreply.github.com> Co-authored-by: Matt W <436037+mlw@users.noreply.github.com>
1 parent 89fd339 commit ee23f98

3 files changed

Lines changed: 222 additions & 2 deletions

File tree

docs/docs/configuration/faa.md

Lines changed: 219 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,222 @@ sidebar_position: 2
44

55
# File-Access Authorization
66

7-
Coming soon!
7+
File Access Authorization (FAA) policies are defined using a plist configuration
8+
file. The policy can be specified either in a
9+
[separate file](/configuration/keys#FileAccessPolicyPlist) or
10+
[in-line](/configuration/keys#FileAccessPolicy) with the rest of the Santa
11+
configuration.
12+
13+
If the policy is specified in a separate file, Santa will periodically re-read
14+
this file. By default this will occur every 10 minutes but the interval can be
15+
[overridden](/configuration/keys#FileAccessPolicyUpdateIntervalSec).
16+
17+
## Policy Structure
18+
19+
The policy file has a hierarchical structure with root-level configuration and
20+
individual watch rules.
21+
22+
### Root Level Keys
23+
24+
- `Version` (required): Policy version identifier that will be reported in events
25+
- `EventDetailURL` (optional): URL displayed when users receive block notifications. Supports [variable substitution](#eventdetailurl-placeholders) (e.g., `%hostname%`, `%rule_name%`, `%file_identifier%`)
26+
- `EventDetailText` (optional): Button label text for the notification dialog, maximum 48 characters. Defaults to 'Open'.
27+
- `WatchItems` (optional): Dictionary containing the individual monitoring rules
28+
29+
### Watch Item Structure
30+
31+
Each entry in the `WatchItems` dictionary represents a single rule. The key for
32+
each entry is the rule name, which will be used in logs and in the block
33+
notification UI. Each rule contains three main components:
34+
35+
- `Paths`: Array of path patterns to monitor
36+
- `Processes`: List of allowed/denied processes with specific identifiers
37+
- `Options`: Settings for rule behavior
38+
39+
## Basic Example
40+
41+
```xml
42+
<?xml version="1.0" encoding="UTF-8"?>
43+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
44+
<plist version="1.0">
45+
<dict>
46+
<key>Version</key>
47+
<string>v0.1</string>
48+
<key>EventDetailURL</key>
49+
<string>https://my-server/faa/%hostname%/%rule_name%/%file_identifier%</string>
50+
<key>WatchItems</key>
51+
<dict>
52+
<key>UserFoo</key>
53+
<dict>
54+
<key>Paths</key>
55+
<array>
56+
<dict>
57+
<key>Path</key>
58+
<string>/Users/*/tmp/foo</string>
59+
<key>IsPrefix</key>
60+
<true/>
61+
</dict>
62+
</array>
63+
<key>Options</key>
64+
<dict>
65+
<key>AllowReadAccess</key>
66+
<false/>
67+
<key>AuditOnly</key>
68+
<true/>
69+
<key>RuleType</key>
70+
<string>PathsWithAllowedProcesses</string>
71+
</dict>
72+
<key>Processes</key>
73+
<array>
74+
<dict>
75+
<key>TeamID</key>
76+
<string>EQHXZ8M8AV</string>
77+
<key>SigningID</key>
78+
<string>com.google.Chrome.helper</string>
79+
</dict>
80+
</array>
81+
</dict>
82+
</dict>
83+
</dict>
84+
</plist>
85+
```
86+
87+
## Path Configuration
88+
89+
Paths can be specified using exact matches or wildcard patterns:
90+
91+
- Exact paths: `/etc/sudoers`
92+
- Wildcards: `/Users/*/Documents/*`
93+
94+
Each path entry can include:
95+
96+
- `Path` (required): The path pattern to monitor
97+
- `IsPrefix` (optional): Boolean indicating whether the path represents prefix matching. When `true`, the rule will match files nested inside directories. When `false` or omitted, wildcards only match files/directories at that level without recursing.
98+
99+
:::important
100+
101+
If a configuration contains multiple rules with overlapping configured paths,
102+
only one rule will be applied. Which rule will be applied is undefined, so take
103+
care not to define rules with duplicate paths.
104+
105+
:::
106+
107+
### Path Globs
108+
109+
Path globs represent a point-in-time snapshot. Globs are expanded when a
110+
configuration is applied and periodically re-evaluated based on the
111+
[FileAccessPolicyUpdateIntervalSec](/configuration/keys#FileAccessPolicyUpdateIntervalSec)
112+
setting.
113+
114+
When multiple path globs or prefixes match an operation, the rule with the "most
115+
specific" or longest match is applied.
116+
117+
Glob pattern support is provided by the libc
118+
[`glob(3)`](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/glob.3.html)
119+
function. Extended glob patterns, such as globstar (`**`), are not supported.
120+
121+
### Path Resolution
122+
123+
All configured paths are case-sensitive and must match the case as stored on the
124+
filesystem.
125+
126+
Due to system limitations, Santa cannot reliably monitor hard-linked resources.
127+
To help mitigate bypasses, Santa will not allow the creation of hard links for
128+
monitored paths. If hard links previously existed for monitored paths, Santa
129+
cannot guarantee that access via these other links will be monitored.
130+
131+
Configured path globs must refer to resolved paths only. Monitoring access on
132+
symbolic links is not supported. This is important as some common macOS paths
133+
are symbolic links (e.g., `/tmp` and `/var` are both symlinks into `/private`).
134+
135+
## Process Matching
136+
137+
Processes can be matched using several identifiers:
138+
139+
- **Signing ID**: Specified with the `SigningID` key (e.g., `EQHXZ8M8AV:com.google.Chrome.helper`)
140+
- **Team ID**: Specified with the `TeamID` key (e.g., `ZMCG7MLDV9`)
141+
- **Platform Binary**: Specified with the `PlatformBinary` boolean key
142+
- **CDHash**: Specified with the `CDHash` key (e.g., `397d55ebec87943ea3c3fe6b4d4f47edc490d25e`)
143+
- **Leaf Certificate Hash**: Specified with the `CertificateSha256` key
144+
- **Binary Path**: Specified with the `BinaryPath` key (e.g., `/Applications/Safari.app/Contents/MacOS/Safari`)
145+
146+
:::tip
147+
148+
Signing IDs must be scoped to a specific TeamID. You can use the same format as
149+
binary authorization rules where the SigningID is prefixed with the TeamID (e.g.
150+
`TeamID:SigningID`. For platform binaries, you can use the hard coded string
151+
`platform` as the TeamID (e.g. `platform:com.apple.yes`).
152+
153+
:::
154+
155+
:::warning
156+
157+
Specifying binaries by full path using `BinaryPath` is not very secure, as
158+
binaries can easily be moved. This should only be used as a last resort.
159+
Additionally, the `BinaryPath` key does not support glob patterns (`*`).
160+
161+
:::
162+
163+
## Rule Options
164+
165+
The `Options` dictionary within each rule supports the following keys:
166+
167+
- `RuleType` (required): Defines whether the rule is data-centric or process-centric:
168+
- `PathsWithAllowedProcesses`: Data-centric, only listed processes can access the paths
169+
- `PathsWithDeniedProcesses`: Data-centric, listed processes cannot access the paths
170+
- `ProcessesWithAllowedPaths`: Process-centric, listed processes can only access specified paths
171+
- `ProcessesWithDeniedPaths`: Process-centric, listed processes cannot access specified paths
172+
173+
- `AllowReadAccess` (optional): Boolean controlling whether read access is allowed. When `false`, both read and write access are monitored/blocked. When `true`, only write access is monitored/blocked. Defaults to `true` if not specified.
174+
175+
- `AuditOnly` (optional): Boolean. When `true`, violations are logged but not blocked. Defaults to `true`.
176+
177+
- `EventDetailURL` (optional): Rule-specific URL that overrides the top-level EventDetailURL.
178+
179+
- `EventDetailText` (optional): Custom button label text for this specific rule, overriding the root-level setting.
180+
181+
- `BlockMessage` (optional): Custom message to be shown in the dialog presented to users upon a violation. Defaults to a reasonable, generic message that the action was blocked.
182+
183+
- `EnableSilentMode` (optional): Boolean. When `true`, violations are logged but no notification is shown to the user. Defaults to `false`.
184+
185+
- `EnableSilentTTYMode` (optional): Boolean. When `true`, violations are logged, but no notification is sent to the controlling TTY. Defaults to `false`.
186+
187+
## Rule Type Selection
188+
189+
Choose your rule type based on what you're protecting:
190+
191+
| Goal | Rule Type |
192+
| ----------------------------------------------------- | --------------------------------------------------------- |
193+
| Protect specific files/paths from unauthorized access | `PathsWithAllowedProcesses` or `PathsWithDeniedProcesses` |
194+
| Restrict what a specific process can access | `ProcessesWithAllowedPaths` or `ProcessesWithDeniedPaths` |
195+
196+
**Data-centric example**: Protect browser cookies from theft by limiting access to the cookie files to only the browser processes.
197+
198+
**Process-centric example**: Prevent AirDrop processes from reading files in folders containing sensitive corporate data.
199+
200+
## EventDetailURL placeholders
201+
202+
When an FAA rule blocks access to a file, the user will be presented with a block notification dialog. On this dialog a
203+
button can be displayed which will take the user to a page with more information about that event. For the button to
204+
appear you must populate the `EventDetailURL` field, either at the top-level of the configuration or in an individual
205+
rule. This URL can contain placeholders, which will be populated at runtime; the supported placeholders are:
206+
207+
| Placeholder | Description |
208+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------- |
209+
| `%rule_version%` | Version of the rule that was violated |
210+
| `%rule_name%` | Name of the rule that was violated |
211+
| `%file_identifier%` | SHA-256 of the binary that was being executed |
212+
| `%accessed_path%` | The path that was being accessed |
213+
| `%username%` | The executing user |
214+
| `%team_id%` | The team ID that signed this binary, if any |
215+
| `%signing_id%` | The signing ID of this binary, if any |
216+
| `%cdhash%` | The binary's CDHash, if any |
217+
| `%machine_id%` | The ID of the machine, usually the hardware UUID unless [overridden](https://northpole.dev/configuration/keys/#MachineID) |
218+
| `%serial%` | The serial number of the machine |
219+
| `%uuid%` | The hardware UUID of the machine |
220+
| `%hostname%` | The system's full hostname |
221+
222+
## More Information
223+
224+
For complete example policies and use-cases, see the [File-Access Authorization
225+
feature documentation](/features/faa) and the [FAA cookbook](/cookbook/faa).

docs/docs/cookbook/faa.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ while](https://theevilbit.github.io/beyond/beyond_0011/), going back to Patrick
260260
<false/>
261261
<key>EnableSilentMode</key>
262262
<true/>
263+
<key>RuleType</key>
264+
<string>PathsWithAllowedProcesses</string>
263265
</dict>
264266
<key>Processes</key>
265267
<array>

docs/src/lib/santaconfig.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ changes in the release notes of any future release that changes them.`,
605605
{
606606
key: "FileAccessPolicyUpdateIntervalSec",
607607
description: `Number of seconds between re-reading the file access policy config and policies/monitored paths
608-
updated`,
608+
updated. The minimum value is 15 seconds.`,
609609
type: "integer",
610610
defaultValue: 600,
611611
},

0 commit comments

Comments
 (0)