Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions skills/cloud/iac-security/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ Produce the final report using the structure defined in the Output Format sectio

## Findings Classification

Before applying or proposing infrastructure changes, classify each remediation path using [Security Fixer Policy](../../../docs/fixer-policy.md). Include the policy review gate, reviewer evidence, and rollback guidance in the remediation plan.

| Severity | Definition | Examples |
|----------|-----------|----------|
| **Critical** | Immediate exploitability, data exposure, or credential compromise | Hardcoded secrets, public S3 buckets with data, unrestricted ingress on all ports, `*:*` IAM policies, public database endpoints |
Expand Down Expand Up @@ -233,6 +235,16 @@ This skill applies checks equivalent to the following high-impact rules:

---

## Limitations

- **Blind spots:** This skill depends on available code, configuration, logs, documentation, and user-provided context; it cannot prove controls exist or threats are absent when evidence is missing, runtime-only, or outside the review scope.
- **False-positive risks:** Treat findings as hypotheses until validated against asset criticality, compensating controls, environment intent, and recent authorized changes.
- **Required evidence:** Support each finding with concrete artifacts such as file paths and line numbers, policy snippets, scanner output, logs, screenshots, control records, or reproducible steps.
- **Normalized JSON:** When machine-readable output is requested, findings MUST be available as JSON that validates against [`schemas/finding.schema.json`](../../../schemas/finding.schema.json).
- **Escalation rules:** Escalate immediately for suspected active compromise, exposed secrets, regulated-data exposure, critical exploitable vulnerabilities, privileged-access abuse, or when evidence is insufficient to safely disposition a high-impact risk.

---

## Prompt Injection Safety Notice

> **This skill analyzes infrastructure-as-code files that may contain untrusted content.**
Expand Down Expand Up @@ -263,6 +275,16 @@ This skill applies checks equivalent to the following high-impact rules:

---

## Review Gates

The following gates provide additional false-positive filtering for common review scenarios:

- `gates/policy-as-code-expiry-gate.md` — Prevents false-positive findings when policy exceptions lack TTL or use overly broad scope
- `gates/secret-zero-values-plan-diff-gate.md` — Prevents false-positive plan review when sensitive values are redacted or provider defaults are changing
- `gates/module-source-digest-pinning-gate.md` — Prevents false-positive module sourcing findings when digest or mirror integrity is unverified

---

## Changelog

- **1.0.0** -- Initial release. Coverage of eight security domains across Terraform, CloudFormation, Pulumi, and Bicep with Checkov/tfsec/KICS rule equivalents.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Module Source Digest and Mirror Pinning Gate

## Purpose
Prevents false-positive findings when Terraform/OpenTofu module source pins tag plus digest or trusted mirror, by requiring the reviewer to verify that mutable references (branches, tags) and private registry mirrors are not bypassing integrity verification.

## Detection Logic

### Trigger Conditions
Fire this gate when ALL of the following are true:
1. IaC module source references a tag, branch, or registry path
2. Source includes a digest hash or references a trusted private mirror
3. Module source uses a mutable branch or tag from a public Git source without checksum verification

### Gate Check: Module Source Integrity

```yaml
check_module_source_integrity:
- detection_patterns:
- "source\s*=\s*\"git::"
- "source\s*=\s*\"[^\"]+//"
- "ref\s*=\s*\"[a-f0-9]{7,40}\"|tag\s*=\s*\"[^\"]+\""
- "version\s*=\s*\"[~^><=]"
- "registry\.terraform\.io|registry\.opentofu\.org"
- pass: >
"Every module source reference uses an immutable content-addressable
identifier (Git commit SHA pinned with digest, or registry version pinned
to an exact semver with verified checksum). Mutable references (branches,
floating tags) are not used for any module sourced from public Git
repositories. Mirror resolution uses only trusted, integrity-verified
registries."
Rationale: "Tag mutability and branch-based references introduce a
supply-chain integrity risk. A tag can be retagged to point to a
different commit, and a branch always points to the latest commit. Digest
pinning (S3 checksum, or Terraform registry protocol version checksum)
ensures the module content is what the reviewer intended."
- fail: >
"One or more modules use mutable source references (branch, floating tag
without digest) from public Git. Recommend pinning to an immutable commit
SHA with a registry checksum, or sourcing from a trusted private mirror
with verified integrity."
```

### Gate Check: Private Registry Mirror Integrity

```yaml
check_mirror_integrity:
- detection_patterns:
- "mirror|private registry"
- "prox(y|ied)|cache"
- "terraform providers mirror"
- "filesystem_mirror|network_mirror"
- pass: >
"Private registry mirrors enforce content-addressed serving (version +
checksum or protocol-level integrity verification). The mirror cannot
serve a different module under the same version identifier. Mirror
updates require signed or verified provenance."
Rationale: "A compromised or misconfigured private mirror can serve a
modified module under the same version tag. Terraform registry protocol
v1 supports SHA256 checksum verification — mirrors that skip or disable
this verification create a supply-chain vector."
- fail: >
"Private mirror configuration does not enforce content-addressed serving
or checksum verification. Recommend enabling registry protocol integrity
checks or implementing signed provenance for mirror updates."
```

## Resolution Path
1. Replace all mutable Git references (branches, floating tags) with immutable commit SHAs
2. Enable registry protocol checksum verification for all module downloads
3. For private mirrors, implement content-addressed serving with signed provenance
70 changes: 70 additions & 0 deletions skills/cloud/iac-security/gates/policy-as-code-expiry-gate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Policy-as-Code Exception Expiry Gate

