Skip to main content

A deterministic pre-deployment infrastructure governance engine

Project description

ObsidianWall Verdict

Pre-deployment infrastructure governance. Evaluate Terraform plans against governance policies before deployment executes — catching budget overruns, policy violations, and compliance failures before they become incidents.

CI Python 3.13+ License: Apache 2.0 obsidianwall.com


What it does

Verdict runs as a CLI command or a GitHub Actions step. It takes a Terraform plan and a policy file, evaluates the plan deterministically against the policy conditions, and produces a governance decision with a full audit trail.

$ verdict evaluate \
    --plan  terraform_plan.json \
    --policy policies/cost/basic_budget.yaml \
    --role  engineer

  policy       basic_budget_verdict
  condition    budget_check                    ✗ FAILED
  expression   (current_spend + estimated_cost) <= budget.amount
  evaluated    (0 + 100) <= 50  →  false

  risk score   75 / 100  (critical)
  findings     cost_analysis: 2   topology: 1
  notified     budget_owner (email)   engineering_lead (slack)

  decision     DENY_WITH_OVERRIDE
  override     budget_owner may authorize
  decision_id  abc3a13b-83d5-4fad-87d8

✗ Deployment blocked by governance policy.

No AI guessing. No approximations. Every decision is deterministic, reproducible, and attributable to a human-authored policy.


Quickstart

Install

pip install obsidianwall-verdict

Write a policy

# policies/cost/budget.yaml
apiVersion: obsidianwall.io/v1
kind: Policy

metadata:
  name: team_budget
  version: "0.1"
  owner: your-team

spec:
  inputs:
    - estimated_cost
    - current_spend

  parameters:
    budget:
      amount: 5000
      period: monthly
      flexibility: soft

  conditions:
    - id: budget_check
      expression: "(current_spend + estimated_cost) <= budget.amount"
      description: "Monthly spend must not exceed budget"

  decision:
    allow: ALLOW
    deny:  DENY_WITH_OVERRIDE
    warn:  ALLOW_WITH_NOTIFICATION

  governance:
    severity: medium
    notifications:
      - role: budget_owner
        channel: email
      - role: engineering_lead
        channel: slack

  override:
    roles:
      - budget_owner
    requires_approval: false

Evaluate a plan

# Generate your Terraform plan
terraform plan -out=tfplan
terraform show -json tfplan > terraform_plan.json

# Run governance evaluation
verdict evaluate \
  --plan   terraform_plan.json \
  --policy policies/cost/budget.yaml \
  --role   engineer

Verdict returns exit code 0 on ALLOW and non-zero on DENY, blocking CI/CD pipelines automatically.


GitHub Actions

Add Verdict as a governance gate in your CI/CD pipeline in one step:

# .github/workflows/governance.yml
name: Infrastructure Governance

on:
  pull_request:
    paths: ["**.tf", "**.tfvars"]

jobs:
  governance:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Generate Terraform plan
        run: |
          terraform init
          terraform plan -out=tfplan
          terraform show -json tfplan > terraform_plan.json

      - name: ObsidianWall Verdict
        id: verdict
        uses: obsidianwall/obsidianwall-verdict@main
        with:
          plan:         terraform_plan.json
          policy:       policies/cost/budget.yaml
          role:         engineer
          fail_on_deny: "true"

      - name: Governance outcome
        if: always()
        run: |
          echo "Decision:   ${{ steps.verdict.outputs.decision }}"
          echo "Risk score: ${{ steps.verdict.outputs.risk_score }}/100"
          echo "Severity:   ${{ steps.verdict.outputs.effective_severity }}"

Verdict posts a governance summary table to the workflow step summary on every run. Budget owners and engineering leads receive notifications through the channels defined in the policy.

Action outputs

Output Description
decision ALLOW / ALLOW_WITH_NOTIFICATION / ALLOW_WITH_APPROVAL_REQUIRED / DENY_WITH_OVERRIDE / DENY
conditions_passed true or false
risk_score Integer 0–100
effective_severity informational / low / medium / high / critical
decision_id UUID for audit trail correlation

How it works

Verdict runs a deterministic evaluation pipeline on every invocation:

Terraform plan
      ↓
Context builder       Parses resources, estimates cost
      ↓
Policy loader         Loads and validates the policy YAML
      ↓
