Flecto reads your Terraform plan and Kubernetes changes and posts a plain-English risk summary on every pull request, blocking the dangerous ones.
That is a real comment on a
real pull request
you can open right now. The PR says it is about partner access and changes eight
lines; it opens the web tier to the internet, turns off the bucket's
public-access protection, and widens an IAM policy to s3:* on *.
One sticky comment, updated in place on every push. Exit code 1, so the build
fails before the change ships.
The same gate on an ordinary change reports no findings and passes. That matters as much: a check that fires on everything gets uninstalled in a week.
The same report as text, and what a plan with existing state adds
The comment above, as flecto plan prints it:
❌ Check failing — 30 changes in 1 file — 0 changed, 30 added, 0 removed.
Policy: 6 errors.
aws_security_group.web.ingress[0].cidr_blocks[0]
terraform-security-group-open-ingress
Security group ingress will accept traffic from the whole internet
(0.0.0.0/0). Restrict the source to a known CIDR, a prefix list, or
another security group.
aws_s3_bucket_public_access_block.uploads.block_public_acls (+3 more)
terraform-s3-public-access-block-disabled
S3 public access block is being turned off or removed.
aws_iam_role_policy.app.policy
terraform-iam-wildcard
IAM policy grants a wildcard action or resource ("*").
The example repository has no Terraform state, so every resource shows as
create. With existing state, a plan that replaces a database also reports:
aws_db_instance.main.#action
terraform-stateful-resource-destroyed
Terraform will destroy a stateful resource. Its data does not survive.
Take a final snapshot, or add a prevent_destroy lifecycle block, before
applying.
Flecto PR Risk is on the
GitHub Marketplace, so
myselfsiddharth/Flecto@v4.4.2 is the whole reference.
Terraform — point it at the plan JSON:
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v7
- run: |
terraform plan -out=tf.plan
terraform show -json tf.plan > plan.json
- uses: myselfsiddharth/Flecto@v4.4.2
with:
terraform-plan: plan.json
fail-on: errorKubernetes — render your manifests, then diff them against the PR's base:
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- run: helm template ./chart > rendered.yaml
- uses: myselfsiddharth/Flecto@v4.4.2
with:
targets: rendered.yaml
policies: kubernetesFlecto never invokes terraform, helm, kustomize, sops, or age, so
nothing extra has to exist on the runner. → CI guide
- A database about to be destroyed —
terraform plansaysreplace, the diff says the data does not survive - Ingress widened to the world —
10.0.0.0/8→0.0.0.0/0on a security group - An IAM policy gone wildcard —
Action: "*"where it used to be scoped - S3 public-access protection switched off — the block removed, not just loosened
- A container turned privileged, or
runAsNonRootquietly weakened - Resource limits removed from a Deployment, so one pod can starve a node
- An image tag unpinned —
:1.4.0→:latest - A new recipient on a SOPS file — someone who could not decrypt it now can
debug: truein a 40-line formatting diff, or a connection pool quadrupled
Rules live in policy packs you can extend, remap, or replace.
| A CLI | flecto ci, flecto plan, flecto compare — plain exit codes, any runner → CLI reference |
| A file watcher | flecto watch reports changes as you edit → Getting started |
| A webhook / command trigger | Restart a service or notify an endpoint on change → Webhooks |
| An MCP server | Read-only diff, check, explain tools for agents → MCP |
| An editor language server | flecto lsp — diagnostics while you type → Editor |
| A drift detector | flecto-drift compares declared config against what is running → Drift |
Flecto runs inside your merge path. The JSON envelope
(schema_version: "2.0"), exit codes (0 clean, 1 failed — it fails
closed), .flectorc keys, and command and flag names follow
semver, and no breaking change to them ships without a
minor release that warns first. The one exception is a security fix.
Terminal output, message wording, and anything under src/ are deliberately
not stable — parse --format json.
| Guide | Covers |
|---|---|
| Getting started | A full walkthrough, from install to a failing build |
| CI | Baselines, fail triggers, output formats, the bundled Actions, pinning |
| Terraform plans | Reviewing terraform show -json output and the terraform pack |
| Kubernetes | Diffing rendered Helm/Kustomize manifests before they reach a cluster |
| Comparison | Honest comparison with Checkov, Trivy/tfsec, conftest/OPA, tf-summarize, dyff |
| Supported formats | YAML, JSON, TOML, INI, dotenv, age — and what each one accepts |
| Encrypted files | SOPS and age: what is detected, why nothing is decrypted |
| Configuration | .flectorc, profiles, ignore patterns, array identity, masking |
| CLI reference | Every command, flag, and exit code |
| Policy packs | Writing declarative rules |
| Plugins · Cookbook | Rules that need real code |
| Webhooks and commands | Envelope shape, delivery modes, command environment |
| MCP server | Read-only diff/check/explain tools for agents, and the security posture |
| Explain | Opt-in model narration of a diff: what is sent, what it can never do, cost |
| Editor diagnostics | flecto lsp setup for Neovim, Helix, Emacs |
| Live drift | flecto-drift: declared config versus what is actually running |
| Performance | Where time goes at scale |
| Stability | What you can build against, and the deprecation sequence |
| Troubleshooting | When something doesn't behave |
| Migrating to 4.0 | The five breaking changes, and whether they affect you |
| Changelog | Release history and migration notes |
- Questions and ideas — Discussions
- Bugs and requests — Issues
- Contributing — CONTRIBUTING.md · Code of Conduct
- Security — SECURITY.md, private disclosure only
- Roadmap — Milestones
Released under the MIT License.
