dfe-schemas 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.
Files changed (54) hide show
  1. dfe_schemas-0.1.0/.gitignore +5 -0
  2. dfe_schemas-0.1.0/LICENSE +306 -0
  3. dfe_schemas-0.1.0/PKG-INFO +108 -0
  4. dfe_schemas-0.1.0/README.md +95 -0
  5. dfe_schemas-0.1.0/additional/aws/cloudtrail_test_additional.yaml +18 -0
  6. dfe_schemas-0.1.0/common-header/minimal.yaml +98 -0
  7. dfe_schemas-0.1.0/common-header/passthrough.yaml +82 -0
  8. dfe_schemas-0.1.0/common-header/timeseries.yaml +155 -0
  9. dfe_schemas-0.1.0/dfe_schemas/__init__.py +40 -0
  10. dfe_schemas-0.1.0/dfe_schemas/clickhouse.py +261 -0
  11. dfe_schemas-0.1.0/dfe_schemas/deploy_defaults.py +43 -0
  12. dfe_schemas-0.1.0/dfe_schemas/py.typed +0 -0
  13. dfe_schemas-0.1.0/hunts/detection_checkpoint.yaml +120 -0
  14. dfe_schemas-0.1.0/hunts/results.yaml +77 -0
  15. dfe_schemas-0.1.0/meta/aws/cloudtrail.yaml +86 -0
  16. dfe_schemas-0.1.0/meta/aws/cloudwatch_logs.yaml +56 -0
  17. dfe_schemas-0.1.0/meta/aws/cloudwatch_metrics.yaml +65 -0
  18. dfe_schemas-0.1.0/meta/aws/config.yaml +65 -0
  19. dfe_schemas-0.1.0/meta/aws/guardduty.yaml +85 -0
  20. dfe_schemas-0.1.0/meta/aws/securityhub.yaml +94 -0
  21. dfe_schemas-0.1.0/meta/azure/activity_log.yaml +95 -0
  22. dfe_schemas-0.1.0/meta/azure/defender.yaml +78 -0
  23. dfe_schemas-0.1.0/meta/azure/entra_id.yaml +107 -0
  24. dfe_schemas-0.1.0/meta/azure/sentinel.yaml +92 -0
  25. dfe_schemas-0.1.0/meta/beats/filebeat.yaml +166 -0
  26. dfe_schemas-0.1.0/meta/gcp/audit_logs.yaml +80 -0
  27. dfe_schemas-0.1.0/meta/gcp/cloud_logging.yaml +67 -0
  28. dfe_schemas-0.1.0/meta/gcp/scc.yaml +78 -0
  29. dfe_schemas-0.1.0/meta/m365/alerts.yaml +80 -0
  30. dfe_schemas-0.1.0/meta/m365/audit_log.yaml +87 -0
  31. dfe_schemas-0.1.0/meta/m365/dlp.yaml +72 -0
  32. dfe_schemas-0.1.0/meta/m365/message_trace.yaml +27 -0
  33. dfe_schemas-0.1.0/meta/otel/logs.yaml +152 -0
  34. dfe_schemas-0.1.0/meta/syslog.yaml +149 -0
  35. dfe_schemas-0.1.0/pyproject.toml +52 -0
  36. dfe_schemas-0.1.0/tables/core/default.yaml +19 -0
  37. dfe_schemas-0.1.0/tables/core/detection.yaml +19 -0
  38. dfe_schemas-0.1.0/tables/core/detection_checkpoint.yaml +20 -0
  39. dfe_schemas-0.1.0/tables/internal/alert_state.yaml +54 -0
  40. dfe_schemas-0.1.0/tables/internal/hunt_lease.yaml +36 -0
  41. dfe_schemas-0.1.0/tables/internal/hunt_schedule.yaml +35 -0
  42. dfe_schemas-0.1.0/tables/internal/hunt_state.yaml +31 -0
  43. dfe_schemas-0.1.0/tables/internal/hunt_watermark.yaml +30 -0
  44. dfe_schemas-0.1.0/tables/internal/repository.yaml +51 -0
  45. dfe_schemas-0.1.0/tables/otel/logs.yaml +162 -0
  46. dfe_schemas-0.1.0/tables/otel/metrics_exponential_histogram.yaml +136 -0
  47. dfe_schemas-0.1.0/tables/otel/metrics_gauge.yaml +106 -0
  48. dfe_schemas-0.1.0/tables/otel/metrics_histogram.yaml +124 -0
  49. dfe_schemas-0.1.0/tables/otel/metrics_sum.yaml +112 -0
  50. dfe_schemas-0.1.0/tables/otel/metrics_summary.yaml +100 -0
  51. dfe_schemas-0.1.0/tables/otel/traces.yaml +114 -0
  52. dfe_schemas-0.1.0/tables/otel/traces_trace_id_ts.yaml +54 -0
  53. dfe_schemas-0.1.0/tests/test_clickhouse_engine.py +206 -0
  54. dfe_schemas-0.1.0/tests/test_package.py +30 -0
