obsidianwall-verdict 0.2.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.
- obsidianwall_verdict-0.2.0/PKG-INFO +503 -0
- obsidianwall_verdict-0.2.0/README.md +470 -0
- obsidianwall_verdict-0.2.0/audit/__init__.py +0 -0
- obsidianwall_verdict-0.2.0/audit/audit_logger.py +41 -0
- obsidianwall_verdict-0.2.0/cli/__init__.py +0 -0
- obsidianwall_verdict-0.2.0/cli/main.py +268 -0
- obsidianwall_verdict-0.2.0/context/__init__.py +0 -0
- obsidianwall_verdict-0.2.0/context/context_builder.py +46 -0
- obsidianwall_verdict-0.2.0/context/terraform_parser.py +104 -0
- obsidianwall_verdict-0.2.0/engine/__init__.py +0 -0
- obsidianwall_verdict-0.2.0/engine/analyzers/__init__.py +17 -0
- obsidianwall_verdict-0.2.0/engine/analyzers/architecture_analyzer.py +291 -0
- obsidianwall_verdict-0.2.0/engine/analyzers/cost_analyzer.py +235 -0
- obsidianwall_verdict-0.2.0/engine/analyzers/topology_analyzer.py +261 -0
- obsidianwall_verdict-0.2.0/engine/analyzers/utilization_analyzer.py +306 -0
- obsidianwall_verdict-0.2.0/engine/condition_evaluator.py +195 -0
- obsidianwall_verdict-0.2.0/engine/cost_estimator.py +376 -0
- obsidianwall_verdict-0.2.0/engine/decision_resolver.py +210 -0
- obsidianwall_verdict-0.2.0/engine/evaluator.py +105 -0
- obsidianwall_verdict-0.2.0/engine/explainability/__init__.py +22 -0
- obsidianwall_verdict-0.2.0/engine/explainability/explanation_builder.py +292 -0
- obsidianwall_verdict-0.2.0/engine/explainability/governance_reasoning_chain.py +834 -0
- obsidianwall_verdict-0.2.0/engine/explainability/policy_reasoning.py +302 -0
- obsidianwall_verdict-0.2.0/engine/explainability/recommendation_explainer.py +361 -0
- obsidianwall_verdict-0.2.0/engine/explainability/trace_graph.py +371 -0
- obsidianwall_verdict-0.2.0/engine/lint_validator.py +47 -0
- obsidianwall_verdict-0.2.0/engine/optimization_catalog.py +213 -0
- obsidianwall_verdict-0.2.0/engine/orchestrator.py +343 -0
- obsidianwall_verdict-0.2.0/engine/policy_loader.py +13 -0
- obsidianwall_verdict-0.2.0/engine/policy_normalizer.py +220 -0
- obsidianwall_verdict-0.2.0/engine/recommender.py +438 -0
- obsidianwall_verdict-0.2.0/engine/replay/__init__.py +9 -0
- obsidianwall_verdict-0.2.0/engine/replay/replay_engine.py +266 -0
- obsidianwall_verdict-0.2.0/engine/replay/replay_schema.py +183 -0
- obsidianwall_verdict-0.2.0/engine/replay/simulation_engine.py +336 -0
- obsidianwall_verdict-0.2.0/engine/risk_scorer.py +322 -0
- obsidianwall_verdict-0.2.0/engine/validator.py +90 -0
- obsidianwall_verdict-0.2.0/engine/workflows/__init__.py +10 -0
- obsidianwall_verdict-0.2.0/engine/workflows/approval_resolver.py +421 -0
- obsidianwall_verdict-0.2.0/engine/workflows/notification_router.py +619 -0
- obsidianwall_verdict-0.2.0/obsidianwall_verdict.egg-info/PKG-INFO +503 -0
- obsidianwall_verdict-0.2.0/obsidianwall_verdict.egg-info/SOURCES.txt +52 -0
- obsidianwall_verdict-0.2.0/obsidianwall_verdict.egg-info/dependency_links.txt +1 -0
- obsidianwall_verdict-0.2.0/obsidianwall_verdict.egg-info/entry_points.txt +2 -0
- obsidianwall_verdict-0.2.0/obsidianwall_verdict.egg-info/requires.txt +12 -0
- obsidianwall_verdict-0.2.0/obsidianwall_verdict.egg-info/top_level.txt +6 -0
- obsidianwall_verdict-0.2.0/pyproject.toml +101 -0
- obsidianwall_verdict-0.2.0/schemas/__init__.py +0 -0
- obsidianwall_verdict-0.2.0/schemas/policy_schema.py +223 -0
- obsidianwall_verdict-0.2.0/scripts/__init__.py +0 -0
- obsidianwall_verdict-0.2.0/scripts/parse_verdict_output.py +131 -0
- obsidianwall_verdict-0.2.0/setup.cfg +4 -0
- obsidianwall_verdict-0.2.0/tests/test_engine.py +58 -0
- obsidianwall_verdict-0.2.0/tests/test_policy.py +93 -0
|
@@ -0,0 +1,503 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: obsidianwall-verdict
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A deterministic pre-deployment infrastructure governance engine
|
|
5
|
+
Author-email: ObsidianWall <hello@obsidianwall.com>
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://obsidianwall.com
|
|
8
|
+
Project-URL: Documentation, https://obsidianwall.dev
|
|
9
|
+
Project-URL: Repository, https://github.com/obsidianwall/obsidianwall-verdict
|
|
10
|
+
Project-URL: Bug Tracker, https://github.com/obsidianwall/obsidianwall-verdict/issues
|
|
11
|
+
Keywords: governance,infrastructure,terraform,policy,devops,devsecops,programmable-assurance,pre-deployment
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: Topic :: Software Development :: Build Tools
|
|
16
|
+
Classifier: Topic :: System :: Systems Administration
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Operating System :: OS Independent
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: pydantic>=2.0
|
|
23
|
+
Requires-Dist: pyyaml>=6.0
|
|
24
|
+
Requires-Dist: click>=8.0
|
|
25
|
+
Requires-Dist: typer>=0.9
|
|
26
|
+
Requires-Dist: python-json-logger>=2.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
31
|
+
Requires-Dist: bandit>=1.7; extra == "dev"
|
|
32
|
+
Requires-Dist: build>=1.0; extra == "dev"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# ObsidianWall Verdict
|
|
36
|
+
|
|
37
|
+
**Pre-deployment infrastructure governance.**
|
|
38
|
+
Evaluate Terraform plans against governance policies before deployment executes —
|
|
39
|
+
catching budget overruns, policy violations, and compliance failures
|
|
40
|
+
before they become incidents.
|
|
41
|
+
|
|
42
|
+
[](https://github.com/obsidianwall/obsidianwall-verdict/actions/workflows/verdict-ci.yml)
|
|
43
|
+
[](https://www.python.org/downloads/)
|
|
44
|
+
[](LICENSE)
|
|
45
|
+
[](https://obsidianwall.com)
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## What it does
|
|
50
|
+
|
|
51
|
+
Verdict runs as a CLI command or a GitHub Actions step. It takes a Terraform
|
|
52
|
+
plan and a policy file, evaluates the plan deterministically against the policy
|
|
53
|
+
conditions, and produces a governance decision with a full audit trail.
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
$ verdict evaluate \
|
|
57
|
+
--plan terraform_plan.json \
|
|
58
|
+
--policy policies/cost/basic_budget.yaml \
|
|
59
|
+
--role engineer
|
|
60
|
+
|
|
61
|
+
policy basic_budget_verdict
|
|
62
|
+
condition budget_check ✗ FAILED
|
|
63
|
+
expression (current_spend + estimated_cost) <= budget.amount
|
|
64
|
+
evaluated (0 + 100) <= 50 → false
|
|
65
|
+
|
|
66
|
+
risk score 75 / 100 (critical)
|
|
67
|
+
findings cost_analysis: 2 topology: 1
|
|
68
|
+
notified budget_owner (email) engineering_lead (slack)
|
|
69
|
+
|
|
70
|
+
decision DENY_WITH_OVERRIDE
|
|
71
|
+
override budget_owner may authorize
|
|
72
|
+
decision_id abc3a13b-83d5-4fad-87d8
|
|
73
|
+
|
|
74
|
+
✗ Deployment blocked by governance policy.
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
No AI guessing. No approximations. Every decision is deterministic,
|
|
78
|
+
reproducible, and attributable to a human-authored policy.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Quickstart
|
|
83
|
+
|
|
84
|
+
**Install**
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pip install obsidianwall-verdict
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Write a policy**
|
|
91
|
+
|
|
92
|
+
```yaml
|
|
93
|
+
# policies/cost/budget.yaml
|
|
94
|
+
apiVersion: obsidianwall.io/v1
|
|
95
|
+
kind: Policy
|
|
96
|
+
|
|
97
|
+
metadata:
|
|
98
|
+
name: team_budget
|
|
99
|
+
version: "0.1"
|
|
100
|
+
owner: your-team
|
|
101
|
+
|
|
102
|
+
spec:
|
|
103
|
+
inputs:
|
|
104
|
+
- estimated_cost
|
|
105
|
+
- current_spend
|
|
106
|
+
|
|
107
|
+
parameters:
|
|
108
|
+
budget:
|
|
109
|
+
amount: 5000
|
|
110
|
+
period: monthly
|
|
111
|
+
flexibility: soft
|
|
112
|
+
|
|
113
|
+
conditions:
|
|
114
|
+
- id: budget_check
|
|
115
|
+
expression: "(current_spend + estimated_cost) <= budget.amount"
|
|
116
|
+
description: "Monthly spend must not exceed budget"
|
|
117
|
+
|
|
118
|
+
decision:
|
|
119
|
+
allow: ALLOW
|
|
120
|
+
deny: DENY_WITH_OVERRIDE
|
|
121
|
+
warn: ALLOW_WITH_NOTIFICATION
|
|
122
|
+
|
|
123
|
+
governance:
|
|
124
|
+
severity: medium
|
|
125
|
+
notifications:
|
|
126
|
+
- role: budget_owner
|
|
127
|
+
channel: email
|
|
128
|
+
- role: engineering_lead
|
|
129
|
+
channel: slack
|
|
130
|
+
|
|
131
|
+
override:
|
|
132
|
+
roles:
|
|
133
|
+
- budget_owner
|
|
134
|
+
requires_approval: false
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Evaluate a plan**
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Generate your Terraform plan
|
|
141
|
+
terraform plan -out=tfplan
|
|
142
|
+
terraform show -json tfplan > terraform_plan.json
|
|
143
|
+
|
|
144
|
+
# Run governance evaluation
|
|
145
|
+
verdict evaluate \
|
|
146
|
+
--plan terraform_plan.json \
|
|
147
|
+
--policy policies/cost/budget.yaml \
|
|
148
|
+
--role engineer
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Verdict returns exit code `0` on ALLOW and non-zero on DENY,
|
|
152
|
+
blocking CI/CD pipelines automatically.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## GitHub Actions
|
|
157
|
+
|
|
158
|
+
Add Verdict as a governance gate in your CI/CD pipeline in one step:
|
|
159
|
+
|
|
160
|
+
```yaml
|
|
161
|
+
# .github/workflows/governance.yml
|
|
162
|
+
name: Infrastructure Governance
|
|
163
|
+
|
|
164
|
+
on:
|
|
165
|
+
pull_request:
|
|
166
|
+
paths: ["**.tf", "**.tfvars"]
|
|
167
|
+
|
|
168
|
+
jobs:
|
|
169
|
+
governance:
|
|
170
|
+
runs-on: ubuntu-latest
|
|
171
|
+
steps:
|
|
172
|
+
- uses: actions/checkout@v4
|
|
173
|
+
|
|
174
|
+
- name: Generate Terraform plan
|
|
175
|
+
run: |
|
|
176
|
+
terraform init
|
|
177
|
+
terraform plan -out=tfplan
|
|
178
|
+
terraform show -json tfplan > terraform_plan.json
|
|
179
|
+
|
|
180
|
+
- name: ObsidianWall Verdict
|
|
181
|
+
id: verdict
|
|
182
|
+
uses: obsidianwall/obsidianwall-verdict@main
|
|
183
|
+
with:
|
|
184
|
+
plan: terraform_plan.json
|
|
185
|
+
policy: policies/cost/budget.yaml
|
|
186
|
+
role: engineer
|
|
187
|
+
fail_on_deny: "true"
|
|
188
|
+
|
|
189
|
+
- name: Governance outcome
|
|
190
|
+
if: always()
|
|
191
|
+
run: |
|
|
192
|
+
echo "Decision: ${{ steps.verdict.outputs.decision }}"
|
|
193
|
+
echo "Risk score: ${{ steps.verdict.outputs.risk_score }}/100"
|
|
194
|
+
echo "Severity: ${{ steps.verdict.outputs.effective_severity }}"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Verdict posts a governance summary table to the workflow step summary
|
|
198
|
+
on every run. Budget owners and engineering leads receive notifications
|
|
199
|
+
through the channels defined in the policy.
|
|
200
|
+
|
|
201
|
+
### Action outputs
|
|
202
|
+
|
|
203
|
+
| Output | Description |
|
|
204
|
+
|--------|-------------|
|
|
205
|
+
| `decision` | `ALLOW` / `ALLOW_WITH_NOTIFICATION` / `ALLOW_WITH_APPROVAL_REQUIRED` / `DENY_WITH_OVERRIDE` / `DENY` |
|
|
206
|
+
| `conditions_passed` | `true` or `false` |
|
|
207
|
+
| `risk_score` | Integer 0–100 |
|
|
208
|
+
| `effective_severity` | `informational` / `low` / `medium` / `high` / `critical` |
|
|
209
|
+
| `decision_id` | UUID for audit trail correlation |
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## How it works
|
|
214
|
+
|
|
215
|
+
Verdict runs a deterministic evaluation pipeline on every invocation:
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
Terraform plan
|
|
219
|
+
↓
|
|
220
|
+
Context builder Parses resources, estimates cost
|
|
221
|
+
↓
|
|
222
|
+
Policy loader Loads and validates the policy YAML
|
|
223
|
+
↓
|
|
224
|
+
Runtime normalizer Flattens policy parameters into evaluation context
|
|
225
|
+
↓
|
|
226
|
+
Condition evaluator Evaluates each condition deterministically
|
|
227
|
+
↓
|
|
228
|
+
Analyzer framework Cost, topology, architecture, utilization analysis
|
|
229
|
+
↓
|
|
230
|
+
Risk scorer Aggregates findings into risk score (0–100)
|
|
231
|
+
↓
|
|
232
|
+
Decision resolver 5-level governance decision with override routing
|
|
233
|
+
↓
|
|
234
|
+
Explainability Reasoning chain, trace graph, remediation steps
|
|
235
|
+
↓
|
|
236
|
+
Notification manifest Stakeholder routing — never dispatched automatically
|
|
237
|
+
↓
|
|
238
|
+
Audit artifact Immutable JSON record of the complete evaluation
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Every stage is deterministic. Analyzers are advisory — they inform
|
|
242
|
+
the risk score but never override the condition evaluation.
|
|
243
|
+
The condition evaluation alone determines the governance decision.
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## Enforcement modes
|
|
249
|
+
|
|
250
|
+
| Mode | How | What it blocks |
|
|
251
|
+
|------|-----|----------------|
|
|
252
|
+
| **CI/CD pipeline** | GitHub Actions with `fail_on_deny: true` | `terraform apply` never runs on DENY |
|
|
253
|
+
| **IAM access controls** | Azure Entra ID / AWS IAM restricts engineer credentials to read-only | Direct deployment from local machines impossible |
|
|
254
|
+
| **Standalone manual** | Run `verdict evaluate` before `terraform apply` | Governance guidance, audit trail, budget owner notification |
|
|
255
|
+
|
|
256
|
+
For hard technical enforcement, integrate Verdict into your CI/CD pipeline
|
|
257
|
+
and restrict cloud credentials so only the pipeline's service principal
|
|
258
|
+
can apply infrastructure. Engineers with read-only credentials cannot
|
|
259
|
+
deploy directly even if they skip Verdict locally.
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Governance decisions
|
|
265
|
+
|
|
266
|
+
Verdict produces one of five decisions on every evaluation:
|
|
267
|
+
|
|
268
|
+
| Decision | Meaning |
|
|
269
|
+
|----------|---------|
|
|
270
|
+
| `ALLOW` | All conditions passed. Deployment authorized. |
|
|
271
|
+
| `ALLOW_WITH_NOTIFICATION` | Conditions passed but high severity — stakeholders notified. |
|
|
272
|
+
| `ALLOW_WITH_APPROVAL_REQUIRED` | Conditions passed but formal approval required before deployment. |
|
|
273
|
+
| `DENY_WITH_OVERRIDE` | Conditions failed. An authorized role may override. |
|
|
274
|
+
| `DENY` | Conditions failed. No override permitted. Hard block. |
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Policy DSL
|
|
279
|
+
|
|
280
|
+
Policies are YAML files that define governance constraints for an
|
|
281
|
+
infrastructure change. The schema is versioned and validated on load.
|
|
282
|
+
|
|
283
|
+
### Policy structure
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
apiVersion: obsidianwall.io/v1 Protocol version
|
|
287
|
+
kind: Policy Always Policy for now
|
|
288
|
+
|
|
289
|
+
metadata:
|
|
290
|
+
name: string Policy identifier
|
|
291
|
+
version: string Semver string
|
|
292
|
+
owner: string Responsible team
|
|
293
|
+
description: string Optional description
|
|
294
|
+
|
|
295
|
+
spec:
|
|
296
|
+
inputs: list[string] Runtime context keys required
|
|
297
|
+
parameters: dict Policy parameters (flattened at runtime)
|
|
298
|
+
conditions: list[Condition] Evaluated deterministically
|
|
299
|
+
decision: Decision allow / deny / warn mappings
|
|
300
|
+
governance: GovernanceConfig Severity, notifications, approvals
|
|
301
|
+
override: Override Roles and approval requirements
|
|
302
|
+
actions: list[Action] notify / log actions
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### Condition expressions
|
|
306
|
+
|
|
307
|
+
Expressions use a restricted grammar — no `eval()`, no dynamic code:
|
|
308
|
+
|
|
309
|
+
```yaml
|
|
310
|
+
conditions:
|
|
311
|
+
- id: budget_check
|
|
312
|
+
expression: "(current_spend + estimated_cost) <= budget.amount"
|
|
313
|
+
description: "Monthly spend must not exceed budget"
|
|
314
|
+
|
|
315
|
+
- id: instance_size_check
|
|
316
|
+
expression: "estimated_cost <= max_instance_cost"
|
|
317
|
+
description: "No single instance may exceed cost threshold"
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Supported operators: `<=`, `>=`, `<`, `>`, `==`
|
|
321
|
+
Supported arithmetic: `+`
|
|
322
|
+
Context resolution: dot-notation for nested parameters (`budget.amount`)
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Audit artifact
|
|
327
|
+
|
|
328
|
+
Every evaluation produces a complete audit artifact:
|
|
329
|
+
|
|
330
|
+
```json
|
|
331
|
+
{
|
|
332
|
+
"decision_id": "abc3a13b-83d5-4fad-87d8-bbe77e4b8075",
|
|
333
|
+
"timestamp": "2026-05-20T04:05:28Z",
|
|
334
|
+
"policy": "basic_budget_verdict",
|
|
335
|
+
"decision": "DENY_WITH_OVERRIDE",
|
|
336
|
+
"override_possible": true,
|
|
337
|
+
"override_required": false,
|
|
338
|
+
"conditions_passed": false,
|
|
339
|
+
"effective_severity": "critical",
|
|
340
|
+
"risk_summary": {
|
|
341
|
+
"overall_risk_score": 75,
|
|
342
|
+
"risk_severity": "critical",
|
|
343
|
+
"highest_risk_analyzer": "cost_analysis",
|
|
344
|
+
"total_findings": 3
|
|
345
|
+
},
|
|
346
|
+
"trace": [...],
|
|
347
|
+
"explanation": {
|
|
348
|
+
"governance_reasoning": {...},
|
|
349
|
+
"policy_reasoning": {...},
|
|
350
|
+
"trace_graph": {...}
|
|
351
|
+
},
|
|
352
|
+
"notification_manifest": {...}
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
The artifact is written to `output/result.json` and printed to stdout.
|
|
357
|
+
It is suitable for storage in an audit log, S3 bucket, or compliance system.
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Doctrine
|
|
362
|
+
|
|
363
|
+
```
|
|
364
|
+
AI may advise.
|
|
365
|
+
AI may explain.
|
|
366
|
+
AI may optimize.
|
|
367
|
+
AI may correlate.
|
|
368
|
+
AI may recommend.
|
|
369
|
+
|
|
370
|
+
AI may NOT authoritatively govern.
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
Every governance decision in ObsidianWall Verdict is produced by
|
|
374
|
+
deterministic evaluation of human-authored policy conditions —
|
|
375
|
+
never by a probabilistic model.
|
|
376
|
+
|
|
377
|
+
Decisions are reproducible, explainable, and attributable to a named
|
|
378
|
+
policy and a named human who wrote it.
|
|
379
|
+
|
|
380
|
+
This is not an anti-AI position. The analyzer framework, recommendation
|
|
381
|
+
engine, and explainability pipeline all use intelligence to inform the
|
|
382
|
+
governance process. The boundary is authority: intelligence informs,
|
|
383
|
+
policy governs.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## Architecture
|
|
388
|
+
|
|
389
|
+
Verdict is the first executable of the ObsidianWall programmable
|
|
390
|
+
assurance platform.
|
|
391
|
+
|
|
392
|
+
```
|
|
393
|
+
┌─────────────────────────────────────────────────────┐
|
|
394
|
+
│ Open Governance Core (this repo — open source) │
|
|
395
|
+
│ │
|
|
396
|
+
│ engine/ deterministic evaluation pipeline │
|
|
397
|
+
│ schemas/ policy DSL and typed contracts │
|
|
398
|
+
│ context/ Terraform plan parsing │
|
|
399
|
+
│ audit/ structured audit logging │
|
|
400
|
+
│ cli/ command-line interface │
|
|
401
|
+
└─────────────────────────────────────────────────────┘
|
|
402
|
+
↓ telemetry (opt-in, anonymous)
|
|
403
|
+
┌─────────────────────────────────────────────────────┐
|
|
404
|
+
│ Intelligence Layer (future — private) │
|
|
405
|
+
│ │
|
|
406
|
+
│ Derived optimization intelligence │
|
|
407
|
+
│ Workload pattern recognition │
|
|
408
|
+
│ Pricing behavior intelligence │
|
|
409
|
+
│ Predictive governance scoring │
|
|
410
|
+
└─────────────────────────────────────────────────────┘
|
|
411
|
+
↓ enterprise workflows
|
|
412
|
+
┌─────────────────────────────────────────────────────┐
|
|
413
|
+
│ Platform Layer (future — paid) │
|
|
414
|
+
│ │
|
|
415
|
+
│ Hosted policy management │
|
|
416
|
+
│ Approval workflow persistence │
|
|
417
|
+
│ Governance dashboards │
|
|
418
|
+
│ RBAC, SSO, multi-tenant │
|
|
419
|
+
│ Compliance exports │
|
|
420
|
+
└─────────────────────────────────────────────────────┘
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
---
|
|
424
|
+
|
|
425
|
+
## Development
|
|
426
|
+
|
|
427
|
+
**Requirements:** Python 3.13+, Git
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
git clone https://github.com/obsidianwall/obsidianwall-verdict
|
|
431
|
+
cd obsidianwall-verdict
|
|
432
|
+
|
|
433
|
+
pip install -r requirements.txt
|
|
434
|
+
|
|
435
|
+
# Run the full test suite
|
|
436
|
+
pytest tests/ -v
|
|
437
|
+
|
|
438
|
+
# Run a sample evaluation
|
|
439
|
+
verdict evaluate \
|
|
440
|
+
--plan samples/terraform_plan.json \
|
|
441
|
+
--policy policies/cost/basic_budget.yaml \
|
|
442
|
+
--role engineer
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
**Test suite:** 101 tests — unit, integration, and pipeline.
|
|
446
|
+
|
|
447
|
+
```bash
|
|
448
|
+
pytest tests/unit/ # 82 tests
|
|
449
|
+
pytest tests/integration/ # 11 tests
|
|
450
|
+
pytest tests/ # 101 tests
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## Policy examples
|
|
456
|
+
|
|
457
|
+
Sample policies are in `policies/cost/`:
|
|
458
|
+
|
|
459
|
+
| Policy | Enforcement | Use case |
|
|
460
|
+
|--------|------------|---------|
|
|
461
|
+
| `basic_budget.yaml` | Soft — override available | Engineering teams with budget owner oversight |
|
|
462
|
+
| `strict_budget.yaml` | Hard — dual approval required | Production environments, finance-controlled budgets |
|
|
463
|
+
|
|
464
|
+
---
|
|
465
|
+
|
|
466
|
+
## Telemetry
|
|
467
|
+
|
|
468
|
+
Verdict collects anonymous usage telemetry to improve the optimization
|
|
469
|
+
catalog and governance intelligence. Telemetry is **opt-in** and
|
|
470
|
+
**disabled by default**.
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
# Enable in .env
|
|
474
|
+
OW_TELEMETRY_ENABLED=true
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
What is collected: evaluation counts, resource type distributions,
|
|
478
|
+
decision outcomes, condition failure patterns.
|
|
479
|
+
|
|
480
|
+
What is **never** collected: plan contents, cost amounts,
|
|
481
|
+
resource names, organization identifiers, policy file contents.
|
|
482
|
+
|
|
483
|
+
---
|
|
484
|
+
|
|
485
|
+
## License
|
|
486
|
+
|
|
487
|
+
Verdict is released under the
|
|
488
|
+
[Apache License 2.0](LICENSE).
|
|
489
|
+
|
|
490
|
+
Free to use, modify, and distribute for any purpose —
|
|
491
|
+
commercial or non-commercial. Attribution required.
|
|
492
|
+
|
|
493
|
+
Built on ObsidianWall — the programmable assurance platform.
|
|
494
|
+
[obsidianwall.com](https://obsidianwall.com)
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
498
|
+
## Built by
|
|
499
|
+
|
|
500
|
+
Aisha I. — [obsidianwall.com](https://obsidianwall.com)
|
|
501
|
+
|
|
502
|
+
> *"Organizations that design for programmable assurance now
|
|
503
|
+
> will not need to retrofit later."*
|