Continuous security design review

Every design decision, reviewed. Every review, provable.

Attestral reads your Terraform, architecture docs, and MCP configs, builds one system model, and reviews it on every change. Findings map to NIST, ASVS, SOC 2, and OWASP Agentic, and land in a tamper-evident evidence chain. It then compiles the reviewed design into a default-deny runtime policy and diffs live telemetry back against it, so what you run and what you reviewed stay the same thing.

$ pip install attestral
★ Star on GitHub
PyPI v0.2.0 Apache 2.0 Python 3.10+ Zero required deps Runs fully offline GitHub Code Scanning NIST · ASVS · SOC 2 · OWASP Agentic

Design review is where security is cheapest. It is also where the tooling is oldest.

The enterprise threat modeling market just consolidated into a single private-equity-owned vendor, priced for the Fortune 500 and built on decade-old architecture. Everyone else reviews designs in spreadsheets and wiki templates: slow, inconsistent, and with nothing to show an auditor. And the fastest-growing attack surface, AI agents and their tools, is the part legacy platforms understand least.

A security review you can't prove happened is an opinion, not a control.

Three layers. Nothing hidden.

Regulated buyers can't accept "the AI said so." Attestral separates what is deterministic from what is model-reasoned, and labels every finding with its origin.

Layer 1 · Deterministic

Typed rules over a unified model

Terraform, MCP configs, and design docs become one graph of components, edges, and trust boundaries. YAML rules with structured matchers fire against that graph. There is no eval anywhere in the path, and an unknown matcher simply never matches.

Layer 2 · Reasoning

LLM threat elicitation, clearly tagged

A frontier model reviews the same graph for design-level gaps rules can't express: trust-boundary violations, tool-permission escalation, prompt-injection paths, handoff confusion. Optional, and always labeled.

Layer 3 · Evidence

A chain you can hand to an auditor

Findings, mitigations, and sign-offs get committed to a SHA-256 hash chain. Every finding carries its NIST 800-53, ASVS, SOC 2, and OWASP Agentic references. Export the review once and anyone can verify it offline, years later. Emit it as SARIF and the same findings land in your GitHub Security tab and right on the pull request.

$ attestral scan ./platform --fail-on high
  [CRITICAL] ATL-003  IAM policy grants wildcard actions  (aws_iam_policy.admin)
  [CRITICAL] ATL-103  Shell-capable MCP server configured  (mcp_server.shell)
  [HIGH    ] ATL-102  Filesystem MCP server rooted at a broad path  (mcp_server.filesystem)
7 components · 10 findings · chain head c31f8e…9bd4
$ attestral verify review.json
chain VALID ✅

Built for the review board, not just the terminal.

On every change

PR design-diff

Each pull request is diffed against the system model. New attack surface (a fresh public edge, a broader tool permission) gets flagged before merge instead of at the annual review.

Agent-native

MCP and agent coverage first

Tool servers, capability scopes, and multi-agent handoffs are first-class parts of the model, not an afterthought bolted onto a diagramming canvas.

Roadmap

Model import

Bring your existing threat models with you. Import from legacy platform exports and keep your review history, chain-sealed from day one. On the roadmap.

The review is the policy. The policy is the proof.

Scanners stop at findings. Gateways enforce policies nobody reviewed. Attestral makes them the same artifact. The reviewed system model compiles into an mcp-guard runtime policy stamped with the review's chain head, and anything the review never saw counts as drift.

attestral scan

Attest

Terraform + MCP configs become one system model, reviewed against typed rules and (optionally) LLM reasoning. Findings are hash-chained.

attestral compile

Enforce

The reviewed model compiles to a default-deny policy. Denied capabilities carry the rule id that denied them, filesystem roots narrow to what was reviewed, and the policy header binds to the review's chain head.

attestral drift

Prove

Runtime telemetry gets diffed against the compiled policy. An unattested server, a denied invocation, an out-of-scope path: each one is a drift finding. Deployment and review can no longer quietly diverge.

$ attestral compile ./platform -o policy.yaml
wrote policy.yaml · default deny · 1 allowed, 3 denied
  [DENY ] shell  (denied by attested design review: ATL-103)
$ attestral drift policy.yaml events.jsonl --fail-on-drift
  [CRITICAL] DRF-001  Unattested server observed at runtime  (mcp_server.jira-sync)
  [HIGH    ] DRF-003  Filesystem access outside attested roots  (mcp_server.docs)
DRIFT: deployment no longer matches the attested design

Start in sixty seconds.

No account, no server, no API key. The whole attest → prove → enforce → detect loop runs on your laptop, under Apache 2.0.

$ pip install attestral
$ attestral scan ./my-project              # attest: one system model, reviewed
$ attestral verify review.json           # prove: chain VALID ✅
$ attestral compile ./my-project -o policy.yaml  # enforce: default-deny policy
$ attestral drift policy.yaml events.jsonl  # detect: runtime vs. reviewed design

Gate every deploy in CI with the GitHub Action:

# .github/workflows/drift.yml
- uses: attestral-labs/attestral@v1
  with:
    policy: policy.yaml
    events: events.jsonl