@@ -0,0 +1,5 @@
1
+ *.pyc
2
+ __pycache__/
3
+ .venv/
4
+ dist/
5
+ uv.lock
@@ -0,0 +1,306 @@
1
+ Business Source License 1.1
2
+
3
+ Parameters
4
+
5
+ Licensor: HYPERI PTY LIMITED (ABN 31 622 581 748)
6
+ Licensed Work: The software, source code, documentation, and associated
7
+ materials in this repository. The Licensed Work is (c)
8
+ 2026 HYPERI PTY LIMITED.
9
+ Additional Use Grant: You may make use of the Licensed Work, provided that
10
+ you may not use the Licensed Work for a Hosted
11
+ Service.
12
+
13
+ A "Hosted Service" is a commercial offering that
14
+ allows third parties (other than your employees and
15
+ contractors) to access the functionality of the
16
+ Licensed Work as a hosted or managed service, where
17
+ the service provides those third parties with access
18
+ to a substantial set of the features or functionality
19
+ of the Licensed Work.
20
+
21
+ Change Date: The third anniversary of the first publicly available
22
+ distribution of the specific version of the Licensed Work
23
+ under this License.
24
+
25
+ Change License: Apache License, Version 2.0
26
+
27
+ Notice
28
+
29
+ The Business Source License (this document, or the "License") is not an Open
30
+ Source license. However, the Licensed Work will eventually be made available
31
+ under an Open Source License, as stated in this License.
32
+
33
+ License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
34
+ "Business Source License" is a trademark of MariaDB Corporation Ab.
35
+
36
+ -----------------------------------------------------------------------------
37
+
38
+ Business Source License 1.1
39
+
40
+ Terms
41
+
42
+ The Licensor hereby grants you the right to copy, modify, create derivative
43
+ works, redistribute, and make non-production use of the Licensed Work. The
44
+ Licensor may make an Additional Use Grant, above, permitting limited
45
+ production use.
46
+
47
+ Effective on the Change Date, or the fourth anniversary of the first publicly
48
+ available distribution of a specific version of the Licensed Work under this
49
+ License, whichever comes first, the Licensor hereby grants you rights under
50
+ the terms of the Change License, and the rights granted in the paragraph
51
+ above terminate.
52
+
53
+ If your use of the Licensed Work does not comply with the requirements
54
+ currently in effect as described in this License, you must purchase a
55
+ commercial license from the Licensor, its affiliated entities, or authorized
56
+ resellers, or you must refrain from using the Licensed Work.
57
+
58
+ All copies of the original and modified Licensed Work, and derivative works
59
+ of the Licensed Work, are subject to this License. This License applies
60
+ separately for each version of the Licensed Work and the Change Date may vary
61
+ for each version of the Licensed Work released by Licensor.
62
+
63
+ You must conspicuously display this License on each original or modified copy
64
+ of the Licensed Work. If you receive the Licensed Work in original or
65
+ modified form from a third party, the terms and conditions set forth in this
66
+ License apply to your use of that work.
67
+
68
+ Any use of the Licensed Work in violation of this License will automatically
69
+ terminate your rights under this License for the current and all other
70
+ versions of the Licensed Work.
71
+
72
+ This License does not grant you any right in any trademark or logo of
73
+ Licensor or its affiliates (provided that you may use a trademark or logo of
74
+ Licensor as expressly required by this License).
75
+
76
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
77
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
78
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
79
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
80
+ TITLE.
81
+
82
+ MariaDB hereby grants you permission to use this License's text to license
83
+ your works, and to refer to it using the trademark "Business Source License",
84
+ as long as you comply with the Covenants of Licensor below.
85
+
86
+ Covenants of Licensor
87
+
88
+ In consideration of the right to use this License's text and the "Business
89
+ Source License" name and trademark, Licensor covenants to MariaDB, and to all
90
+ other recipients of the licensed work to be provided by Licensor:
91
+
92
+ 1. To specify as the Change License the GPL Version 2.0 or any later version,
93
+ or a license that is compatible with GPL Version 2.0 or a later version,
94
+ where "compatible" means that software provided under the Change License can
95
+ be included in a program with software provided under GPL Version 2.0 or a
96
+ later version. Licensor may specify additional Change Licenses without
97
+ limitation.
98
+
99
+ 2. To either: (a) specify an additional grant of rights to use that does not
100
+ impose any additional restriction on the right granted in this License, as
101
+ the Additional Use Grant; or (b) insert the text "None".
102
+
103
+ 3. To specify a Change Date.
104
+
105
+ 4. Not to modify this License in any other way.
106
+
107
+ =============================================================================
108
+ SUPPLEMENTARY INSTRUMENTS (operate alongside the Business Source License above)
109
+
110
+ The following Annexures are separate instruments that operate alongside, and do
111
+ not amend or form part of, the Business Source License 1.1 text above. Each is
112
+ independently severable: if any Annexure (or any provision of it) is held invalid
113
+ or unenforceable, the Business Source License above and the other Annexures
114
+ continue in full force. A separate AI training policy (AI-TRAINING-POLICY.md)
115
+ applies as its own independent instrument.
116
+
117
+ -----------------------------------------------------------------------------
118
+
119
+ # License Annexure -- Affiliate
120
+
121
+ **Licensor: HYPERI PTY LIMITED (ABN 31 622 581 748).**
122
+
123
+ This Annexure supplements the Business Source License 1.1 (the "License") under
124
+ which the Licensed Work is made available, and in particular clarifies the
125
+ scope of the words "third parties" and "your employees and contractors" in the
126
+ Additional Use Grant. This Annexure does not amend, and is not incorporated
127
+ into, the text of the License. It is a separate instrument that operates
128
+ alongside the License and any other Annexure. It does not impose any additional
129
+ restriction on the rights granted by the License; it only clarifies and, where
130
+ stated, extends who may exercise those rights.
131
+
132
+ ---
133
+
134
+ ## 1. Definitions
135
+
136
+ In this Annexure:
137
+
138
+ **"Affiliate"** of an entity means any other entity that, directly or
139
+ indirectly, Controls, is Controlled by, or is under common Control with that
140
+ entity, for so long as that Control subsists.
141
+
142
+ **"Control"** means holding, directly or indirectly, more than fifty percent
143
+ (50%) of the voting securities, voting equity interests, or other voting
144
+ ownership of an entity, or otherwise having the power to direct or cause the
145
+ direction of the management and policies of that entity, whether by contract
146
+ or otherwise.
147
+
148
+ ---
149
+
150
+ ## 2. Contractors and agents acting on your behalf
151
+
152
+ For the purposes of the Additional Use Grant, a contractor or agent that
153
+ accesses the functionality of the Licensed Work solely on your behalf and for
154
+ your own internal purposes, and not on its own account or for the benefit of
155
+ any third party, is treated as one of "your employees and contractors" and is
156
+ not a third party to whom a Hosted Service is provided.
157
+
158
+ ---
159
+
160
+ ## 3. Independent use by Affiliates is internal use
161
+
162
+ Where two or more entities that are Affiliates of one another each deploy and
163
+ operate their own instance of the Licensed Work, each for that entity's own
164
+ internal business purposes, each such entity's use is internal use and is not
165
+ the provision of a Hosted Service to a third party. Each such entity exercises
166
+ the rights granted by the License in its own right.
167
+
168
+ ---
169
+
170
+ ## 4. One Affiliate operating the software for others is a Hosted Service
171
+
172
+ For the avoidance of doubt, where one entity operates the Licensed Work and
173
+ provides access to its functionality to one or more of its Affiliates as a
174
+ shared or centralised hosted or managed service (rather than each Affiliate
175
+ operating its own instance for its own internal purposes), that operation is
176
+ the provision of a Hosted Service within the meaning of the Additional Use
177
+ Grant, and falls outside that Grant. A commercial license is required for that
178
+ use. See COMMERCIAL.md. (An Affiliate is a separate legal entity; the line
179
+ HyperI draws is operate-versus-benefit, not corporate relationship.)
180
+
181
+ ---
182
+
183
+ ## 5. Hosted-service rights are available by commercial license
184
+
185
+ Rights to operate the Licensed Work as a shared or centralised service for the
186
+ benefit of your Affiliates (intra-group hosting), and rights to operate it as a
187
+ hosted or managed service for persons or entities outside your corporate group,
188
+ are available under a commercial license from the Licensor. See COMMERCIAL.md
189
+ and contact sales@hyperi.io.
190
+
191
+ ---
192
+
193
+ ## 6. Relationship to the License and other Annexures
194
+
195
+ This Annexure applies alongside the License. Except for the clarifications in
196
+ clauses 2 to 5 about the internal group-use boundary and the commercial path for
197
+ hosted services, it does not otherwise enlarge, reduce or alter the rights
198
+ granted under the License (including the Additional Use Grant, the Change Date,
199
+ and conversion to the Change License). The License continues to govern the grant of rights in the
200
+ Licensed Work. Nothing in this Annexure is to be construed as a modification of
201
+ the text of the License.
202
+
203
+ ---
204
+
205
+ ## 7. Severability of this Annexure
206
+
207
+ If any provision of this Annexure is held to be invalid, void or unenforceable by
208
+ a court or tribunal of competent jurisdiction, that provision is severed to
209
+ the minimum extent necessary, and the remainder of this Annexure, the License,
210
+ the Additional Use Grant, and any other Annexure continue in full force and
211
+ effect. The invalidity of any provision of this Annexure does not affect the
212
+ validity or enforceability of the License, the Additional Use Grant, or any
213
+ other Annexure.
214
+
215
+ -----------------------------------------------------------------------------
216
+
217
+ # License Annexure -- Australia
218
+
219
+ **Licensor: HYPERI PTY LIMITED (ABN 31 622 581 748).**
220
+
221
+ This is a jurisdiction-specific Australian-law overlay. It applies only as
222
+ between the Licensor and a recipient to whom Australian law applies. It does not
223
+ amend, and is not incorporated into, the Business Source License 1.1 (the
224
+ "License") under which the Licensed Work is made available. It is not a
225
+ condition of the grant under the License or the Additional Use Grant. For
226
+ recipients to whom Australian law does not apply, the License remains the
227
+ complete default public license grant, subject only to its own terms and any
228
+ other separate instrument that applies independently.
229
+
230
+ In the event of a conflict between this Annexure and the License on a matter of
231
+ Australian law, this Annexure prevails to the extent of that conflict and only
232
+ as between the Licensor and a recipient to whom Australian law applies.
233
+
234
+ ---
235
+
236
+ ## 1. Australian Consumer Law -- non-excludable guarantees
237
+
238
+ Nothing in the License or this Annexure excludes, restricts or modifies any
239
+ consumer guarantee, right or remedy conferred on you by the Competition and
240
+ Consumer Act 2010 (Cth), including the Australian Consumer Law in Schedule 2
241
+ to that Act (the "ACL"), or by any other applicable law, where to do so would
242
+ contravene that law or cause any term to be void.
243
+
244
+ ---
245
+
246
+ ## 2. Limitation of liability where the ACL permits
247
+
248
+ To the extent the ACL applies to the supply of the Licensed Work and the
249
+ Licensed Work is not of a kind ordinarily acquired for personal, domestic or
250
+ household use or consumption, the Licensor's liability for failure to comply
251
+ with a consumer guarantee that cannot lawfully be excluded is limited, at the
252
+ Licensor's option, to:
253
+
254
+ (a) for goods: replacing the goods or supplying equivalent goods, repairing
255
+ the goods, paying the cost of replacing the goods or of acquiring
256
+ equivalent goods, or paying the cost of having the goods repaired; and
257
+
258
+ (b) for services: supplying the services again, or paying the cost of having
259
+ the services supplied again,
260
+
261
+ as permitted by section 64A of the ACL. This limitation does not apply if you
262
+ establish that it is not fair or reasonable for the Licensor to rely on it.
263
+
264
+ ---
265
+
266
+ ## 3. Mandatory consumer notice (where required)
267
+
268
+ Where the Licensed Work is supplied to a consumer within the meaning of the ACL
269
+ and a consumer-guarantee notice is required by the ACL or the Competition and
270
+ Consumer Regulations 2010, the applicable prescribed notice for the relevant
271
+ supply (goods, services, or goods and services) must be used.
272
+
273
+ ---
274
+
275
+ ## 4. Governing law and jurisdiction
276
+
277
+ This Annexure is governed by the laws of the Australian Capital Territory,
278
+ Australia. Each party submits to the non-exclusive jurisdiction of the courts
279
+ of the Australian Capital Territory and the courts entitled to hear appeals
280
+ from those courts.
281
+
282
+ Before commencing proceedings (other than for urgent interlocutory relief),
283
+ the parties will attempt in good faith to resolve any dispute by negotiation
284
+ for a period of 30 days from written notice of the dispute.
285
+
286
+ ---
287
+
288
+ ## 5. Relationship to the License and other Annexures
289
+
290
+ This Annexure applies only as between the Licensor and a recipient to whom
291
+ Australian law applies. It does not enlarge, reduce or alter the rights
292
+ granted under the License (including the Additional Use Grant, the Change
293
+ Date, and conversion to the Change License) for any recipient. The License
294
+ continues to govern the grant of rights in the Licensed Work.
295
+
296
+ ---
297
+
298
+ ## 6. Severability of this Annexure
299
+
300
+ If any provision of this Annexure is held to be invalid, void or unenforceable by
301
+ a court or tribunal of competent jurisdiction, that provision is severed to
302
+ the minimum extent necessary, and the remainder of this Annexure, the License,
303
+ the Additional Use Grant, and any other Annexure continue in full force and
304
+ effect. The invalidity of any provision of this Annexure does not affect the
305
+ validity or enforceability of the License, the Additional Use Grant, or of any
306
+ other Annexure.
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.5
2
+ Name: dfe-schemas
3
+ Version: 0.1.0
4
+ Summary: DFE table schemas and the ClickHouse DDL mechanics that render them
5
+ Project-URL: Repository, https://github.com/hyperi-io/dfe-schemas
6
+ Author: HYPERI PTY LIMITED
7
+ License-Expression: BUSL-1.1
8
+ License-File: LICENSE
9
+ Classifier: Operating System :: OS Independent
10
+ Classifier: Programming Language :: Python :: 3
11
+ Requires-Python: >=3.11
12
+ Description-Content-Type: text/markdown
13
+
14
+ # DFE Schemas
15
+
16
+ Shared schema definitions for the Data Fusion Engine (DFE) platform - the
17
+ **single source of truth** for the data-structure definitions that multiple
18
+ DFE components must agree on (dfe-engine, dfe-loader, dfe-receiver,
19
+ dfe-archiver).
20
+
21
+ ## Usage
22
+
23
+ Two consumption modes, one content.
24
+
25
+ As a Python package (the schema trees ship as package data, plus the
26
+ `dfe_schemas.clickhouse` engine resolver and the declared deploy defaults):
27
+
28
+ ```bash
29
+ pip install dfe-schemas
30
+ python -c "import dfe_schemas; print(dfe_schemas.schemas_root())"
31
+ ```
32
+
33
+ Or mount as a git submodule in each consuming project:
34
+
35
+ ```bash
36
+ git submodule add https://github.com/hyperi-io/dfe-schemas.git schemas
37
+ git submodule update --init --recursive
38
+ ```
39
+
40
+ Override the submodule path with `DFE_SCHEMAS_DIR`:
41
+
42
+ ```bash
43
+ export DFE_SCHEMAS_DIR=/opt/dfe/schemas
44
+ ```
45
+
46
+ Validate locally (needs dfe-engine importable - point `PY` at an interpreter
47
+ that has it):
48
+
49
+ ```bash
50
+ make validate PY=../dfe-engine/.venv/bin/python
51
+ ```
52
+
53
+ ## Structure
54
+
55
+ ```
56
+ dfe-schemas/
57
+ |-- common-header/ # header profiles: timeseries (9 col, default),
58
+ | # minimal (5 col), passthrough (4 col)
59
+ |-- meta/ # source meta schemas, by provider (aws/ azure/ gcp/ m365/)
60
+ |-- additional/ # extra-field overlays (aws/)
61
+ |-- hunts/ # hunt output (results.yaml) + runner checkpoint schema
62
+ |-- tables/ # tables in exact ClickHouse types: otel/ + engine internal/
63
+ |-- scripts/ # validate_schemas / annotate_meta_schemas
64
+ |-- docs/meta-schema.md # the YAML format reference (version tree, columns, types)
65
+ |-- docs/tables.md # the tables/ format reference (clauses, exact CH columns)
66
+ '-- Makefile # validate
67
+ ```
68
+
69
+ Every schema YAML carries its own **version tree** - each version entry is a
70
+ complete column snapshot with SchemaVer semantics (model / addition /
71
+ revision), published versions are immutable, and consumers pin versions
72
+ independently. Full format reference, column fields, the 13-primitive type
73
+ system, and the `@directive` expression language:
74
+ [docs/meta-schema.md](docs/meta-schema.md).
75
+
76
+ ## How these reach ClickHouse
77
+
78
+ One applier, three callers. The `dfe-schema` entry point in the dfe-engine
79
+ image reads this tree and reconciles ClickHouse against it: dfe-infra runs it
80
+ as a Job before the data plane starts, dfe-docker runs it as a compose
81
+ init service, and the engine repeats it idempotently at boot. Rendering SQL
82
+ here and applying it separately was a SECOND definition of the same tables, so
83
+ it is gone -- there is one DDL path and it reads these files.
84
+
85
+ ## Consumers
86
+
87
+ | Project | Language | Role | Schema types used |
88
+ |---------|----------|------|-------------------|
89
+ | **dfe-engine** | Python | DDL generation, schema builder, hunt output | All |
90
+ | **dfe-loader** | Rust | Table creation, field enrichment, auto-init | common-header |
91
+ | **dfe-receiver** | Rust | Field validation | common-header |
92
+ | **dfe-archiver** | Rust | Table detection | common-header |
93
+
94
+ Rust services slave from the DEPLOYED ClickHouse schema at runtime
95
+ (`system.columns`) - they never read this YAML directly.
96
+
97
+ ## Updating schemas
98
+
99
+ 1. Branch here, add a NEW version entry (complete column snapshot - never
100
+ modify a published version), update `current`, commit, PR to main.
101
+ 2. Bump the submodule pin in each consumer
102
+ (`git submodule update --remote schemas`, commit the pin).
103
+ 3. Copy changed common-header profiles to the consumers' bundled fallback
104
+ locations (dfe-engine: `src/dfe_engine/schema/profiles/`) so package
105
+ installs work without a submodule checkout.
106
+
107
+ Shipped files here are read-only defaults - customise by pointing
108
+ `DFE_SCHEMAS_DIR` at your own directory with only the profiles you override.
@@ -0,0 +1,95 @@
1
+ # DFE Schemas
2
+
3
+ Shared schema definitions for the Data Fusion Engine (DFE) platform - the
4
+ **single source of truth** for the data-structure definitions that multiple
5
+ DFE components must agree on (dfe-engine, dfe-loader, dfe-receiver,
6
+ dfe-archiver).
7
+
8
+ ## Usage
9
+
10
+ Two consumption modes, one content.
11
+
12
+ As a Python package (the schema trees ship as package data, plus the
13
+ `dfe_schemas.clickhouse` engine resolver and the declared deploy defaults):
14
+
15
+ ```bash
16
+ pip install dfe-schemas
17
+ python -c "import dfe_schemas; print(dfe_schemas.schemas_root())"
18
+ ```
19
+
20
+ Or mount as a git submodule in each consuming project:
21
+
22
+ ```bash
23
+ git submodule add https://github.com/hyperi-io/dfe-schemas.git schemas
24
+ git submodule update --init --recursive
25
+ ```
26
+
27
+ Override the submodule path with `DFE_SCHEMAS_DIR`:
28
+
29
+ ```bash
30
+ export DFE_SCHEMAS_DIR=/opt/dfe/schemas
31
+ ```
32
+
33
+ Validate locally (needs dfe-engine importable - point `PY` at an interpreter
34
+ that has it):
35
+
36
+ ```bash
37
+ make validate PY=../dfe-engine/.venv/bin/python
38
+ ```
39
+
40
+ ## Structure
41
+
42
+ ```
43
+ dfe-schemas/
44
+ |-- common-header/ # header profiles: timeseries (9 col, default),
45
+ | # minimal (5 col), passthrough (4 col)
46
+ |-- meta/ # source meta schemas, by provider (aws/ azure/ gcp/ m365/)
47
+ |-- additional/ # extra-field overlays (aws/)
48
+ |-- hunts/ # hunt output (results.yaml) + runner checkpoint schema
49
+ |-- tables/ # tables in exact ClickHouse types: otel/ + engine internal/
50
+ |-- scripts/ # validate_schemas / annotate_meta_schemas
51
+ |-- docs/meta-schema.md # the YAML format reference (version tree, columns, types)
52
+ |-- docs/tables.md # the tables/ format reference (clauses, exact CH columns)
53
+ '-- Makefile # validate
54
+ ```
55
+
56
+ Every schema YAML carries its own **version tree** - each version entry is a
57
+ complete column snapshot with SchemaVer semantics (model / addition /
58
+ revision), published versions are immutable, and consumers pin versions
59
+ independently. Full format reference, column fields, the 13-primitive type
60
+ system, and the `@directive` expression language:
61
+ [docs/meta-schema.md](docs/meta-schema.md).
62
+
63
+ ## How these reach ClickHouse
64
+
65
+ One applier, three callers. The `dfe-schema` entry point in the dfe-engine
66
+ image reads this tree and reconciles ClickHouse against it: dfe-infra runs it
67
+ as a Job before the data plane starts, dfe-docker runs it as a compose
68
+ init service, and the engine repeats it idempotently at boot. Rendering SQL
69
+ here and applying it separately was a SECOND definition of the same tables, so
70
+ it is gone -- there is one DDL path and it reads these files.
71
+
72
+ ## Consumers
73
+
74
+ | Project | Language | Role | Schema types used |
75
+ |---------|----------|------|-------------------|
76
+ | **dfe-engine** | Python | DDL generation, schema builder, hunt output | All |
77
+ | **dfe-loader** | Rust | Table creation, field enrichment, auto-init | common-header |
78
+ | **dfe-receiver** | Rust | Field validation | common-header |
79
+ | **dfe-archiver** | Rust | Table detection | common-header |
80
+
81
+ Rust services slave from the DEPLOYED ClickHouse schema at runtime
82
+ (`system.columns`) - they never read this YAML directly.
83
+
84
+ ## Updating schemas
85
+
86
+ 1. Branch here, add a NEW version entry (complete column snapshot - never
87
+ modify a published version), update `current`, commit, PR to main.
88
+ 2. Bump the submodule pin in each consumer
89
+ (`git submodule update --remote schemas`, commit the pin).
90
+ 3. Copy changed common-header profiles to the consumers' bundled fallback
91
+ locations (dfe-engine: `src/dfe_engine/schema/profiles/`) so package
92
+ installs work without a submodule checkout.
93
+
94
+ Shipped files here are read-only defaults - customise by pointing
95
+ `DFE_SCHEMAS_DIR` at your own directory with only the profiles you override.
@@ -0,0 +1,18 @@
1
+ # Test additional fields for dfe_aws_cloudtrail_test source.
2
+ #
3
+ # Appended on top of meta/aws/cloudtrail.yaml. Single column for
4
+ # wiring verification only — not for production use.
5
+
6
+ current: "1.0.0"
7
+ resource_type: core
8
+
9
+ versions:
10
+ "1.0.0":
11
+ date: "2026-05-11"
12
+ type: addition
13
+ summary: "Single test field appended for additional_fields wiring test"
14
+ columns:
15
+ - name: test_field
16
+ type: string
17
+ comment: "Test column — verifies additional_fields composition"
18
+ _field_type: base
@@ -0,0 +1,98 @@
1
+ # Common header profile: minimal
2
+ #
3
+ # High-volume structured data - metrics, flow records.
4
+ #
5
+ # Requires: ClickHouse 26.2+ (JSON type GA)
6
+
7
+ current: "1.0.1"
8
+ resource_type: core
9
+
10
+ versions:
11
+ "1.0.1":
12
+ date: "2026-08-05"
13
+ type: revision
14
+ summary: "_json not_null - ClickHouse rejects JSON inside Nullable on the 24.8 floor, and a capture column is always written"
15
+ columns:
16
+ - name: _timestamp_load
17
+ type: timestamp
18
+ default: "now64(3)"
19
+ order: 0
20
+ expr: "@generated: now64(3)"
21
+ comment: "Insertion timestamp (ms precision)"
22
+ _field_type: base
23
+
24
+ - name: _timestamp
25
+ type: timestamp
26
+ use_case: range
27
+ order: 1
28
+ expr: "@source: timestamp | now()"
29
+ comment: "Event timestamp from source data"
30
+ _field_type: base
31
+
32
+ - name: _uuid
33
+ type: uuid
34
+ default: "generateUUIDv7()"
35
+ expr: "@generated: generateUUIDv7()"
36
+ comment: "Time-ordered unique event identifier"
37
+ _field_type: base
38
+
39
+ - name: _org_id
40
+ type: string
41
+ attribute: [lowcardinality, not_null]
42
+ use_case: dimension
43
+ order: 2
44
+ expr: "@source: org_id"
45
+ comment: "Tenant/organisation identifier"
46
+ _field_type: base
47
+
48
+ - name: _json
49
+ type: json
50
+ attribute: [not_null]
51
+ max_dynamic_paths: 2048
52
+ expr: "@captured: raw_payload as JSON"
53
+ comment: "Original event payload as structured JSON"
54
+ _field_type: base
55
+
56
+ "1.0.0":
57
+ date: "2026-06-10"
58
+ type: model
59
+ summary: "JSON max_dynamic_paths=2048, CH 26.2+ hard deck"
60
+ columns:
61
+ - name: _timestamp_load
62
+ type: timestamp
63
+ default: "now64(3)"
64
+ order: 0
65
+ expr: "@generated: now64(3)"
66
+ comment: "Insertion timestamp (ms precision)"
67
+ _field_type: base
68
+
69
+ - name: _timestamp
70
+ type: timestamp
71
+ use_case: range
72
+ order: 1
73
+ expr: "@source: timestamp | now()"
74
+ comment: "Event timestamp from source data"
75
+ _field_type: base
76
+
77
+ - name: _uuid
78
+ type: uuid
79
+ default: "generateUUIDv7()"
80
+ expr: "@generated: generateUUIDv7()"
81
+ comment: "Time-ordered unique event identifier"
82
+ _field_type: base
83
+
84
+ - name: _org_id
85
+ type: string
86
+ attribute: [lowcardinality, not_null]
87
+ use_case: dimension
88
+ order: 2
89
+ expr: "@source: org_id"
90
+ comment: "Tenant/organisation identifier"
91
+ _field_type: base
92
+
93
+ - name: _json
94
+ type: json
95
+ max_dynamic_paths: 2048
96
+ expr: "@captured: raw_payload as JSON"
97
+ comment: "Original event payload as structured JSON"
98
+ _field_type: base