Skip to main content
TirithOpen-source IaC governance · Apache-2.0

Stop unsafe IaCbefore it is applied.

curl -fsSL https://stackguardian.github.io/tirith/skill.sh | sh # then, in your agent: "Add a Tirith policy gate to our pipeline"
  • Any agent with a shell
  • Reads the real schema
  • You review the PR

Plug IaC governance into any pipeline you already run. Policies are JSON, not a program in Rego or Python. Tirith evaluates the plan on your own runner, enforces one policy set across repositories when you want one, and returns a single verdict before the change is applied.

Your IaC tool produces the plan, Tirith checks it, and the exit code decides.

  1. 1

    Your IaC tool plans

    tofu show -json tfplan > plan.json

  2. 2

    Tirith reads the plan

    -input-path plan.json

  3. 3

    Policies test the change

    commit rules under .tirith/policies

  4. 4

    CI continues or stops

    --fail-on-error, so a violation exits 3

.claude/skills/tirith-policies/
# 1 · give the agent the vocabulary, once per repository
curl -fsSL https://stackguardian.github.io/tirith/skill.sh | sh

# 2 · then ask for the gate, in your own words
"Add a Tirith policy gate to our pipeline"

Covers every target in the tabs beside this one, so the agent writes for whichever it finds. It carries the install, the plan export and the exit-code contract.

Claude, Cursor and Codex setup

Five chapters in a public demo repository, from first gate to published state.

Phase 01 · Adopt · local

Add Tirith with local policies

Local policies

The first change adds three policy files and one pipeline step. Evaluation happens on your own runner, against policies committed beside the code.

CHANGE4 files · +83
permissions:
  pull-requests: write
  checks: write

- run: terraform show -json tfplan > plan.json
- uses: StackGuardian/tirith-iac-governance-action@v2.1.1
  with:
    fail-on-error: true
Real PR result3 passed
  • AWS provider is configured for us-east-1
  • Every S3 bucket name starts with demo-
  • Every S3 bucket declares an Owner tag

Tirith runs before Apply and posts the result as a check and pull-request comment.

Two checks, and only one of them needs a plan.

Change the threshold below and watch the verdict update.

SPECIMENstackguardian/terraform_plan
CHANGE THE RULE
condition.value100 GiBLessThanEqualTo
20500
CHANGE THE DOCUMENT
{  "meta": {    "version": "v1",    "required_provider": "stackguardian/terraform_plan"  },  "evaluators": [    {      "id": "volume_within_limit",      "description": "No volume may exceed the standard size",      "provider_args": {        "operation_type": "attribute",        "terraform_resource_type": "aws_ebs_volume",        "terraform_resource_attribute": "size"      },      "condition": {        "type": "LessThanEqualTo",        "value": 100      }    }  ],  "eval_expression": "volume_within_limit"}
provider returns one value per matching resource instanceReference →
stdoutexit 3
$ tirith --fail-on-error -policy-path policy.json -input-path plan.jsonCheck: volume_within_limit  FAILED    1. PASSED: `40` is less than equal to `100`    2. PASSED: `60` is less than equal to `100`    3. FAILED: `120` is not less than or equal to `100`    4. FAILED: `400` is not less than or equal to `100`    5. PASSED: `90` is less than equal to `100`    6. FAILED: `320` is not less than or equal to `100`    7. PASSED: `30` is less than equal to `100`    8. FAILED: `160` is not less than or equal to `100`    9. FAILED: `440` is not less than or equal to `100`    10. PASSED: `45` is less than equal to `100` Passed: 0 Failed: 1 Skipped: 0 Final expression used:-> volume_within_limit$ echo $?3

Which resource failed?

The CLI output lists the tested values, but not their resource addresses. tirith ui maps the values back to the resources below.

  • aws_ebs_volume.api_data40 GiB
  • aws_ebs_volume.cache60 GiB
  • aws_ebs_volume.search_index120 GiB
  • aws_ebs_volume.metrics_cold400 GiB
  • aws_ebs_volume.ledger_primary90 GiB
  • aws_ebs_volume.media_ingest320 GiB
  • aws_ebs_volume.session_store30 GiB
  • aws_ebs_volume.registry_layers160 GiB
  • aws_ebs_volume.warehouse_spill440 GiB
  • aws_ebs_volume.vault_data45 GiB

This browser demo uses sample plan.json data and a Tirith-compatible evaluator. The policy syntax, messages, and exit codes mirror Tirith; install Tirith to evaluate real input documents.

Start with one rule.

A catalogue covers the mistakes everyone makes. Pick the rule only you can state: something your team already checks by hand.

A policy is data
JSON with conditions in it. No rule language, no plugin.
So an agent can write it
The skill pack gives it the real condition list, so it cannot invent one.
The engine decides, not the model
Same evaluator, same exit code, your runner.

Explore the focused guides

Being built next

  • Blast radius as one rulePlannedCount what a change destroys, not what each resource looks like.
  • Before and after, not just afterPlannedMake the transition the subject: deletion protection switched off, a CIDR widened.
  • Applied plan equals approved planPlannedA verify step that refuses a plan it has not seen approved.
  • A skipped check can never read as a passIn devA rule that could not run will be reported as unevaluated, never as success.

The whole roadmap, and roughly when

Get involved

  • Akshat0694
  • arunim2405
  • refeed
  • amitrakshar01
  • naveen8801
  • samriddhi99
  • archana-1209
  • AkashS0510
  • s0la
  • sonaliarora707
  • larisoncarvalho
  • Aman1905
  • BrainButcher101
  • Denish3436
  • gvsl60
  • sranish
  • ritikaaaa177
  • tejasvi541
Built by the community.

Tirith is built in the open by StackGuardian engineers and external contributors. It is licensed under Apache 2.0 and governed publicly. Contributions do not need to be large: a tested policy, a CI example for an underserved system, or a reproducible bug report can be far more valuable than a star.

Influence our roadmap by asking for a feature or watching for releases.