composable-data-stack 0.4.0__py3-none-any.whl

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.
cli/resolver.py ADDED
@@ -0,0 +1,28 @@
1
+ # cli/resolver.py
2
+ from __future__ import annotations
3
+
4
+ from typing import Any
5
+
6
+
7
+ def parse_contract_ref(value: str) -> tuple[str, str] | None:
8
+ parts = value.split(".", 1)
9
+ if len(parts) != 2 or not parts[0] or not parts[1]:
10
+ return None
11
+ return parts[0], parts[1]
12
+
13
+
14
+ def resolve_path(obj: dict[str, Any], path: str) -> Any:
15
+ current: Any = obj
16
+ for part in path.split("."):
17
+ if not isinstance(current, dict) or part not in current:
18
+ raise KeyError(path)
19
+ current = current[part]
20
+ return current
21
+
22
+
23
+ def is_secret_ref(value: Any) -> bool:
24
+ return isinstance(value, str) and value.startswith("secrets.") and len(value) > len("secrets.")
25
+
26
+
27
+ def secret_name_from_ref(value: str) -> str:
28
+ return value.split(".", 1)[1]
@@ -0,0 +1 @@
1
+ """Runtime data bundled with the CDS CLI."""
@@ -0,0 +1,274 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/RonaldHensbergen/composable-data-stack/security-rules.schema.json",
4
+ "title": "Composable Data Stack Security Rule Set",
5
+ "type": "object",
6
+ "required": ["version", "rules"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "$schema": {
10
+ "type": "string"
11
+ },
12
+ "version": {
13
+ "type": "string",
14
+ "pattern": "^1\\.0(\\.\\d+)?$"
15
+ },
16
+ "metadata": {
17
+ "type": "object",
18
+ "additionalProperties": false,
19
+ "properties": {
20
+ "name": { "type": "string" },
21
+ "description": { "type": "string" },
22
+ "defaultProfileClass": {
23
+ "type": "string",
24
+ "enum": ["local", "dev", "staging", "prod"]
25
+ }
26
+ }
27
+ },
28
+ "rules": {
29
+ "type": "array",
30
+ "minItems": 1,
31
+ "items": { "$ref": "#/$defs/rule" }
32
+ }
33
+ },
34
+ "$defs": {
35
+ "severity": {
36
+ "type": "string",
37
+ "enum": ["low", "medium", "high"]
38
+ },
39
+ "category": {
40
+ "type": "string",
41
+ "enum": [
42
+ "secrets",
43
+ "auth",
44
+ "network-exposure",
45
+ "file-output-safety",
46
+ "config-integrity",
47
+ "supply-chain",
48
+ "runtime-hardening",
49
+ "observability-leakage"
50
+ ]
51
+ },
52
+ "scopeItem": {
53
+ "type": "string",
54
+ "enum": [
55
+ "profile",
56
+ "profile-raw",
57
+ "profile-resolved",
58
+ "module-values",
59
+ "bindings",
60
+ "service",
61
+ "service-env",
62
+ "runtime",
63
+ "rendered-compose",
64
+ "none"
65
+ ]
66
+ },
67
+ "matchCondition": {
68
+ "type": "object",
69
+ "additionalProperties": false,
70
+ "properties": {
71
+ "pathPatterns": {
72
+ "type": "array",
73
+ "items": { "type": "string" }
74
+ },
75
+ "keyRegex": {
76
+ "type": "string"
77
+ },
78
+ "valueRegex": {
79
+ "type": "string"
80
+ },
81
+ "notValueRegex": {
82
+ "type": "string"
83
+ },
84
+ "containsAny": {
85
+ "type": "array",
86
+ "items": { "type": "string" }
87
+ },
88
+ "equalsAny": {
89
+ "type": "array",
90
+ "items": { "type": "string" }
91
+ },
92
+ "serviceTypes": {
93
+ "type": "array",
94
+ "items": {
95
+ "type": "string",
96
+ "enum": [
97
+ "admin-ui",
98
+ "database",
99
+ "api",
100
+ "worker",
101
+ "cache",
102
+ "broker",
103
+ "ingress",
104
+ "generic"
105
+ ]
106
+ }
107
+ },
108
+ "profileClasses": {
109
+ "type": "array",
110
+ "items": {
111
+ "type": "string",
112
+ "enum": ["local", "dev", "staging", "prod"]
113
+ }
114
+ },
115
+ "envInterpolation": {
116
+ "type": "boolean"
117
+ },
118
+ "allowEmpty": {
119
+ "type": "boolean"
120
+ },
121
+ "entropy": {
122
+ "type": "string",
123
+ "enum": ["high"]
124
+ },
125
+ "minLength": {
126
+ "type": "integer",
127
+ "minimum": 1
128
+ },
129
+ "portExposure": {
130
+ "type": "string",
131
+ "enum": ["localhost-only", "host-published", "0.0.0.0", "public"]
132
+ },
133
+ "imageTagPolicy": {
134
+ "type": "string",
135
+ "enum": ["forbid-latest", "require-tag", "require-digest"]
136
+ },
137
+ "permissions": {
138
+ "type": "string",
139
+ "enum": ["world-readable", "group-readable", "owner-only"]
140
+ },
141
+ "runtimeFlags": {
142
+ "type": "array",
143
+ "items": { "type": "string" }
144
+ },
145
+ "fallbackPattern": {
146
+ "type": "string"
147
+ },
148
+ "secretSinkPolicy": {
149
+ "type": "string",
150
+ "enum": ["allowed", "forbidden"]
151
+ }
152
+ }
153
+ },
154
+ "match": {
155
+ "type": "object",
156
+ "additionalProperties": false,
157
+ "properties": {
158
+ "all": {
159
+ "type": "array",
160
+ "minItems": 1,
161
+ "items": { "$ref": "#/$defs/matchCondition" }
162
+ },
163
+ "any": {
164
+ "type": "array",
165
+ "minItems": 1,
166
+ "items": { "$ref": "#/$defs/matchCondition" }
167
+ }
168
+ },
169
+ "anyOf": [
170
+ { "required": ["all"] },
171
+ { "required": ["any"] }
172
+ ]
173
+ },
174
+ "recommendation": {
175
+ "type": "array",
176
+ "minItems": 1,
177
+ "items": { "type": "string" }
178
+ },
179
+ "rule": {
180
+ "type": "object",
181
+ "required": [
182
+ "id",
183
+ "title",
184
+ "severity",
185
+ "category",
186
+ "scope",
187
+ "match",
188
+ "message",
189
+ "whyItMatters",
190
+ "recommendation"
191
+ ],
192
+ "additionalProperties": false,
193
+ "properties": {
194
+ "id": {
195
+ "type": "string",
196
+ "pattern": "^CDS-SEC-\\d{3}$"
197
+ },
198
+ "$comment": {
199
+ "type": "string"
200
+ },
201
+ "title": {
202
+ "type": "string"
203
+ },
204
+ "severity": {
205
+ "$ref": "#/$defs/severity"
206
+ },
207
+ "category": {
208
+ "$ref": "#/$defs/category"
209
+ },
210
+ "scope": {
211
+ "type": "array",
212
+ "minItems": 1,
213
+ "items": { "$ref": "#/$defs/scopeItem" }
214
+ },
215
+ "match": {
216
+ "$ref": "#/$defs/match"
217
+ },
218
+ "message": {
219
+ "type": "string"
220
+ },
221
+ "whyItMatters": {
222
+ "type": "string"
223
+ },
224
+ "recommendation": {
225
+ "$ref": "#/$defs/recommendation"
226
+ },
227
+ "references": {
228
+ "type": "array",
229
+ "items": { "type": "string" }
230
+ },
231
+ "enabled": {
232
+ "type": "boolean",
233
+ "default": true
234
+ }
235
+ }
236
+ }
237
+ },
238
+ "examples": [
239
+ {
240
+ "version": "1.0.0",
241
+ "metadata": {
242
+ "name": "cds-core-security-rules",
243
+ "description": "Core security validation rules for cds validate --security",
244
+ "defaultProfileClass": "local"
245
+ },
246
+ "rules": [
247
+ {
248
+ "id": "CDS-SEC-001",
249
+ "title": "Hardcoded secret-like value",
250
+ "severity": "high",
251
+ "category": "secrets",
252
+ "scope": ["profile-raw", "module-values", "service-env"],
253
+ "match": {
254
+ "all": [
255
+ {
256
+ "keyRegex": "(?i)(password|passwd|secret|token|api[_-]?key|access[_-]?key|secret[_-]?key|private[_-]?key|jwt|dsn)"
257
+ },
258
+ {
259
+ "notValueRegex": "^(\\$\\{[A-Z0-9_:-]+\\}|<set-me>|<from-env>|REDACTED|example)$"
260
+ }
261
+ ]
262
+ },
263
+ "message": "Secret-like value appears to be hardcoded",
264
+ "whyItMatters": "Hardcoded secrets can leak through source control, rendered output, and logs.",
265
+ "recommendation": [
266
+ "Move the value to an environment variable or secret backend.",
267
+ "Reference the secret indirectly rather than storing it in YAML."
268
+ ],
269
+ "enabled": true
270
+ }
271
+ ]
272
+ }
273
+ ]
274
+ }