Skip to main content
QWED Logo

☁️ QWED-Infra

Deterministic Verification for Infrastructure as Code (IaC)

"Don't let AI hallucinate your cloud bill to $20,000."

Verified by QWED Verification Context PyPI License Python 3.10+ GitHub stars GitHub Developer Program

Sponsor QWED on GitHub

Twitter LinkedIn


🚨 The Problem

AI agents like Devin, GitHub Copilot Workspace, and Cursor are writing Terraform and Kubernetes configs. But AI doesn't understand consequences.

Case What AI Wrote Real World Impact
IAM Permission Action: "s3:*", Resource: "*" Data Breach: Entire bucket exposed to public.
Network Rule Ingress: 0.0.0.0/0, Port: 22 Ransomware: SSH open to the whole internet.
Instance Type instance_type = "p4d.24xlarge" Bankrupt: $23,000/month bill for a dev env.

💡 What QWED-Infra Is (and Isn't)

✅ QWED-Infra IS:

  • A Deterministic Verification Engine: Uses Z3 Theorem Prover to prove IAM action/resource matching, with IP and date conditions evaluated deterministically in Python.
  • A Graph Analyzer: Uses NetworkX to map and verify network reachability (Reachability Analysis).
  • An Artifact Boundary Gate: Scans release packages for secrets, debug artifacts, and misconfigured build paths — blocks unsafe releases before they ship.
  • Deterministic: Inputs are code, output is True/False with 100% certainty.
  • A "Guard" Layer: Plugs into CI/CD to block AI-generated PRs that violate rules.

❌ QWED-Infra is NOT:

  • A Linter: We don't just check syntax (like TFLint). We check logic.
  • A Cost Explorer: We predict costs before deployment, not after you get the bill.
  • Black Box AI: We don't use LLMs to verify LLMs. We use Math.

🆚 How We're Different

Feature TFLint / Checkov / TFSec QWED-Infra
Approach Regex / Static Pattern Matching Symbolic Execution (Z3) & Graph Theory
IAM Logic Can catch s3:* text match Proves Allow overrides Deny logically
Network Checks generic "port 22 open" Traces Internet -> IGW -> Route -> SG -> Subnet (fail-closed on NAT/NACL/peering)
Cost N/A (usually distinct tools) Deterministic Pre-Deployment Estimation
Accuracy High False Positives Deterministic Correctness

🛡️ The Four Guards

1. IamGuard (The Security Math)

Converts AWS IAM Policies into logical formulas.

  • Wildcards: Handles s3:Get* vs s3:GetObject — proved symbolically in Z3.
  • Logic: Proves Deny statements always win — proved symbolically in Z3.
  • Context: Verifies against specific conditions (e.g., aws:SourceIp, aws:CurrentTime) — evaluated deterministically in Python, with full trace in diagnostic output.

2. NetworkGuard (The Topology Graph)

Builds a directed graph of your VPC.

  • Reachability: "Can an attacker on the Internet reach my Database?"
  • Path Analysis: Traces routes through Subnets and Security Groups.
  • Limitations (fail-closed): NAT Gateways, VPC Peering, NACLs, and Transit Gateway are not modeled. If any are present, the guard returns UNVERIFIABLE — the result carries no proof and must not be used for authorization decisions.

3. CostGuard (The Budget Enforcer)

Prevents financial ruin.

  • Static Catalog: Embedded prices for standard AWS resources.
  • Budget Checks: if estimated_cost > $500: Block Deployment.

4. ArtifactBoundaryGuard (The Release Gate)

Verifies release artifacts before they ship.

  • Secret Scanning: Detects leaked secrets (.env, *.token, API keys) in package files.
  • Debug Artifact Detection: Blocks .coverage, .pytest_cache, __pycache__ from entering packages.
  • Build Config Verification: Ensures pyproject.toml hatch build config only includes intended paths.
  • Fail-Closed: Unknown backends, missing configs, or unparseable files produce BLOCKED, never a silent pass.

📦 Installation

pip install qwed-infra

(Node.js/npm SDK coming soon)


⚡ Usage Examples

Verify IAM Policies

from qwed_infra import IamGuard

guard = IamGuard()
policy = {
    "Effect": "Allow",
    "Action": "s3:GetObject",
    "Resource": "*",
    "Condition": {"IpAddress": {"aws:SourceIp": "192.168.1.0/24"}}
}

# Verify: Is it accessible from the public internet?
result = guard.verify_access(
    policy, 
    action="s3:GetObject", 
    resource="my-bucket", 
    context={"aws:SourceIp": "8.8.8.8"} # Public IP
)

print(result.allowed) # -> False (Blocked by IP)

Verify Network Reachability

from qwed_infra import NetworkGuard

net = NetworkGuard()
infra = {
    "subnets": [
        {"id": "subnet-web", "security_groups": ["sg-web"]},
    ],
    "route_tables": [
        {
            "subnet_id": "subnet-web",
            "routes": {"0.0.0.0/0": "igw-main"},
        }
    ],
    "security_groups": {
        "sg-web": {"ingress": [{"port": 80, "cidr": "0.0.0.0/0"}]},
    },
}

# Is the web subnet reachable from Internet on port 80?
result = net.verify_reachability(infra, "internet", "subnet-web", port=80)
print(result.reachable)  # -> True (Risk Alert!)

# Convert to structured diagnostic for CI/CD enforcement
diagnostic = NetworkGuard.to_diagnostic(result)
print(diagnostic.status.value)  # -> VERIFIED / BLOCKED / UNVERIFIABLE

Enforce Budget

from qwed_infra import CostGuard

cost = CostGuard()
resources = {
    "instances": [
        {"id": "gpu", "instance_type": "p4d.24xlarge", "count": 2}
    ]
}

result = cost.verify_budget(resources, budget_monthly=1000)
print(result.within_budget) # -> False
print(result.reason) # -> "Estimated cost $47844.20 EXCEEDS budget $1000.00"

Verify Package Boundary

from qwed_infra import ArtifactBoundaryGuard

guard = ArtifactBoundaryGuard()
result = guard.verify_package_boundary(package_dir="qwed_infra")

# Convert to structured diagnostic for CI/CD enforcement
diagnostic = ArtifactBoundaryGuard.to_diagnostic(result)

if diagnostic.status.value == "BLOCKED":
    for finding in diagnostic.developer_fields["findings"]:
        print(f"❌ {finding['finding_type']}: {finding['reason']}")
else:
    print("✅ Package boundary verified — safe to ship.")

🔏 Verification Context v1.0

Every guard can emit a Verification Context (VC) document — a portable, machine-checkable trust artifact that records what was verified, by whom, with what proof, and whether a downstream system should admit or deny.

Why VC?

A True/False return value is enough for one process — but CI/CD pipelines, release gates, and audit trails need evidence that travels:

Plain result Verification Context
result.allowed == False Document: claim, verifier identity+version, hash-linked evidence (proof_ref), admission decision
Lives only in your process log JSON-serializable, schema-validated, evidence-bound (sha256 proof_ref computed over the exact evidence)
No story when someone asks "who verified this?" proof.verifier, audit_trace, and rule IDs answer it

The document is fail-closed by construction: anything that is not proven is DENY — UNVERIFIABLE and BLOCKED outcomes can never produce ADMIT. Attestations are cryptographically validated (ES256 signature, issuer, expiry, revocation) and bound to the exact claim and evidence (query_hash, proof_hash) — a token minted for one statement can never admit another.

Usage

Each guard runs its own verification internally and returns a VC document. You pass raw inputs — never a pre-computed result object:

from qwed_infra import NetworkGuard
from qwed_infra.attestation import mint_diagnostic_attestation

net = NetworkGuard()
infra = {
    "subnets": [{"id": "subnet-web", "security_groups": ["sg-web"]}],
    "route_tables": [
        {"subnet_id": "subnet-web", "routes": {"0.0.0.0/0": "igw-main"}},
    ],
    "security_groups": {
        "sg-web": {"ingress": [{"port": 80, "cidr": "0.0.0.0/0"}]},
    },
}

statement = "Traffic from internet to subnet-web on port 80 is safe"

# Mint an attestation bound to THIS claim + evidence (the guard computes the
# same check internally; the token's proof_hash must match its commitment).
diagnostic = NetworkGuard.to_diagnostic(
    net.verify_reachability(infra, "internet", "subnet-web", 80)
)
attestation = mint_diagnostic_attestation(
    diagnostic, engine="NetworkGuard", query=statement
)
if not attestation.is_issued:
    # fail-closed contract: never proceed on an unissued attestation
    raise RuntimeError(f"Attestation unavailable [{attestation.error_code}]")

doc = net.to_verification_context(
    infra,                       # raw topology — the guard verifies this itself
    "internet",
    "subnet-web",
    80,
    formal_statement=statement,
    # optional; without it VERIFIED degrades to UNVERIFIABLE/DENY.
    # A forged, expired, revoked, or non-matching token BLOCKS.
    attestation_token=attestation.token,
)

print(doc.verdict.value)          # -> VERIFIED / BLOCKED / UNVERIFIABLE
print(doc.context.decision.admission.value)  # -> ADMIT / DENY

The same pattern holds for every guard (formal_statement is keyword-only and required). Schematic — define policy/resources etc. as in the guard examples above:

IamGuard().to_verification_context(policy, action, resource, context,
                                   formal_statement="IAM policy is safe to apply")
CostGuard().to_verification_context(resources, budget_monthly,
                                    formal_statement="Estimated cost is within budget")
ArtifactBoundaryGuard().to_verification_context(package_dir="mypkg", pyproject_path="pyproject.toml",
                                                formal_statement="Package boundary is safe to publish")

Using VC documents downstream

from qwed_infra.verification_context import is_valid_document, resolve_document_proof_ref

document = doc.to_dict()   # JSON-serializable dict

if not is_valid_document(document):
    raise ValueError("Invalid VC document — reject")   # schema/verdict inconsistency

admission = document["context"]["decision"]["admission"]   # ADMIT or DENY

if admission == "ADMIT":
    # VERIFIED documents carry a proof_ref bound to the exact evidence;
    # require that it resolves before trusting the decision.
    if not resolve_document_proof_ref(document):
        raise ValueError("VC document proof_ref does not resolve — reject")
    # ... proceed with the gated operation ...
else:
    # DENY: fail closed. BLOCKED/UNVERIFIABLE documents do not require
    # context.evidence.proof_ref (diagnostic proof hashes are separate).
    raise PermissionError(f"Verification denied ({document['verdict']}) — reject")

Store or forward document anywhere JSON goes — release gates, pipeline artifacts, audit logs. The proof_ref binds a VERIFIED decision to the exact evidence that produced it. VC evidence can contain sensitive infrastructure, policy, or cost data — apply your own access control, redaction, and retention rules when storing or forwarding documents downstream.

Attestation trust model: attestations are self-signed by the guard process (ES256, ephemeral key) and cryptographically validated at the admission boundary — signature, issuer, expiry, revocation, plus binding to the exact claim and evidence. This is the interim stage on the path to an external witness/transparency log (ADR-005 in qwed-verification); multi-replica deployments require shared signing keys until replica-key resolution exists.


❓ FAQ

Q: Do I need Terraform installed? A: No. qwed-infra parses .tf files as text using a custom HCL parser (or operates on JSON plans).

Q: Can it verify Kubernetes? A: Currently focuses on AWS Terraform. K8s Manifest verification is on the roadmap (Phase 19).

Q: Why standard pricing? A: We use public On-Demand pricing for "Worst Case" estimation. If you have Enterprise Discounts, qwed-infra ensures you remain safe even at list price.


🗺️ Roadmap

  • ✅ v0.1.0: IAM Z3 Logic, Basic Network Graph, Static Cost Catalog. (Released Jan 2025)
  • ✅ v0.2.0: Fail-closed parser + IAM, NetworkGuard CIDR fix, CI fail-open removal, diagnostic port (audit.py/InfraDiagnosticResult), CostGuard Decimal/unknown types, ArtifactBoundaryGuard.
  • ✅ v0.3.0: Verification Context v1.0 across all four guards (bridge, to_verification_context() adapters, conformance suite) + attestation trust boundary — ES256-signed receipts bound to the exact claim and evidence gate every ADMIT. (Current)
  • 🔮 Next: Docker/deployment artifact verification, K8s manifest support, Azure provider.

🌐 QWED Ecosystem

Package Description Repo
qwed ☑️ Core deterministic AI verification (Math, Logic, Code) GitHub
qwed-infra ☁️ IaC verification (Terraform, IAM, Network, Cost, Artifact) ← you are here GitHub
qwed-finance 🏦 Financial computation verification GitHub
qwed-legal 🏛️ Legal document verification GitHub
qwed-tax 💸 Tax calculation verification GitHub
qwed-mcp 🔌 Model Context Protocol verification GitHub
qwed-a2a 🔄 Agent-to-Agent verification protocol GitHub
qwed-ucp 🛒 Unified Context Protocol GitHub
open-responses 🤖 Guards for OpenAI/LangChain agent outputs GitHub
qwed-learning 📚 Educational content verification GitHub

🛡️ What Does "Verified by QWED" Mean?

When you see the Verified by QWED badge on a repository, it is a technical guarantee that:

  1. Deterministic Verification: The software uses symbolic solvers (Z3, graph theory) — not AI confidence scores — to prove correctness.
  2. Fail-Closed Architecture: If the infrastructure cannot be fully parsed or verified, it is blocked, not silently passed.
  3. No Silent Degradation: Every guard produces a structured diagnostic with clear status (VERIFIED, BLOCKED, UNVERIFIABLE). Partial verification is never presented as proof.

The badge means: "We don't trust the AI. We trust the Math."


⭐ Star History

Star History Chart


📄 Citation

If you use qwed-infra in your research or project:

@software{dass2026qwedinfra,
  author = {Dass, Rahul},
  title = {QWED-Infra: Deterministic Verification for Infrastructure as Code},
  year = {2026},
  publisher = {GitHub},
  url = {https://github.com/QWED-AI/qwed-infra}
}

👥 Contributors

Rahul Dass

Thanks to everyone building QWED. See all contributors →


🙏 Contributors Wanted

Good First Issues

Area What We Need
🧪 Testing Edge cases for guards (NetworkGuard, ArtifactBoundaryGuard)
🐛 Bugs Fix issues or report new ones
📝 Docs Improve examples and tutorials
🔧 SDKs Terraform plan JSON integration

→ Read CONTRIBUTING.md


📄 License

Apache 2.0 - Open Source.

Safe Infrastructure is Scalable Infrastructure.
Built by QWED-AI

Metadata

Release files for qwed-infra 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qwed-infra 0.3.0
File Size Uploaded
qwed_infra-0.3.0.tar.gz 122.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for qwed-infra 0.3.0
File Interpreter ABI Platform
qwed_infra-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 182.3 kB

Release files / qwed_infra-0.3.0.tar.gz

Download URL qwed_infra-0.3.0.tar.gz
Size 122.7 kB
Tags Source
SHA-256 checksum
How to use checksums
9e74e4b8436977222d5d5c587a04168b5a76c9b7b07e6ab2a660d943f7e22a1b
BLAKE2b-256 checksum
How to use checksums
abc52a9d170d71da2425be1e35e46d1369c543aeb51fb9f38858cc05b5742d56
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.

Transparency log

Release files / qwed_infra-0.3.0-py3-none-any.whl

Download URL qwed_infra-0.3.0-py3-none-any.whl
Size 59.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
204e7da31ade34c6cddb0ae06c69815a315dec8d5380f50fca787bbdacd06365
BLAKE2b-256 checksum
How to use checksums
b365c707bc445b32aacd8345c6009c9a898d202a2a3294a58052dcdb7e531fe7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page