Runtime normalizer    Flattens policy parameters into evaluation context
      ↓
Condition evaluator   Evaluates each condition deterministically
      ↓
Analyzer framework    Cost, topology, architecture, utilization analysis
      ↓
Risk scorer           Aggregates findings into risk score (0–100)
      ↓
Decision resolver     5-level governance decision with override routing
      ↓
Explainability        Reasoning chain, trace graph, remediation steps
      ↓
Notification manifest Stakeholder routing — never dispatched automatically
      ↓
Audit artifact        Immutable JSON record of the complete evaluation

Every stage is deterministic. Analyzers are advisory — they inform the risk score but never override the condition evaluation. The condition evaluation alone determines the governance decision.


Enforcement modes

Mode How What it blocks
CI/CD pipeline GitHub Actions with fail_on_deny: true terraform apply never runs on DENY
IAM access controls Azure Entra ID / AWS IAM restricts engineer credentials to read-only Direct deployment from local machines impossible
Standalone manual Run verdict evaluate before terraform apply Governance guidance, audit trail, budget owner notification

For hard technical enforcement, integrate Verdict into your CI/CD pipeline and restrict cloud credentials so only the pipeline's service principal can apply infrastructure. Engineers with read-only credentials cannot deploy directly even if they skip Verdict locally.


Governance decisions

Verdict produces one of five decisions on every evaluation:

Decision Meaning
ALLOW All conditions passed. Deployment authorized.
ALLOW_WITH_NOTIFICATION Conditions passed but high severity — stakeholders notified.
ALLOW_WITH_APPROVAL_REQUIRED Conditions passed but formal approval required before deployment.
DENY_WITH_OVERRIDE Conditions failed. An authorized role may override.
DENY Conditions failed. No override permitted. Hard block.

Policy DSL

Policies are YAML files that define governance constraints for an infrastructure change. The schema is versioned and validated on load.

Policy structure

apiVersion: obsidianwall.io/v1     Protocol version
kind: Policy                        Always Policy for now

metadata:
  name:        string               Policy identifier
  version:     string               Semver string
  owner:       string               Responsible team
  description: string               Optional description

spec:
  inputs:      list[string]         Runtime context keys required
  parameters:  dict                 Policy parameters (flattened at runtime)
  conditions:  list[Condition]      Evaluated deterministically
  decision:    Decision             allow / deny / warn mappings
  governance:  GovernanceConfig     Severity, notifications, approvals
  override:    Override             Roles and approval requirements
  actions:     list[Action]         notify / log actions

Condition expressions

Expressions use a restricted grammar — no eval(), no dynamic code:

conditions:
  - id: budget_check
    expression: "(current_spend + estimated_cost) <= budget.amount"
    description: "Monthly spend must not exceed budget"

  - id: instance_size_check
    expression: "estimated_cost <= max_instance_cost"
    description: "No single instance may exceed cost threshold"

Supported operators: <=, >=, <, >, == Supported arithmetic: + Context resolution: dot-notation for nested parameters (budget.amount)


Audit artifact

Every evaluation produces a complete audit artifact:

{
  "decision_id":        "abc3a13b-83d5-4fad-87d8-bbe77e4b8075",
  "timestamp":          "2026-05-20T04:05:28Z",
  "policy":             "basic_budget_verdict",
  "decision":           "DENY_WITH_OVERRIDE",
  "override_possible":  true,
  "override_required":  false,
  "conditions_passed":  false,
  "effective_severity": "critical",
  "risk_summary": {
    "overall_risk_score":    75,
    "risk_severity":         "critical",
    "highest_risk_analyzer": "cost_analysis",
    "total_findings":        3
  },
  "trace": [...],
  "explanation": {
    "governance_reasoning": {...},
    "policy_reasoning":     {...},
    "trace_graph":          {...}
  },
  "notification_manifest": {...}
}

The artifact is written to output/result.json and printed to stdout. It is suitable for storage in an audit log, S3 bucket, or compliance system.


Doctrine

AI may advise.
AI may explain.
AI may optimize.
AI may correlate.
AI may recommend.

AI may NOT authoritatively govern.

Every governance decision in ObsidianWall Verdict is produced by deterministic evaluation of human-authored policy conditions — never by a probabilistic model.

