pySigma-pipeline-macos 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,23 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 macOS Sigma Pipeline Contributors
4
+ Copyright (c) 2026 Nebulock, Inc.
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
23
+
@@ -0,0 +1,158 @@
1
+ Metadata-Version: 2.4
2
+ Name: pySigma-pipeline-macos
3
+ Version: 0.1.0
4
+ Summary: pySigma processing pipelines for macOS Endpoint Security, Unified Log and CrowdStrike Falcon telemetry
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Keywords: sigma,pysigma,macos,endpoint security,unified log,detection
8
+ Author: Eric Brown - Nebulock, Inc.
9
+ Requires-Python: >=3.10,<3.15
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Topic :: Security
20
+ Requires-Dist: pysigma (>=1.1.1,<3)
21
+ Project-URL: Homepage, https://github.com/Nebulock-Inc/pySigma-pipeline-macos
22
+ Project-URL: Issues, https://github.com/Nebulock-Inc/pySigma-pipeline-macos/issues
23
+ Project-URL: Repository, https://github.com/Nebulock-Inc/pySigma-pipeline-macos
24
+ Description-Content-Type: text/markdown
25
+
26
+ ![Tests](https://github.com/Nebulock-Inc/pySigma-pipeline-macos/actions/workflows/test.yml/badge.svg)
27
+ ![Status](https://img.shields.io/badge/Status-pre--release-orange)
28
+
29
+ # pySigma macOS Processing Pipelines
30
+
31
+ This package adds pySigma processing pipelines for Sigma rules with `product: macos`. It provides the namespace `sigma.pipelines.macos`. pySigma discovers the module-level factory functions (`macos_esf_ecs`, `macos_ul_ecs`, `macos_ul_raw`, `macos_falcon`); the `pipelines` dictionary maps the same names to those factories, so call the entry to get a new pipeline: `pipelines["macos_esf_ecs"]()`.
32
+
33
+ Rules select macOS telemetry through the logsource:
34
+
35
+ * `product: macos` with a `category` such as `process_creation` (optionally `service: endpointsecurity`) is Endpoint Security Framework (ESF) data.
36
+ * `product: macos` with `service: unifiedlog` is Unified Log data. The category narrows which log lines are in scope (for example `sudo`, `tcc`, `gatekeeper`, `mdm`).
37
+
38
+ `process_creation` is scoped to the `exec` event (`event.action: exec`), so it does not match other process events. Logsource values must be lowercase, and a macOS rule whose `service` is anything other than `endpointsecurity` or `unifiedlog` (a misspelling such as `unifiedlogs`) fails conversion instead of being converted unscoped. A wrong-case value fails conversion with a clear error instead of being silently skipped.
39
+
40
+ Each pipeline scopes only its own family. A Unified Log pipeline run alone passes an ESF rule through unscoped and unmapped, and the ESF pipeline does the same for a Unified Log rule. Stack both pipelines (for example `-p macos_esf_ecs -p macos_ul_ecs`), or use the one that matches the rule's service.
41
+
42
+ ## Install
43
+
44
+ pip install pySigma-pipeline-macos
45
+
46
+ With sigma-cli:
47
+
48
+ sigma plugin install macos
49
+ sigma list pipelines
50
+
51
+ (`sigma plugin install` works once the plugin is listed in the pySigma plugin directory. Until then, use `pip install` into the same environment as sigma-cli.)
52
+
53
+ ## Pipelines
54
+
55
+ | Pipeline | Targets | Notes |
56
+ |---|---|---|
57
+ | `macos_esf_ecs` | ECS documents built from Endpoint Security events | Supports the 22 ESF categories in `sigma/pipelines/macos/taxonomy.py` (`process_creation`, `file_event`, `tcc_modification`, `sudo`, ...). Sigma fields are mapped to ECS field names; the logsource is replaced by ECS `event.*` conditions. `file_event` covers file creates and the destination of renames. `file_attribute_change` is scoped on the ESF event names (`setextattr`, `deleteextattr`, `setmode`, `setowner`, `setflags`). `privilege_change` includes `setegid` and `setregid`, and `user_account_change` covers the `od_*` user and group events (including disable, enable, remove and set). |
58
+ | `macos_ul_ecs` | ECS documents built from Unified Log entries by the coreSigma collector | Supports the 10 Unified Log categories in the taxonomy. Adds the subsystem / process predicate for the category and maps fields to the collector's names (`unified_log.subsystem`, `unified_log.sender_image_path`, `log.level`, ...). Elastic's macOS Unified Logs integration names two fields differently (`dll.path`, `unified_log.message_type`); there is no pySigma pipeline for that integration yet. |
59
+ | `macos_ul_raw` | Native `log --style ndjson` keys (`subsystem`, `processImagePath`, `eventMessage`, ...) | Same categories as `macos_ul_ecs`, with the native key names. |
60
+ | `macos_falcon` | CrowdStrike Falcon LogScale | `process_creation` only. See Limitations. |
61
+
62
+ Events are expected to have the field names the taxonomy defines. This package does not collect telemetry.
63
+
64
+ Field checks: `macos_falcon` also fails unknown fields in correlation group-by, aliases and condition fields, and in a correlation rule's own `fields:` (a base rule's own `fields:` is not checked, because LogScale ignores it). The ESF and Unified Log pipelines fail a rule that uses a field the taxonomy does not know, in a detection item, in a `fields:` list, in a correlation's group-by, and in a correlation's condition field. Known fields are not checked per category: a known field is accepted in any ESF category, even where those events never carry it (for example `TargetUser` in `privilege_change`, or `Success` in `process_creation`), and the query then simply never matches. `process.pid` and `process.parent.pid` values are emitted as strings, which matches keyword-mapped pid fields. Elastic Defend's long-typed pid fields are not supported in this release. `user.id` and similar id fields are keywords: plain values are converted to strings, and numeric comparisons (`gt`, `lt`, ...) on them fail instead of comparing a keyword with a number.
65
+
66
+ The `ecs_macos_esf` pipeline in pySigma-backend-elasticsearch is a different, Elasticsearch-specific pipeline. `macos_esf_ecs` is the multi-backend layer: it scopes rules by ESF event name and category and is tested with the Lucene, EQL, ES|QL, Splunk and LogScale backends. A fixed `ecs_macos_esf` will be proposed upstream separately, once it has been tested against live Elastic Defend data.
67
+
68
+ ## Examples
69
+
70
+ Python:
71
+
72
+ ```python
73
+ from sigma.collection import SigmaCollection
74
+ from sigma.backends.elasticsearch import LuceneBackend
75
+ from sigma.pipelines.macos import pipelines
76
+
77
+ rule = SigmaCollection.from_yaml("""
78
+ title: Curl writing to /tmp
79
+ logsource:
80
+ product: macos
81
+ category: process_creation
82
+ detection:
83
+ selection:
84
+ Image|endswith: /curl
85
+ CommandLine|contains: /tmp/
86
+ condition: selection
87
+ """)
88
+ print(LuceneBackend(processing_pipeline=pipelines["macos_esf_ecs"]()).convert(rule)[0])
89
+ ```
90
+
91
+ (event.category:process AND event.type:start AND event.action:exec) AND (process.executable:*\/curl AND process.command_line:*\/tmp\/*)
92
+
93
+ The same rule with `macos_falcon` and the LogScale backend:
94
+
95
+ #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ event_platform=/^Mac$/i ImageFileName=/\/curl$/i CommandLine=/\/tmp\//i
96
+
97
+ Unified Log, with `service: unifiedlog`, `category: sudo` and `eventMessage|contains: COMMAND=`:
98
+
99
+ # macos_ul_ecs (Lucene)
100
+ process.executable:\/usr\/bin\/sudo AND message:*COMMAND\=*
101
+ # macos_ul_raw (Lucene)
102
+ processImagePath:\/usr\/bin\/sudo AND eventMessage:*COMMAND\=*
103
+
104
+ sigma-cli:
105
+
106
+ sigma convert -t lucene -p macos_esf_ecs rule.yml
107
+ sigma convert -t splunk -p macos_ul_raw rule.yml
108
+
109
+ ## Fields for account, authentication and policy categories
110
+
111
+ Besides the process fields (`Image`, `CommandLine`, `User`, `UserId`, ...), these categories have fields of their own. All map to ECS or ECS-style names; see `ESF_FIELDS` in `taxonomy.py` for the exact keys.
112
+
113
+ | Category | Sigma fields |
114
+ |---|---|
115
+ | `authentication` | `TargetUser` and `InstigatorImage` (both Open Directory logins only), `Success`, `AuthenticationType` |
116
+ | `sudo` (events `sudo` and `su`) | `SourceUser`, `TargetUser`, `TargetUserId`, `TargetImage` (sudo: the command run; su: the login shell), `Success`, `FailureReason` |
117
+ | `screen_sharing` | `TargetUser` (the account used to authenticate; empty for VNC-password sessions), `Success`, `SourceAddress`, `ViewerAppleID`, `ExistingSession` |
118
+ | `configuration_profile` | `ProfileIdentifier`, `ProfileDisplayName`, `ProfileInstallSource`, `ProfileScope`, `InstigatorImage` |
119
+ | `xprotect` | `MalwareIdentifier`, `MalwareIncidentIdentifier`, `RemediationAction`, `TargetFilename`, `Success` (remediation only) |
120
+ | `gatekeeper_override` | `TargetFilename`, `FileSha256`, `FileSigningID`, `FileTeamID` |
121
+ | `user_account_change` | `TargetUser`, `TargetGroup`, `OdAttributeName`, `OdAttributeValue`, `Success`, `InstigatorImage` |
122
+
123
+ `Success` is a boolean in Sigma: `true` converts to `event.outcome: success` and `false` to `event.outcome: failure`; any other value fails conversion. `setowner` and `setflags` in `file_attribute_change` also expose the target path as `TargetFilename`.
124
+
125
+ For `od_group_add` and `od_group_remove`, `TargetUser` is the member value, which can be a user name, a user UUID or a group UUID. The member type (not mapped) says which.
126
+
127
+ The `xprotect` and `gatekeeper_override` fields come from the member names in Apple's Endpoint Security headers; those events were not observed in captures, so treat them as unverified against live data.
128
+
129
+ ## Limitations
130
+
131
+ * **Falcon is `process_creation` only, with no keyword search.** Keyword (field-less) detection items fail with a clear message. `macos_falcon` converts `Image`, `CommandLine` and `ParentImage` for `process_creation` rules. Every other macOS category, and all `unifiedlog` rules, fail with "not supported on Falcon macOS telemetry". Fields without a Falcon equivalent (for example `SigningID`) also fail rather than being dropped. `ParentImage` is matched on the parent's basename only (Falcon's `ParentBaseFileName`), so only exact and `endswith` values with a non-empty basename are accepted; `contains`, `startswith` and `re` fail. A directory in the value is dropped, so a positive selection on `/usr/libexec/xpcproxy` also matches a parent named `xpcproxy` anywhere. Under `not`, where dropping it would widen an exclusion into a bypass, only `endswith` with the file name alone (`name`, `/name` or `*/name`) converts; any other `ParentImage` value under `not` fails.
132
+ * **Falcon LogScale only.** `macos_falcon` scopes on the LogScale tag `#event_simpleName`. Falcon Data Replicator (FDR) data outside LogScale, for example FDR shipped to Splunk, names that field `event_simpleName` (no `#`), so these queries never match there.
133
+ * **No Kusto pipeline.** Microsoft Sentinel and Defender for Endpoint (Kusto) have no macOS tables for ESF or Unified Log data. Defender for Endpoint's `DeviceProcessEvents` carries macOS `process_creation`, and the stock `microsoft_xdr_pipeline` from pySigma-backend-kusto already converts those rules (covered by a test here); this package adds nothing for Kusto.
134
+ * **Rename coverage depends on the data source.** `file_event` matches creates by `event.type` and renames by `event.action: rename`. Whether a rename reaches your index with those values (and with the destination path in `TargetFilename`) depends on the collector or integration that produced the documents; check your data before relying on rename rules.
135
+ * **Elastic Defend data differs on macOS.** Observed with Elastic Defend 9.5.6: a new file arrives only as `event.type: change` / `event.action: modification`, never as a creation, so `file_event` (a creation or a rename) misses file creates in Defend data. No `open` events were seen, so `file_access` may not match either. Defend also writes its own `event.action` values for Gatekeeper overrides (`gatekeeper_override`) and launch items (`launch_daemon`), so the `gatekeeper_override` and `background_task` categories, which scope on eslogger's event names, don't match Defend data as-is.
136
+ * **`eventType` is raw-only.** The native Unified Log key `eventType` works with `macos_ul_raw`; `macos_ul_ecs` fails it because ECS Unified Log documents do not carry it. Unknown fields fail in both Unified Log pipelines.
137
+ * **ES|QL matching is case-sensitive.** With pySigma-backend-elasticsearch 2.1.0 the ES|QL backend emits case-sensitive comparisons, unlike Sigma's default. Use the Lucene or EQL backend where case-insensitive matching matters.
138
+ * **Unified Log `launchd` scoping** matches `processImagePath = /sbin/launchd` (exact path); the pipeline adds no other condition for that category.
139
+ * **ESF only has a `macos_esf_ecs` pipeline.** There is no raw ESF pipeline; raw `eslogger` JSON is not mapped.
140
+ * **LogScale has no correlation support in pySigma-backend-crowdstrike 3.0.0.** That release does not convert correlation rules, so there the Falcon correlation field checks only matter for other backends. Later releases may add correlation support.
141
+ * Only the backends exercised by the tests are known to work: Elasticsearch (Lucene, EQL, ES|QL), Splunk and CrowdStrike LogScale. coreSigma's [support matrix](https://github.com/Nebulock-Inc/macos-coresigma/blob/v2.0.0/docs/SUPPORT_MATRIX.md) shows how each of its 69 rules converts and fires on each target, from replays of macOS test-host captures.
142
+
143
+ ## Tested versions
144
+
145
+ CI runs pySigma 1.x on Python 3.10 to 3.14, because the backends used by the tests still pin pySigma below 2. pySigma 2.x was tested locally only (the full suite passes with the backend packages installed without their dependency pins); it is not covered by CI.
146
+
147
+ ## Development
148
+
149
+ python -m venv .venv && . .venv/bin/activate
150
+ pip install . pytest pysigma-backend-elasticsearch pysigma-backend-splunk pysigma-backend-crowdstrike pysigma-backend-kusto
151
+ pytest
152
+
153
+ or `poetry install && poetry run pytest`. Code is formatted with `black` (line length 120).
154
+
155
+ ## License
156
+
157
+ MIT. See `LICENSE`.
158
+
@@ -0,0 +1,132 @@
1
+ ![Tests](https://github.com/Nebulock-Inc/pySigma-pipeline-macos/actions/workflows/test.yml/badge.svg)
2
+ ![Status](https://img.shields.io/badge/Status-pre--release-orange)
3
+
4
+ # pySigma macOS Processing Pipelines
5
+
6
+ This package adds pySigma processing pipelines for Sigma rules with `product: macos`. It provides the namespace `sigma.pipelines.macos`. pySigma discovers the module-level factory functions (`macos_esf_ecs`, `macos_ul_ecs`, `macos_ul_raw`, `macos_falcon`); the `pipelines` dictionary maps the same names to those factories, so call the entry to get a new pipeline: `pipelines["macos_esf_ecs"]()`.
7
+
8
+ Rules select macOS telemetry through the logsource:
9
+
10
+ * `product: macos` with a `category` such as `process_creation` (optionally `service: endpointsecurity`) is Endpoint Security Framework (ESF) data.
11
+ * `product: macos` with `service: unifiedlog` is Unified Log data. The category narrows which log lines are in scope (for example `sudo`, `tcc`, `gatekeeper`, `mdm`).
12
+
13
+ `process_creation` is scoped to the `exec` event (`event.action: exec`), so it does not match other process events. Logsource values must be lowercase, and a macOS rule whose `service` is anything other than `endpointsecurity` or `unifiedlog` (a misspelling such as `unifiedlogs`) fails conversion instead of being converted unscoped. A wrong-case value fails conversion with a clear error instead of being silently skipped.
14
+
15
+ Each pipeline scopes only its own family. A Unified Log pipeline run alone passes an ESF rule through unscoped and unmapped, and the ESF pipeline does the same for a Unified Log rule. Stack both pipelines (for example `-p macos_esf_ecs -p macos_ul_ecs`), or use the one that matches the rule's service.
16
+
17
+ ## Install
18
+
19
+ pip install pySigma-pipeline-macos
20
+
21
+ With sigma-cli:
22
+
23
+ sigma plugin install macos
24
+ sigma list pipelines
25
+
26
+ (`sigma plugin install` works once the plugin is listed in the pySigma plugin directory. Until then, use `pip install` into the same environment as sigma-cli.)
27
+
28
+ ## Pipelines
29
+
30
+ | Pipeline | Targets | Notes |
31
+ |---|---|---|
32
+ | `macos_esf_ecs` | ECS documents built from Endpoint Security events | Supports the 22 ESF categories in `sigma/pipelines/macos/taxonomy.py` (`process_creation`, `file_event`, `tcc_modification`, `sudo`, ...). Sigma fields are mapped to ECS field names; the logsource is replaced by ECS `event.*` conditions. `file_event` covers file creates and the destination of renames. `file_attribute_change` is scoped on the ESF event names (`setextattr`, `deleteextattr`, `setmode`, `setowner`, `setflags`). `privilege_change` includes `setegid` and `setregid`, and `user_account_change` covers the `od_*` user and group events (including disable, enable, remove and set). |
33
+ | `macos_ul_ecs` | ECS documents built from Unified Log entries by the coreSigma collector | Supports the 10 Unified Log categories in the taxonomy. Adds the subsystem / process predicate for the category and maps fields to the collector's names (`unified_log.subsystem`, `unified_log.sender_image_path`, `log.level`, ...). Elastic's macOS Unified Logs integration names two fields differently (`dll.path`, `unified_log.message_type`); there is no pySigma pipeline for that integration yet. |
34
+ | `macos_ul_raw` | Native `log --style ndjson` keys (`subsystem`, `processImagePath`, `eventMessage`, ...) | Same categories as `macos_ul_ecs`, with the native key names. |
35
+ | `macos_falcon` | CrowdStrike Falcon LogScale | `process_creation` only. See Limitations. |
36
+
37
+ Events are expected to have the field names the taxonomy defines. This package does not collect telemetry.
38
+
39
+ Field checks: `macos_falcon` also fails unknown fields in correlation group-by, aliases and condition fields, and in a correlation rule's own `fields:` (a base rule's own `fields:` is not checked, because LogScale ignores it). The ESF and Unified Log pipelines fail a rule that uses a field the taxonomy does not know, in a detection item, in a `fields:` list, in a correlation's group-by, and in a correlation's condition field. Known fields are not checked per category: a known field is accepted in any ESF category, even where those events never carry it (for example `TargetUser` in `privilege_change`, or `Success` in `process_creation`), and the query then simply never matches. `process.pid` and `process.parent.pid` values are emitted as strings, which matches keyword-mapped pid fields. Elastic Defend's long-typed pid fields are not supported in this release. `user.id` and similar id fields are keywords: plain values are converted to strings, and numeric comparisons (`gt`, `lt`, ...) on them fail instead of comparing a keyword with a number.
40
+
41
+ The `ecs_macos_esf` pipeline in pySigma-backend-elasticsearch is a different, Elasticsearch-specific pipeline. `macos_esf_ecs` is the multi-backend layer: it scopes rules by ESF event name and category and is tested with the Lucene, EQL, ES|QL, Splunk and LogScale backends. A fixed `ecs_macos_esf` will be proposed upstream separately, once it has been tested against live Elastic Defend data.
42
+
43
+ ## Examples
44
+
45
+ Python:
46
+
47
+ ```python
48
+ from sigma.collection import SigmaCollection
49
+ from sigma.backends.elasticsearch import LuceneBackend
50
+ from sigma.pipelines.macos import pipelines
51
+
52
+ rule = SigmaCollection.from_yaml("""
53
+ title: Curl writing to /tmp
54
+ logsource:
55
+ product: macos
56
+ category: process_creation
57
+ detection:
58
+ selection:
59
+ Image|endswith: /curl
60
+ CommandLine|contains: /tmp/
61
+ condition: selection
62
+ """)
63
+ print(LuceneBackend(processing_pipeline=pipelines["macos_esf_ecs"]()).convert(rule)[0])
64
+ ```
65
+
66
+ (event.category:process AND event.type:start AND event.action:exec) AND (process.executable:*\/curl AND process.command_line:*\/tmp\/*)
67
+
68
+ The same rule with `macos_falcon` and the LogScale backend:
69
+
70
+ #event_simpleName=/^(ProcessRollup2|SyntheticProcessRollup2)$/ event_platform=/^Mac$/i ImageFileName=/\/curl$/i CommandLine=/\/tmp\//i
71
+
72
+ Unified Log, with `service: unifiedlog`, `category: sudo` and `eventMessage|contains: COMMAND=`:
73
+
74
+ # macos_ul_ecs (Lucene)
75
+ process.executable:\/usr\/bin\/sudo AND message:*COMMAND\=*
76
+ # macos_ul_raw (Lucene)
77
+ processImagePath:\/usr\/bin\/sudo AND eventMessage:*COMMAND\=*
78
+
79
+ sigma-cli:
80
+
81
+ sigma convert -t lucene -p macos_esf_ecs rule.yml
82
+ sigma convert -t splunk -p macos_ul_raw rule.yml
83
+
84
+ ## Fields for account, authentication and policy categories
85
+
86
+ Besides the process fields (`Image`, `CommandLine`, `User`, `UserId`, ...), these categories have fields of their own. All map to ECS or ECS-style names; see `ESF_FIELDS` in `taxonomy.py` for the exact keys.
87
+
88
+ | Category | Sigma fields |
89
+ |---|---|
90
+ | `authentication` | `TargetUser` and `InstigatorImage` (both Open Directory logins only), `Success`, `AuthenticationType` |
91
+ | `sudo` (events `sudo` and `su`) | `SourceUser`, `TargetUser`, `TargetUserId`, `TargetImage` (sudo: the command run; su: the login shell), `Success`, `FailureReason` |
92
+ | `screen_sharing` | `TargetUser` (the account used to authenticate; empty for VNC-password sessions), `Success`, `SourceAddress`, `ViewerAppleID`, `ExistingSession` |
93
+ | `configuration_profile` | `ProfileIdentifier`, `ProfileDisplayName`, `ProfileInstallSource`, `ProfileScope`, `InstigatorImage` |
94
+ | `xprotect` | `MalwareIdentifier`, `MalwareIncidentIdentifier`, `RemediationAction`, `TargetFilename`, `Success` (remediation only) |
95
+ | `gatekeeper_override` | `TargetFilename`, `FileSha256`, `FileSigningID`, `FileTeamID` |
96
+ | `user_account_change` | `TargetUser`, `TargetGroup`, `OdAttributeName`, `OdAttributeValue`, `Success`, `InstigatorImage` |
97
+
98
+ `Success` is a boolean in Sigma: `true` converts to `event.outcome: success` and `false` to `event.outcome: failure`; any other value fails conversion. `setowner` and `setflags` in `file_attribute_change` also expose the target path as `TargetFilename`.
99
+
100
+ For `od_group_add` and `od_group_remove`, `TargetUser` is the member value, which can be a user name, a user UUID or a group UUID. The member type (not mapped) says which.
101
+
102
+ The `xprotect` and `gatekeeper_override` fields come from the member names in Apple's Endpoint Security headers; those events were not observed in captures, so treat them as unverified against live data.
103
+
104
+ ## Limitations
105
+
106
+ * **Falcon is `process_creation` only, with no keyword search.** Keyword (field-less) detection items fail with a clear message. `macos_falcon` converts `Image`, `CommandLine` and `ParentImage` for `process_creation` rules. Every other macOS category, and all `unifiedlog` rules, fail with "not supported on Falcon macOS telemetry". Fields without a Falcon equivalent (for example `SigningID`) also fail rather than being dropped. `ParentImage` is matched on the parent's basename only (Falcon's `ParentBaseFileName`), so only exact and `endswith` values with a non-empty basename are accepted; `contains`, `startswith` and `re` fail. A directory in the value is dropped, so a positive selection on `/usr/libexec/xpcproxy` also matches a parent named `xpcproxy` anywhere. Under `not`, where dropping it would widen an exclusion into a bypass, only `endswith` with the file name alone (`name`, `/name` or `*/name`) converts; any other `ParentImage` value under `not` fails.
107
+ * **Falcon LogScale only.** `macos_falcon` scopes on the LogScale tag `#event_simpleName`. Falcon Data Replicator (FDR) data outside LogScale, for example FDR shipped to Splunk, names that field `event_simpleName` (no `#`), so these queries never match there.
108
+ * **No Kusto pipeline.** Microsoft Sentinel and Defender for Endpoint (Kusto) have no macOS tables for ESF or Unified Log data. Defender for Endpoint's `DeviceProcessEvents` carries macOS `process_creation`, and the stock `microsoft_xdr_pipeline` from pySigma-backend-kusto already converts those rules (covered by a test here); this package adds nothing for Kusto.
109
+ * **Rename coverage depends on the data source.** `file_event` matches creates by `event.type` and renames by `event.action: rename`. Whether a rename reaches your index with those values (and with the destination path in `TargetFilename`) depends on the collector or integration that produced the documents; check your data before relying on rename rules.
110
+ * **Elastic Defend data differs on macOS.** Observed with Elastic Defend 9.5.6: a new file arrives only as `event.type: change` / `event.action: modification`, never as a creation, so `file_event` (a creation or a rename) misses file creates in Defend data. No `open` events were seen, so `file_access` may not match either. Defend also writes its own `event.action` values for Gatekeeper overrides (`gatekeeper_override`) and launch items (`launch_daemon`), so the `gatekeeper_override` and `background_task` categories, which scope on eslogger's event names, don't match Defend data as-is.
111
+ * **`eventType` is raw-only.** The native Unified Log key `eventType` works with `macos_ul_raw`; `macos_ul_ecs` fails it because ECS Unified Log documents do not carry it. Unknown fields fail in both Unified Log pipelines.
112
+ * **ES|QL matching is case-sensitive.** With pySigma-backend-elasticsearch 2.1.0 the ES|QL backend emits case-sensitive comparisons, unlike Sigma's default. Use the Lucene or EQL backend where case-insensitive matching matters.
113
+ * **Unified Log `launchd` scoping** matches `processImagePath = /sbin/launchd` (exact path); the pipeline adds no other condition for that category.
114
+ * **ESF only has a `macos_esf_ecs` pipeline.** There is no raw ESF pipeline; raw `eslogger` JSON is not mapped.
115
+ * **LogScale has no correlation support in pySigma-backend-crowdstrike 3.0.0.** That release does not convert correlation rules, so there the Falcon correlation field checks only matter for other backends. Later releases may add correlation support.
116
+ * Only the backends exercised by the tests are known to work: Elasticsearch (Lucene, EQL, ES|QL), Splunk and CrowdStrike LogScale. coreSigma's [support matrix](https://github.com/Nebulock-Inc/macos-coresigma/blob/v2.0.0/docs/SUPPORT_MATRIX.md) shows how each of its 69 rules converts and fires on each target, from replays of macOS test-host captures.
117
+
118
+ ## Tested versions
119
+
120
+ CI runs pySigma 1.x on Python 3.10 to 3.14, because the backends used by the tests still pin pySigma below 2. pySigma 2.x was tested locally only (the full suite passes with the backend packages installed without their dependency pins); it is not covered by CI.
121
+
122
+ ## Development
123
+
124
+ python -m venv .venv && . .venv/bin/activate
125
+ pip install . pytest pysigma-backend-elasticsearch pysigma-backend-splunk pysigma-backend-crowdstrike pysigma-backend-kusto
126
+ pytest
127
+
128
+ or `poetry install && poetry run pytest`. Code is formatted with `black` (line length 120).
129
+
130
+ ## License
131
+
132
+ MIT. See `LICENSE`.
@@ -0,0 +1,42 @@
1
+ [tool.poetry]
2
+ name = "pySigma-pipeline-macos"
3
+ version = "0.1.0"
4
+ description = "pySigma processing pipelines for macOS Endpoint Security, Unified Log and CrowdStrike Falcon telemetry"
5
+ readme = "README.md"
6
+ authors = ["Eric Brown - Nebulock, Inc."]
7
+ license = "MIT"
8
+ repository = "https://github.com/Nebulock-Inc/pySigma-pipeline-macos"
9
+ homepage = "https://github.com/Nebulock-Inc/pySigma-pipeline-macos"
10
+ keywords = ["sigma", "pysigma", "macos", "endpoint security", "unified log", "detection"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Operating System :: OS Independent",
15
+ "Topic :: Security",
16
+ ]
17
+ packages = [
18
+ { include = "sigma" }
19
+ ]
20
+
21
+ [tool.poetry.urls]
22
+ "Issues" = "https://github.com/Nebulock-Inc/pySigma-pipeline-macos/issues"
23
+
24
+ [tool.poetry.dependencies]
25
+ python = ">=3.10,<3.15"
26
+ pysigma = ">=1.1.1,<3"
27
+
28
+ [tool.poetry.group.dev.dependencies]
29
+ black = ">=24.10"
30
+ pytest = ">=8.3"
31
+ pytest-cov = ">=6.0"
32
+ pysigma-backend-elasticsearch = ">=2.1.0"
33
+ pysigma-backend-splunk = ">=2.1.0"
34
+ pysigma-backend-crowdstrike = ">=3.0.0"
35
+ pysigma-backend-kusto = ">=1.0.1"
36
+
37
+ [tool.black]
38
+ line-length = 120
39
+
40
+ [build-system]
41
+ requires = ["poetry-core>=1.9.0"]
42
+ build-backend = "poetry.core.masonry.api"
@@ -0,0 +1,13 @@
1
+ """macOS pySigma pipeline."""
2
+
3
+ from .esf import macos_esf_ecs
4
+ from .falcon import macos_falcon
5
+ from .ul import macos_ul_ecs, macos_ul_raw
6
+
7
+ # Factories, not instances (SigmaHQ convention): each conversion builds its own pipeline.
8
+ pipelines = {
9
+ "macos_esf_ecs": macos_esf_ecs,
10
+ "macos_falcon": macos_falcon,
11
+ "macos_ul_ecs": macos_ul_ecs,
12
+ "macos_ul_raw": macos_ul_raw,
13
+ }