Iac security
Hardening rules for Terraform, CloudFormation, and Pulumi: state, providers, drift, secretsFrom its SKILL.md
npx -y skills add ShieldNet-360/secure-vibe --skill iac-securityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 15 stars15 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.0 KB, ~1.3k tokens by cl100k_base, as published. Nobody here has run it
Infrastructure-as-Code Security
Rules (for AI agents)
ALWAYS
- Pin every provider/module to an exact version or a pessimistic constraint
(
~> 5.42); never>= 0or unpinnedlatest. - Configure a remote backend with encryption at rest, server-side state locking,
and versioning (Terraform:
s3+ DynamoDB lock table withkms_key_id; Pulumi: the managed backend ors3://?kmskey=; CloudFormation: managed by AWS). - Encrypt every persistent resource by default with a customer-managed KMS key: S3 buckets, EBS volumes, RDS, EFS, DynamoDB, SQS, SNS, CloudWatch log groups.
- Tag every resource with
owner,environment,cost-center, anddata-classificationvia a default tags block. - Run
terraform plan(orpulumi preview,aws cloudformation deploy --no-execute-changeset) in CI and require a human approval beforeapplyon production stacks. - Add a drift-detection job that runs daily and opens an issue when actual cloud
state diverges from code (Terraform Cloud drift detection,
pulumi refresh,cfn-drift-detect). - Use IAM Conditions to scope every role:
aws:SourceArn,aws:SourceAccount,aws:PrincipalOrgID, and TLS-only access policies on storage.
NEVER
- Hardcode provider credentials in the code or
.tfvars(access_key,secret_key,client_secret,service_account_key). Use OIDC federation from CI, the provider's instance metadata service, or a secret manager. - Commit
terraform.tfstate,terraform.tfstate.backup,.pulumi/, or any*.tfvarscontaining real secrets. They contain plaintext secrets even if the code references variables. - Use
local_exec/null_resourceto fetch secrets at apply time and stash them in state. State is queryable plaintext by anyone with backend read access. - Open security groups / firewall rules to
0.0.0.0/0for ports 22, 3389, 3306, 5432, 1433, 6379, 27017, 9200, 11211 — even for "just dev". Use bastion or VPN. - Grant
*:*(wildcard action on wildcard resource) IAM policies. Useiam:PassRolewith explicit resource ARNs. - Disable provider TLS verification (
skip_tls_verify,insecure = true). - Use
count = 0to "soft-delete" resources you actually want gone — destroy them.
KNOWN FALSE POSITIVES
- Bastion hosts intentionally exposed on port 22 to the internet with hardened configurations are not the same risk as opening RDS to the world. Document the exception inline.
- Public CloudFront distributions, ALB listeners on 80/443, API Gateways, and Lambda function URLs that are meant to be internet-facing.
- Bootstrap resources (the S3 bucket and DynamoDB lock table the backend itself
uses) must exist before remote state can; this chicken-and-egg is usually
bootstrapped by a one-time
localbackend that's then migrated.
Context (for humans)
IaC mistakes scale: a single bad module gets terraform apply'd into hundreds of
accounts. The classes of issue we cover here — state-secret leaks, unbounded
network exposure, wildcard IAM, drift — are exactly what CIS and the cloud
providers' own well-architected reviews flag the most. AI assistants are
particularly prone to generating "works on my machine" Terraform that pins nothing
and uses local state; this skill is the counterbalance.
Verify & lock (triaging a finding)
A scanner/review hit is a candidate, not a confirmed bug. Confirm it, fix it, then lock it so it can't come back.
- Confirm it's real (inspect the resolved plan, not the source). Run
terraform plan/pulumi preview/cfnchange-set and inspect the resolved resource, since a variable, module default, or default-tags block can flip the verdict: a literal0.0.0.0/0ingress on 22/3306/5432, a public S3 ACL or bucket policy, an unencrypted volume/bucket/RDS (nokms_key_id), a*:*IAM action/resource, an unpinned provider, or local/unencrypted state. For secrets, grep the plan and the state file — referencing a variable still leaves plaintext in state. Real if the planned resource has the bad property; FP if a constraint already narrows it (e.g. an intentional bastion on 22). - Fix, then lock with a regression test (unit or integration — dev's
call): add a policy-as-code check in CI (conftest/OPA, checkov, trivy config,
or
terraform test) asserting the resource stays constrained — no0.0.0.0/0on admin ports, encryption with a CMK, private ACL, no wildcard IAM, providers pinned, remote encrypted state — plus a benign config that passes so the rule is exercised. Commit it so the guard can't be silently dropped.
References
checklists/terraform_hardening.yamlchecklists/cloudformation_hardening.yaml- CIS Benchmark for Amazon Web Services Foundations.
- Terraform Recommended Practices.
- NIST SP 800-53 Rev. 5 control catalog.
What ships with it: 3 files
9.8 KB alongside SKILL.md
checklists/
tests/
- corpus.json5.0 KB