Decisions are reproducible, explainable, and attributable to a named policy and a named human who wrote it.

This is not an anti-AI position. The analyzer framework, recommendation engine, and explainability pipeline all use intelligence to inform the governance process. The boundary is authority: intelligence informs, policy governs.


Architecture

Verdict is the first executable of the ObsidianWall programmable assurance platform.

┌─────────────────────────────────────────────────────┐
│  Open Governance Core  (this repo — open source)    │
│                                                     │
│  engine/       deterministic evaluation pipeline    │
│  schemas/      policy DSL and typed contracts       │
│  context/      Terraform plan parsing               │
│  audit/        structured audit logging             │
│  cli/          command-line interface               │
└─────────────────────────────────────────────────────┘
         ↓ telemetry (opt-in, anonymous)
┌─────────────────────────────────────────────────────┐
│  Intelligence Layer  (future — private)             │
│                                                     │
│  Derived optimization intelligence                  │
│  Workload pattern recognition                       │
│  Pricing behavior intelligence                      │
│  Predictive governance scoring                      │
└─────────────────────────────────────────────────────┘
         ↓ enterprise workflows
┌─────────────────────────────────────────────────────┐
│  Platform Layer  (future — paid)                    │
│                                                     │
│  Hosted policy management                           │
│  Approval workflow persistence                      │
│  Governance dashboards                              │
│  RBAC, SSO, multi-tenant                            │
│  Compliance exports                                 │
└─────────────────────────────────────────────────────┘

Development

Requirements: Python 3.13+, Git

git clone https://github.com/obsidianwall/obsidianwall-verdict
cd obsidianwall-verdict

pip install -r requirements.txt

# Run the full test suite
pytest tests/ -v

# Run a sample evaluation
verdict evaluate \
  --plan  samples/terraform_plan.json \
  --policy policies/cost/basic_budget.yaml \
  --role  engineer

Test suite: 101 tests — unit, integration, and pipeline.

pytest tests/unit/        # 82 tests
pytest tests/integration/ # 11 tests
pytest tests/             # 101 tests

Policy examples

Sample policies are in policies/cost/:

Policy Enforcement Use case
basic_budget.yaml Soft — override available Engineering teams with budget owner oversight
strict_budget.yaml Hard — dual approval required Production environments, finance-controlled budgets

Telemetry

Verdict collects anonymous usage telemetry to improve the optimization catalog and governance intelligence. Telemetry is opt-in and disabled by default.

# Enable in .env
OW_TELEMETRY_ENABLED=true

What is collected: evaluation counts, resource type distributions, decision outcomes, condition failure patterns.

What is never collected: plan contents, cost amounts, resource names, organization identifiers, policy file contents.


License

Verdict is released under the Apache License 2.0.

Free to use, modify, and distribute for any purpose — commercial or non-commercial. Attribution required.

Built on ObsidianWall — the programmable assurance platform. obsidianwall.com


Built by

Aisha I. — obsidianwall.com

"Organizations that design for programmable assurance now will not need to retrofit later."

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

obsidianwall_verdict-0.2.0.tar.gz (63.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

obsidianwall_verdict-0.2.0-py3-none-any.whl (76.3 kB view details)

Uploaded Python 3

File details

Details for the file obsidianwall_verdict-0.2.0.tar.gz.

File metadata

  • Download URL: obsidianwall_verdict-0.2.0.tar.gz
  • Upload date:
  • Size: 63.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for obsidianwall_verdict-0.2.0.tar.gz
Algorithm Hash digest
SHA256 92ab337cc43cc89b476df016964515d5e3ce01a9ea7b6b7a97cbf1d6503bd4c1
MD5 9ad244e5e5e47261d3ff5fbe3472a505
BLAKE2b-256 5404a8cd936ab65c0cfcf235c748d2e2f00d76237d35f2bd9e454b8503a4ce5b

See more details on using hashes here.

File details

Details for the file obsidianwall_verdict-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for obsidianwall_verdict-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ca70f602515aba7be23515615f81c3ae11349efbce0ecf6a7a199c95caa611cf
MD5 e7ca3658b3555faa6a012d2a1519377e
BLAKE2b-256 cc65d3fe1246347275973139e4c328e2302e7d5b5a6a04cf7328091d4fae9c83

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page