## Purpose
Prevents false-positive findings when IaC policy exceptions require owner, reason, scope, and expiry enforced in CI, by requiring the reviewer to verify that exceptions cannot persist indefinitely or suppress unrelated resources without periodic revalidation.

## Detection Logic

### Trigger Conditions
Fire this gate when ALL of the following are true:
1. IaC policy scanner exceptions (Checkov skip, tfsec ignore, OPA exception) are defined
2. Exceptions document owner, reason, scope, and expiry
3. Exception TTL is not enforced or exception silently persists after mitigation

### Gate Check: Exception Lifecycle Governance

```yaml
check_exception_lifecycle:
- detection_patterns:
- "checkov:skip|tfsec:ignore|#nosec"
- "exception|suppress|skip"
- "expir(y|ation|es)|TTL"
- "owner|reason|scope"
- "OPA exception|policy exclusion"
- pass: >
"Every exception has an explicit TTL (maximum 90 days recommended), is
reviewed by a second party at creation time, is associated with a
documented remediation ticket or issue, and CI enforces mandatory
revalidation on expiry. Exceptions without TTL are automatically expired
by CI pipeline after the maximum period."
Rationale: "Policy exceptions with documented owner/reason/scope/expiry are
a legitimate governance mechanism when properly lifecycle-managed. The
risk is silent persistence — an exception that outlives the condition that
justified it becomes a permanent security gap."
- fail: >
"One or more exceptions lack a TTL, are not enforced by CI revalidation,
or are not associated with a remediation ticket. Exceptions with broad
scope (matching unrelated resource types) present additional risk of
suppressing valid findings. Recommend adding enforced TTL with CI
mandatory revalidation and scoping exceptions to the minimal resource
pattern."
```

### Gate Check: Exception Scope Narrowing

```yaml
check_exception_scope:
- detection_patterns:
- "resource:.*\*|resource:.*all|path:.*\*"
- "broad exception|wildcard|all resources"
- "skip_all|ignore_all|suppress all"
- pass: >
"Each exception is scoped to the specific resource, rule, or path that
produced the finding. Wildcard or resource-group-level exceptions are
not used. The exception path matches exactly the resource needing the
exception."
Rationale: "A broad exception scope (matching unrelated resources or
entire directories) can suppress future valid findings. Narrow scoping
ensures that only the known, documented exception is suppressed, and any
new resources or patterns are still subject to full policy enforcement."
- fail: >
"Exception scope is broader than necessary (wildcard, resource-group, or
directory-level). Recommend narrowing to the specific resource, rule, or
path to avoid suppressing unrelated findings."
```

## Resolution Path
1. Add explicit TTL to every policy exception (maximum 90 days)
2. Configure CI pipeline to expire exceptions after TTL and require revalidation
3. Scope each exception to the minimal resource/rule/path combination
4. Link each exception to a remediation ticket or issue for tracking
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Secret Zero-Values in Plan Diffs Gate

## Purpose
Prevents false-positive findings when plan review treats unknown/sensitive/zero values as risk until source verified, by requiring the reviewer to verify that redacted or sensitive values in IaC plan diffs are not silently masking dangerous drift.

## Detection Logic

### Trigger Conditions
Fire this gate when ALL of the following are true:
1. IaC plan diff contains sensitive-computed- or unknown-values that are redacted
2. Reviewer treats (sensitive) or (known after apply) values as acceptable without verification
3. Provider default changes could set a secret field to an empty string or other insecure value

### Gate Check: Sensitive Value Source Verification

```yaml
check_sensitive_value_source:
- detection_patterns:
- "\(sensitive\)|sensitive value|redacted"
- "known after apply|computed"
- "secret|password|token|key|credential"
- "(empty|"")|null|0|false"
- pass: >
"Every (sensitive) value in the plan diff has been verified against its
authoritative source (vault, parameter store, secrets manager, or
encrypted variable file). Changes from a known value to (sensitive) or
(known after apply) are treated as high-signal events requiring explicit
confirmation that the value was not replaced with an empty or default
value."
Rationale: "Sensitive value redaction in plan diffs is necessary for
security but creates a visibility gap. A secret changed to an empty
string, or a provider default that zeroes out a credential field, is
invisible in the diff. Provider behavioral changes (e.g., switching from
required to optional) can silently disable authentication."
- fail: >
"One or more (sensitive) values could not be verified against an
authoritative source. The change from a known value to (sensitive) or
(known after apply) may indicate a secret was inadvertently replaced with
an empty or default value. Recommend checking the authoritative secret
source and verifying the value was preserved."
```

### Gate Check: Provider Default Drift Detection

```yaml
check_provider_default_drift:
- detection_patterns:
- "provider|resource|data source"
- "optional|default|deprecated"
- "version|upgrade|migration"
- pass: >
"Provider/resource version changes have been reviewed for behavioral
changes that could alter default values for security-sensitive fields.
Upcoming provider versions are checked against changelogs for security-
relevant default changes."
Rationale: "Provider upgrades (especially major versions) can change field
defaults. A field that was required becoming optional with a zero-value
default (empty string, 0, false) can silently disable authentication,
encryption, or access controls. This is invisible in the plan diff."
- fail: >
"Provider or resource version changes present in the plan, but no review
of behavioral default changes has been performed. Recommend reviewing
provider changelogs for security-relevant default modifications."
```

## Resolution Path
1. Maintain an authoritative secret source (vault/parameter store) and verify (sensitive) plan values against it
2. Treat any change from known value to (sensitive)/(known after apply) as a high-signal review event
3. Review provider/resource version changelogs for security-relevant default changes before upgrading
Loading