Skip to content

Audit rules reference

llms.txt lists every page for an agent

This is the reference for every rule chant audit can report. Each finding in a report links to its rule here.

Each rule is tagged with its tier — merge-worthy (a security or correctness issue worth a PR) or report-only (hygiene) — and its fix kind — deterministic (a safe mechanical fix the report can apply as a diff) or guidance (needs a judgement call). Where an open-source tool checks the same thing, the rule says so under Prior art; the Prior art section at the end lists every tool the rules on this page credit.

Also applied to Forgejo workflows, which are GitHub-dialect.

Duplicate workflow name (report-only · guidance)

Give each workflow a unique name:.

Empty matrix dimension (merge-worthy · guidance)

Remove the empty matrix axis or give it values; an empty axis produces zero jobs.

Prior artactionlint Unexpected empty mappings (overlaps)

needs references a non-existent job (merge-worthy · guidance)

Fix the needs: target to name a real job.

Prior artactionlint Job dependencies validation (equivalent)

Missing job permissions on a sensitive trigger (merge-worthy · guidance)

Add an explicit least-privilege permissions: block to jobs under pull_request_target/workflow_dispatch.

AuthorityOSSF Scorecard — Token-Permissions · GitHub — Automatic token authentication
Prior artpoutine default_permissions_on_risky_events (overlaps) · zizmor excessive-permissions (overlaps) · OpenSSF Scorecard Token-Permissions (overlaps)

No explicit permissions block (merge-worthy · deterministic)

Add a top-level permissions: \{ contents: read } and widen only where a job needs it.

AuthorityOSSF Scorecard — Token-Permissions · GitHub — Automatic token authentication
Prior artzizmor excessive-permissions (overlaps) · OpenSSF Scorecard Token-Permissions (overlaps)

pull_request_target checks out untrusted code (merge-worthy · guidance)

Don’t check out / run PR head code under pull_request_target; split into a privileged + unprivileged workflow.

AuthorityGitHub Security Lab — Preventing pwn requests
Prior artOpenSSF Scorecard Dangerous-Workflow (overlaps) · octoscan dangerous-checkout (overlaps) · poutine untrusted_checkout_exec (overlaps)

Circular needs chain (merge-worthy · guidance)

Break the cycle in the job dependency graph.

Prior artactionlint Job dependencies validation (equivalent)

actions/checkout not pinned to a SHA (merge-worthy · deterministic)

Pin actions/checkout to a full 40-char commit SHA.

AuthorityOSSF Scorecard — Pinned-Dependencies · GitHub — Using third-party actions
Prior artzizmor unpinned-uses (overlaps) · OpenSSF Scorecard Pinned-Dependencies (overlaps)

Job without timeout-minutes (report-only · guidance)

Add timeout-minutes: to bound runaway jobs.

Deprecated ::set-output (report-only · guidance)

Replace ::set-output with $GITHUB_OUTPUT.

Prior artactionlint Check deprecated workflow commands (overlaps)

Missing concurrency block (report-only · guidance)

Add a concurrency: group to deploy workflows.

Prior artzizmor concurrency-limits (overlaps)

Unrestricted pull_request_target (merge-worthy · guidance)

Gate pull_request_target jobs and avoid running untrusted code with elevated scope.

AuthorityGitHub Security Lab — Preventing pwn requests
Prior artzizmor dangerous-triggers (overlaps)

Secret used without environment protection (report-only · guidance)

Move secret-consuming jobs behind a protected environment:.

Prior artzizmor secrets-outside-env (equivalent)

Cleanup step without if: always() (report-only · guidance)

Add if: always() to cleanup steps.

Workflow with no triggers (merge-worthy · guidance)

Add an on: trigger; the workflow never runs without one.

Prior artactionlint Missing required keys and key duplicates (overlaps)

Action not pinned to a commit SHA (merge-worthy · deterministic)

Pin the action to a full commit SHA instead of a tag/branch.

AuthorityOSSF Scorecard — Pinned-Dependencies · GitHub — Using third-party actions
Prior artzizmor unpinned-uses (overlaps) · OpenSSF Scorecard Pinned-Dependencies (overlaps)

Container image not pinned to a digest (merge-worthy · deterministic)

Pin the image to an immutable @sha256: digest.

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior artzizmor unpinned-images (overlaps)

Possible action impersonation (merge-worthy · guidance)

Verify the action owner/slug; it resembles a well-known action.

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior artzizmor typosquat-uses (equivalent)

Archived/abandoned or vulnerable action (merge-worthy · guidance)

Replace the archived action or one with a disclosed security issue.

Prior artzizmor archived-uses (overlaps) · zizmor known-vulnerable-actions (overlaps)

Blanket write-all permissions (merge-worthy · deterministic)

Replace write-all with the specific scopes the jobs need (default contents: read).

AuthorityOSSF Scorecard — Token-Permissions · GitHub — Automatic token authentication
Prior artzizmor excessive-permissions (overlaps) · OpenSSF Scorecard Token-Permissions (overlaps)

Write permissions granted workflow-wide (merge-worthy · guidance)

Move write scopes to the single job that needs them; keep the workflow least-privilege.

AuthorityOSSF Scorecard — Token-Permissions · GitHub — Automatic token authentication
Prior artzizmor excessive-permissions (overlaps) · OpenSSF Scorecard Token-Permissions (overlaps)

Elevated token on an untrusted-code trigger (merge-worthy · guidance)

Drop the elevated permissions: on triggers that can run untrusted code.

AuthorityGitHub Security Lab — Preventing pwn requests · OSSF Scorecard — Token-Permissions

Untrusted input interpolated into run: (merge-worthy · guidance)

Pass untrusted $\{\{ }} values via an env: var and reference "$VAR", never inline in the script.

AuthorityGitHub — Understanding the risk of script injections
Prior artzizmor template-injection (equivalent) · poutine injection (equivalent) · actionlint Script injection by potentially untrusted inputs (equivalent) · octoscan expression-injection (equivalent) · OpenSSF Scorecard Dangerous-Workflow (overlaps)

Untrusted input written to GITHUB_ENV/GITHUB_PATH (merge-worthy · guidance)

Don’t write untrusted input to $GITHUB_ENV/$GITHUB_PATH; sanitize or avoid.

AuthorityGitHub — Understanding the risk of script injections
Prior artzizmor github-env (equivalent) · octoscan dangerous-write (overlaps)

workflow_run checks out untrusted code in a privileged context (merge-worthy · guidance)

Avoid checking out untrusted code under workflow_run; treat it as privileged.

AuthorityGitHub Security Lab — Preventing pwn requests
Prior artOpenSSF Scorecard Dangerous-Workflow (overlaps) · octoscan dangerous-checkout (overlaps)

Auth gate on a spoofable author field (merge-worthy · guidance)

Gate on a non-spoofable identity, not a commit-author field.

AuthorityGitHub Security Lab — Preventing pwn requests
Prior artzizmor bot-conditions (overlaps) · octoscan bot-check (overlaps) · poutine confused_deputy_auto_merge (overlaps)

Self-hosted runner on an untrusted-code trigger (merge-worthy · guidance)

Don’t run untrusted-code triggers on self-hosted runners.

AuthorityGitHub Security Lab — Preventing pwn requests
Prior artpoutine pr_runs_on_self_hosted (equivalent) · zizmor self-hosted-runner (overlaps) · octoscan runner-label (overlaps)

Blanket secrets: inherit (merge-worthy · guidance)

Pass only the specific secrets the reusable workflow needs.

AuthorityGitHub — Using secrets in GitHub Actions
Prior artzizmor secrets-inherit (equivalent)

Entire secrets context passed (merge-worthy · guidance)

Pass named secrets instead of the whole secrets context.

AuthorityGitHub — Using secrets in GitHub Actions
Prior artzizmor overprovisioned-secrets (equivalent) · poutine job_all_secrets (equivalent)

Secret consumed without an environment gate (merge-worthy · guidance)

Put secret-consuming jobs behind a protected environment.

AuthorityGitHub — Using secrets in GitHub Actions
Prior artzizmor secrets-outside-env (equivalent)

Hardcoded registry/container credential (merge-worthy · guidance)

Remove the hardcoded credential, move it to a secret, and rotate it (responsible disclosure first).

AuthorityGitHub — Using secrets in GitHub Actions
Prior artzizmor hardcoded-container-credentials (equivalent) · actionlint Hardcoded credentials (equivalent) · octoscan credentials (equivalent)

Secret interpolated into run: (merge-worthy · guidance)

Reference secrets via env:, not inline in the shell command.

AuthorityGitHub — Understanding the risk of script injections · GitHub — Using secrets in GitHub Actions

Constant/unsound guard condition (merge-worthy · guidance)

Fix the always-true/false if: — it may neutralize a security gate.

Prior artactionlint Constant conditions at if:“ (equivalent) · zizmor unsound-condition (overlaps) · poutine if_always_true (overlaps)

Ineffective contains() guard (reversed args) (merge-worthy · guidance)

Swap the contains() arguments so the guard actually filters.

Prior artzizmor unsound-contains (equivalent)

Obfuscated guard condition (merge-worthy · guidance)

Simplify the indirect if: so its effect is reviewable.

Prior artzizmor obfuscation (overlaps)

Persisted checkout credentials reachable by an artifact (merge-worthy · guidance)

Use persist-credentials: false or exclude .git from uploaded artifacts.

AuthorityGitHub — Using secrets in GitHub Actions
Prior artzizmor artipacked (equivalent) · octoscan dangerous-artefact (overlaps)

Cache populated in a privileged context (merge-worthy · guidance)

Don’t populate caches from untrusted code paths (poisoning risk).

AuthorityGitHub Security Lab — Preventing pwn requests
Prior artzizmor cache-poisoning (overlaps)

Long-lived token instead of OIDC (report-only · guidance)

Migrate publish/release to OIDC short-lived credentials.

Prior artzizmor use-trusted-publishing (overlaps)

Software piped to a shell without verification (merge-worthy · guidance)

Verify a checksum/signature before executing fetched scripts.

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior artpoutine unverified_script_exec (equivalent) · OpenSSF Scorecard Pinned-Dependencies (overlaps)

Re-enables unsafe set-env/add-path (merge-worthy · guidance)

Remove ACTIONS_ALLOW_UNSECURE_COMMANDS; use $GITHUB_ENV/$GITHUB_PATH.

AuthorityGitHub — Understanding the risk of script injections
Prior artzizmor insecure-commands (equivalent) · octoscan unsecure-commands (equivalent)

Feature with a known security footgun (merge-worthy · guidance)

Replace the flagged feature with the safe alternative.

Prior artzizmor misfeature (overlaps)

Runtime install of a tool already on the runner (report-only · guidance)

Drop the redundant install to save time.

Prior artzizmor superfluous-actions (overlaps)

Workflow without a name (report-only · guidance)

Add a name: to the workflow.

Prior artzizmor anonymous-definition (overlaps)

Dependency update can execute untrusted code (merge-worthy · guidance)

Disable the option that lets dependency updates run external code.

AuthorityGitHub Security Lab — Preventing pwn requests
Prior artzizmor dependabot-execution (equivalent)

Dependency update has no cooldown window (report-only · guidance)

Add a cooldown so new releases aren’t merged instantly.

Prior artzizmor dependabot-cooldown (equivalent)

Stale or missing pin annotation (merge-worthy · guidance)

Add or correct the trailing version comment on the SHA-pinned reference so it matches the digest.

AuthorityOSSF Scorecard — Pinned-Dependencies · GitHub — Using third-party actions
Prior artzizmor ref-version-mismatch (equivalent)

Over-scoped generated token (merge-worthy · guidance)

Narrow the GitHub App token’s permission-* inputs to the scopes its consuming steps actually use, or remove the unused ones.

AuthorityOSSF Scorecard — Token-Permissions · GitHub — Automatic token authentication
Prior artzizmor github-app (overlaps)

Action reference outside the configured usage policy (merge-worthy · guidance)

Replace the reference with one from the approved allowlist, or get it added if it should be trusted.

Prior artzizmor forbidden-uses (equivalent)

Pinned reference matches a known-vulnerability advisory (merge-worthy · guidance)

Bump the reference to a patched ref/commit named by the advisory.

AuthorityOSSF Scorecard — Vulnerabilities
Prior artzizmor known-vulnerable-actions (equivalent) · poutine known_vulnerability_in_build_component (equivalent) · octoscan known-vulnerability (equivalent) · OpenSSF Scorecard Vulnerabilities (overlaps)

Dependency setup action without caching enabled (report-only · guidance)

Enable the setup action’s cache: option or add an actions/cache step.

Expensive runner without justification (report-only · guidance)

Confirm the job needs that OS, or move it to a Linux runner.

Unbounded matrix fan-out (report-only · guidance)

Trim the matrix with include/exclude, or cap it with max-parallel.

Unbounded artifact retention (report-only · guidance)

Set a retention-days sized to how long the artifact is actually needed.

Unconditional heavy step with no path filter (report-only · guidance)

Scope the trigger’s paths, or add an if: guard to the step.

Pull-request workflow missing a concurrency group (report-only · guidance)

Add a concurrency group with cancel-in-progress: true.

Prior artzizmor concurrency-limits (overlaps)

Job permissions block drops the workflow’s id-token: write (merge-worthy · guidance)

Add id-token: write to the job’s permissions: block; keep the job block rather than removing it.

Job references an undefined stage (merge-worthy · guidance)

Add the stage to stages: or fix the job’s stage:.

Prior artGitLab CI/CD YAML reference stage: supported values are the default stages or stages listed in stages“ (equivalent)

Job rules always evaluate to never (merge-worthy · guidance)

Fix the rules: so the job can run; it is currently unreachable.

Deprecated property (report-only · guidance)

Replace the deprecated GitLab CI property.

Prior artGitLab CI/CD YAML reference Deprecated keywords (only/except, globally-defined image/services/cache/before_script/after_script) (equivalent)

Invalid needs target (merge-worthy · guidance)

Fix the dangling/self needs: reference.

Prior artGitLab CI/CD YAML reference Error: 'job' does not exist in the pipeline (needs) (equivalent)

Invalid extends target (merge-worthy · guidance)

Point extends: at a template that exists in the pipeline.

Prior artGitLab CI/CD YAML reference extends: supported values are the name(s) of another job in the pipeline (equivalent)

Circular needs chain (merge-worthy · guidance)

Break the cycle in the job dependency graph.

Hardcoded secret in variables (merge-worthy · guidance)

Move the secret out of variables: into a masked/protected CI variable and rotate it.

AuthorityGitHub — Using secrets in GitHub Actions
Prior artGitLab CI/CD YAML reference CI/CD variable security (secrets belong in masked/protected variables, not in .gitlab-ci.yml) (overlaps)

Insecure (non-HTTPS) registry (merge-worthy · guidance)

Use an HTTPS registry endpoint.

Missing job timeout (report-only · guidance)

Add a timeout: to bound long-running jobs.

Missing retry on deploy job (report-only · guidance)

Add a retry: strategy to deploy jobs.

Duplicate job names (merge-worthy · guidance)

Rename so each job resolves to a unique name.

Unused global variable (report-only · guidance)

Remove the unused global variables: entry.

Missing artifacts expiry (report-only · guidance)

Add expire_in: to artifacts to avoid disk bloat.

Overly broad rules (when: always) (report-only · guidance)

Add real conditions to the job’s rules:.

Prior artGitLab CI/CD YAML reference Pipeline warning: Job may allow multiple pipelines to run for a single action (final when rule without conditions) (overlaps)

Manual job without allow_failure (report-only · guidance)

Add allow_failure: true so a manual job doesn’t block the pipeline.

Prior artGitLab CI/CD YAML reference allow_failure default: true for manual jobs, false for rules:when: manual (overlaps)

Cache without a key (report-only · guidance)

Add a cache.key to avoid cross-job cache collisions.

Prior artGitLab CI/CD YAML reference cache:key: all jobs with cachebut nocache:keyshare thedefault cache (overlaps)

Privileged DinD service without TLS (merge-worthy · guidance)

Set DOCKER_TLS_CERTDIR for privileged Docker-in-Docker services.

Prior artGitLab CI/CD YAML reference Docker-in-Docker with TLS enabled (recommended); DOCKER_TLS_CERTDIR (overlaps)

Empty script (merge-worthy · guidance)

Give the job a non-empty script:; it currently does nothing.

Redundant needs (report-only · guidance)

Drop needs: already implied by stage ordering.

include/component resolved by a moving ref (merge-worthy · guidance)

Pin include:project/component to a tag or commit SHA, not a branch.

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior artGitLab CI/CD YAML reference include:project ref guidance: use a specific SHA hash, protected branch/tag rules (overlaps) · GitLab CI/CD YAML reference CI/CD component security best practices: use pinned versions (commit SHA preferred), avoid latest“ (overlaps)

Insecure or mutable include:remote (merge-worthy · guidance)

Use HTTPS and pin the remote include to an immutable ref.

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior artGitLab CI/CD YAML reference include:remote: treat as a third-party dependency; verify integrity with include:integrity (overlaps)

Container image not pinned to a digest (merge-worthy · deterministic)

Pin the image to an immutable @sha256: digest.

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior artGitLab CI/CD YAML reference Use checksum to keep your image secure (image@sha256:digest) (overlaps)

Possible include/component impersonation (merge-worthy · guidance)

Verify the include source; it resembles a well-known project.

AuthorityOSSF Scorecard — Pinned-Dependencies

OIDC id_token without a scoped audience (merge-worthy · guidance)

Set a specific aud: on the OIDC id_token.

AuthorityGitHub — Security hardening with OpenID Connect
Prior artGitLab CI/CD YAML reference id_tokens: the required aud sub-keyword configures the aud claim (overlaps)

OIDC id_token mintable from a merge-request pipeline (merge-worthy · guidance)

Restrict OIDC token minting to protected pipelines.

AuthorityGitHub — Security hardening with OpenID Connect · GitHub Security Lab — Preventing pwn requests

Untrusted CI variable interpolated into a script (merge-worthy · guidance)

Pass untrusted variables via the environment and quote them; don’t inline.

AuthorityGitHub — Understanding the risk of script injections
Prior artpoutine injection (overlaps)

Privileged service reachable from merge-request pipelines (merge-worthy · guidance)

Block privileged/DinD services on merge-request pipelines.

AuthorityGitHub Security Lab — Preventing pwn requests

Security gate on an untrusted ref regex (merge-worthy · guidance)

Don’t gate security decisions on a regex over an untrusted ref variable.

AuthorityGitHub Security Lab — Preventing pwn requests

Secret reachable from a merge-request pipeline (merge-worthy · guidance)

Scope secret-like variables to protected branches/pipelines.

AuthorityGitHub — Using secrets in GitHub Actions · GitHub Security Lab — Preventing pwn requests
Prior artGitLab CI/CD YAML reference Protect a CI/CD variable (available only to protected branches/tags) (overlaps) · GitLab CI/CD YAML reference Merge request pipelines from forked projects can steal secrets in the parent project (overlaps)

Secret printed to job logs (merge-worthy · guidance)

Stop echoing the secret-like variable; mask it.

AuthorityGitHub — Using secrets in GitHub Actions
Prior artGitLab CI/CD YAML reference CI/CD variable security: accidental-leak-job example (echo of $PASSWORD); mask sensitive variables (overlaps)

Hardcoded credential in a registry login (merge-worthy · guidance)

Move the credential to a masked CI variable and rotate it.

AuthorityGitHub — Using secrets in GitHub Actions

Tautological rules:if condition (merge-worthy · guidance)

Fix the always-true rules:if; it may neutralize a gate.

Unreachable rules after an unconditional match (report-only · guidance)

Remove the dead rules: entries after the catch-all.

Match-anything regex gate in rules:if (merge-worthy · guidance)

Tighten the regex; a match-anything gate is no gate.

AuthorityGitHub Security Lab — Preventing pwn requests

Public artifacts expose build output (merge-worthy · guidance)

Mark sensitive artifacts non-public (public: false).

Prior artGitLab CI/CD YAML reference artifacts:public (default true: downloadable by anonymous users in public pipelines) (overlaps)

Artifact path may capture a credential file (merge-worthy · guidance)

Narrow the artifact path so it can’t capture credential files.

AuthorityGitHub — Using secrets in GitHub Actions

Cache populated in a merge-request pipeline (merge-worthy · guidance)

Don’t populate caches from merge-request pipelines (poisoning risk).

AuthorityGitHub Security Lab — Preventing pwn requests
Prior artGitLab CI/CD YAML reference Cache key names: protected and non-protected branches do not share the cache by default (overlaps)

Software piped to a shell without verification (merge-worthy · guidance)

Verify a checksum/signature before executing fetched scripts.

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior artpoutine unverified_script_exec (equivalent)

Pipeline without workflow:name (report-only · guidance)

Add a workflow:name for clearer pipeline naming.

Prior artGitLab CI/CD YAML reference Use pipeline names (workflow:name) (overlaps)

Dependency install without a cache (report-only · guidance)

Add a cache: covering the dependency directory.

Merge-request job missing interruptible (report-only · guidance)

Add interruptible: true so a superseded pipeline can be cancelled.

Unresolved action reference on Forgejo (merge-worthy · guidance)

Use an action reference Forgejo can resolve (full URL or a mirrored action).

GitHub-hosted runner label with no Forgejo equivalent (merge-worthy · guidance)

Use a runner label your Forgejo instance provides.

Run against Kubernetes manifests.

Argo Application references an undeclared AppProject (merge-worthy · guidance)

Declare the named AppProject or reference an existing project.

Argo Application targets an unregistered cluster (merge-worthy · guidance)

Point spec.destination at a registered cluster or the in-cluster target.

Argo source.path may not resolve (report-only · guidance)

Ensure the source path exists under the build root.

Flux Kustomization references an undeclared source (merge-worthy · guidance)

Declare the GitRepository/OCIRepository/Bucket, or point sourceRef at the bootstrap flux-system repo.

Prior artFlux Kustomization API reference .spec.sourceRef (overlaps)

Flux Kustomization dependsOn names an undeclared Kustomization (report-only · guidance)

Fix the dependsOn name, or ignore if the dependency is declared in another repo.

Prior artFlux Kustomization API reference .spec.dependsOn (overlaps)

Hardcoded secret in env var (merge-worthy · guidance)

Use a secretKeyRef instead of a literal value, and rotate the secret.

AuthorityKubernetes — Good practices for Secrets
Prior artFairwinds Polaris sensitiveContainerEnvVar (overlaps) · KubeLinter env-var-secret (overlaps)

Image uses :latest or no tag (merge-worthy · guidance)

Pin the image to an explicit version tag (ideally a digest).

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior artKubeLinter latest-tag (equivalent) · Fairwinds Polaris tagNotSpecified (equivalent) · Checkov CKV_K8S_14 (equivalent)

Hardcoded API key in env var (merge-worthy · guidance)

Move the key to a Secret and rotate it.

AuthorityKubernetes — Good practices for Secrets
Prior artFairwinds Polaris sensitiveContainerEnvVar (overlaps) · KubeLinter env-var-secret (overlaps) · Datree prevent-exposed-secrets-aws (overlaps)

Private key stored in a ConfigMap (merge-worthy · guidance)

Store private keys in a Secret, not a ConfigMap.

AuthorityKubernetes — Good practices for Secrets
Prior artFairwinds Polaris sensitiveConfigmapContent (overlaps) · Datree prevent-exposed-secrets-privatekey (overlaps)

Deployment selector does not match template labels (merge-worthy · guidance)

Align spec.selector with the pod template labels.

Prior artKubeLinter mismatching-selector (equivalent) · kube-score deployment-pod-selector-labels-match-template-metadata-labels (equivalent)

Resource missing metadata labels (report-only · guidance)

Add metadata labels for filtering and tooling.

Container missing name (merge-worthy · guidance)

Add the required container name.

Container ports not named (report-only · guidance)

Name ports for clearer Service/NetworkPolicy config.

imagePullPolicy not explicit (report-only · guidance)

Set imagePullPolicy explicitly to avoid surprising defaults.

Prior artFairwinds Polaris pullPolicyNotAlways (overlaps) · kube-score container-image-pull-policy (overlaps) · Checkov CKV_K8S_15 (overlaps)

Container missing resource limits (report-only · guidance)

Set CPU and memory limits.

Prior artFairwinds Polaris cpuLimitsMissing (overlaps) · Checkov CKV_K8S_13 (overlaps) · kube-score container-resources (overlaps)

Privileged container (merge-worthy · guidance)

Remove privileged: true; grant only the specific capabilities needed.

AuthorityKubernetes — Pod Security Standards
Prior artKubeLinter privileged-container (equivalent) · Fairwinds Polaris runAsPrivileged (equivalent) · Checkov CKV_K8S_16 (equivalent)

Root filesystem is writable (merge-worthy · guidance)

Set readOnlyRootFilesystem: true.

AuthorityKubernetes — Pod Security Standards
Prior artKubeLinter no-read-only-root-fs (equivalent) · Fairwinds Polaris notReadOnlyRootFilesystem (equivalent) · Checkov CKV_K8S_22 (equivalent)

Container may run as root (merge-worthy · guidance)

Set runAsNonRoot: true (and a non-zero runAsUser).

AuthorityKubernetes — Pod Security Standards
Prior artFairwinds Polaris runAsRootAllowed (equivalent) · Checkov CKV_K8S_23 (equivalent) · KubeLinter run-as-non-root (overlaps)

Capabilities not dropped (merge-worthy · guidance)

drop: [ALL] and add back only what is required.

AuthorityKubernetes — Pod Security Standards
Prior art[kubesec `containers[] .securityContext .capabilities .drop

Pod uses host network (merge-worthy · guidance)

Remove hostNetwork; it bypasses network isolation.

AuthorityKubernetes — Pod Security Standards
Prior artKubeLinter host-network (equivalent) · Fairwinds Polaris hostNetworkSet (equivalent) · Checkov CKV_K8S_19 (equivalent)

Pod shares host PID namespace (merge-worthy · guidance)

Remove hostPID.

AuthorityKubernetes — Pod Security Standards
Prior artKubeLinter host-pid (equivalent) · Fairwinds Polaris hostPIDSet (equivalent) · Checkov CKV_K8S_17 (equivalent)

Pod shares host IPC namespace (merge-worthy · guidance)

Remove hostIPC.

AuthorityKubernetes — Pod Security Standards
Prior artKubeLinter host-ipc (equivalent) · Fairwinds Polaris hostIPCSet (equivalent) · Checkov CKV_K8S_18 (equivalent)

Container missing probes (report-only · guidance)

Add liveness and readiness probes.

Prior artkube-score pod-probes (overlaps) · Fairwinds Polaris readinessProbeMissing (overlaps) · Checkov CKV_K8S_8 (overlaps)

Deployment has a single replica (report-only · guidance)

Use replicas >= 2 for availability.

Prior artFairwinds Polaris deploymentMissingReplicas (equivalent) · kube-score deployment-replicas (equivalent) · Datree ensure-minimum-two-replicas (equivalent)

No PodDisruptionBudget for an HA Deployment (report-only · guidance)

Add a PDB to protect availability during disruptions.

Prior artkube-score deployment-has-poddisruptionbudget (overlaps) · Fairwinds Polaris missingPodDisruptionBudget (overlaps) · KICS Deployment Without PodDisruptionBudget (overlaps)

SSL redirect without a certificate (report-only · guidance)

Provide a certificate and HTTPS listen-ports for the ssl-redirect annotation.

Prior artFairwinds Polaris tlsSettingsMissing (overlaps)

Ingress backend port does not match the Service (merge-worthy · guidance)

Point the Ingress backend at a declared Service port.

Prior artKubeLinter dangling-ingress (overlaps) · kube-score ingress-targets-service (overlaps)

Container command starts with a flag (merge-worthy · guidance)

The first command element should be a binary, not a flag.

shmSize exceeds the container memory limit (merge-worthy · guidance)

Lower shmSize or raise the memory limit so the pod can schedule.

RayCluster missing spec.rayVersion (report-only · guidance)

Set spec.rayVersion so KubeRay picks the right autoscaler image.

rayVersion does not match the head image tag (report-only · guidance)

Align spec.rayVersion with the Ray version in the head container image.

GPU request without a matching toleration (merge-worthy · guidance)

Add a toleration for the nvidia.com/gpu taint (or a wildcard Exists toleration) so the pod can schedule onto a GPU node pool.

Serving workload has no PodDisruptionBudget (report-only · guidance)

Add a PDB selecting the InferenceService/serving Deployment so a node drain can’t take down every replica at once.

Prior artkube-score deployment-has-poddisruptionbudget (overlaps) · Fairwinds Polaris missingPodDisruptionBudget (overlaps)

GPU container missing resource limits (merge-worthy · guidance)

Set CPU and memory limits on GPU-requesting containers to avoid starving the (scarce, expensive) GPU node.

Prior artCheckov CKV_K8S_13 (overlaps) · kube-score container-resources (overlaps) · KubeLinter unset-memory-requirements (overlaps)

Unpinned model version (merge-worthy · guidance)

Pin the InferenceService model storageUri to an explicit version segment (e.g. via the Model composite’s required version) instead of a floating tag.

Custom resource spec has a field its CRD does not declare (merge-worthy · guidance)

Fix the field name; the API server prunes unknown fields and the controller never sees them.

Prior artKubeLinter schema-validation (overlaps)

Custom resource spec field has the wrong type or enum value (merge-worthy · guidance)

Match the CRD schema: use the declared scalar type and one of the enum values.

Prior artKubeLinter schema-validation (overlaps)

Workload consumes a Secret nothing in the output produces (merge-worthy · guidance)

Produce the Secret in the same build (Secret, ExternalSecret, InfisicalSecret, cert-manager Certificate), or declare its provenance with declareSecret() if it exists out of band.

Prior artKubeLinter env-value-from (overlaps)

committed-encrypted secret declaration does not resolve (merge-worthy · guidance)

Point file at the committed ciphertext, make its metadata.name match the declaration, and re-run sops -e -i so every data/stringData value is ENC[…].

AuthorityKubernetes — Good practices for Secrets

committed-encrypted secret with no Flux decryption wiring (report-only · guidance)

Add decryption: “sops” to the FluxAppFor reconciling the path that carries the ciphertext sidecar, or ignore if that Kustomization is declared in a different build. This check sees one build root at a time, so it goes silent once the secret and the Kustomization live in different build roots (chant #1939).

Prior artFlux Kustomization API reference .spec.decryption (overlaps)

OpenTelemetry Collector runs tail_sampling on every node (merge-worthy · guidance)

Move tail_sampling from the DaemonSet agent to a gateway Deployment, and send traces to it through a loadbalancing exporter routed by traceID.

Multi-replica tail sampling gateway reached without trace-aware load balancing (merge-worthy · guidance)

Send traces to the gateway through a loadbalancing exporter with routing_key traceID (k8s resolver, or dns on a headless Service), or run the gateway with one replica. It goes silent when the senders are in another build root (chant #1939).

k8s_cluster receiver runs in every collector copy (merge-worthy · guidance)

Run the k8s_cluster receiver in a single-replica Deployment, or set its k8s_leader_elector to a k8s_leader_elector extension enabled in service.extensions.

Collector config in a ConfigMap fails the otel config checks (merge-worthy · guidance)

Fix the collector config the ConfigMap carries: each finding keeps its OTEL1xx id and names the ConfigMap and key. Change the declared components and pipelines, not the rendered YAML.

Collector config reads the node but its workload lacks the node name or host mounts (merge-worthy · guidance)

Set the node name variable from spec.nodeName with the downward API and mount the host paths hostmetrics and filelog read, read-only; OtelCollector adds them from the config.

PrometheusRule groups fail the prometheus rule-file checks (merge-worthy · guidance)

Fix the rule group the PrometheusRule carries: each finding keeps its PROM1xx or PROM2xx id and names the PrometheusRule. Change the declared RuleGroup, not the rendered YAML.

PrometheusRule selected by no Prometheus or ThanosRuler (merge-worthy · guidance)

Match the rule’s labels and namespace with ruleSelector and ruleNamespaceSelector; null selects nothing, {} selects all.

Monitor selected by no Prometheus or PrometheusAgent (merge-worthy · guidance)

Match the ServiceMonitor, PodMonitor, Probe or ScrapeConfig with the selector and namespace selector for its kind; null selects nothing, {} selects all.

AlertmanagerConfig selected by no Alertmanager (merge-worthy · guidance)

Match the config’s labels and namespace with alertmanagerConfigSelector and alertmanagerConfigNamespaceSelector; null selects nothing, {} selects all.

Monitor selects no Service or pod, or names a port that is not there (merge-worthy · guidance)

Make the monitor’s selector match the labels on the Service or pod template, and name a port the Service or container declares.

Prometheus selects no monitor at all (merge-worthy · guidance)

Set serviceMonitorSelector, podMonitorSelector, probeSelector and scrapeConfigSelector for the monitor kinds it should scrape; {} selects all in the selected namespaces.

Run against Dockerfiles and Compose files.

Service uses :latest or untagged image (merge-worthy · guidance)

Pin the image to an explicit version tag (ideally a digest).

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior arthadolint DL3007 (overlaps) · Checkov CKV_DOCKER_7 (overlaps) · KICS image_version_using_latest (overlaps)

Named volume declared but unused (report-only · guidance)

Remove the unused volume or mount it in a service.

Service exposes SSH (port 22) (merge-worthy · guidance)

Don’t expose SSH from a container; use exec/ephemeral access instead.

AuthorityDocker — Security best practices
Prior artCheckov CKV_DOCKER_1 (overlaps) · KICS Exposing Port 22 (SSH) (overlaps)

apt-get install without —no-install-recommends (report-only · guidance)

Add —no-install-recommends to keep images small.

Prior arthadolint DL3015 (equivalent) · KICS apt_get_not_avoiding_additional_packages (equivalent)

ADD used where COPY would do (report-only · guidance)

Prefer COPY unless fetching a URL or extracting an archive.

Prior arthadolint DL3020 (equivalent) · Checkov CKV_DOCKER_4 (overlaps) · Dockle CIS-DI-0009 (overlaps)

Container runs as root: the final stage has no USER, or ends on USER root (merge-worthy · guidance)

Add a non-root USER instruction to the final stage, after the root setup steps.

AuthorityDocker — Security best practices
Prior artCheckov CKV_DOCKER_3 (equivalent) · KICS missing_user_instruction (equivalent) · Dockle CIS-DI-0001 (overlaps) · hadolint DL3002 (overlaps)

Whole build context copied before a dependency install (report-only · guidance)

Copy the dependency manifests, run the install, then copy the rest of the source.

Root-only RUN after a non-root USER (report-only · guidance)

Run package installs and user/ownership changes before switching USER.

More than one CMD or ENTRYPOINT in a stage (report-only · guidance)

Keep one CMD and one ENTRYPOINT per stage; only the last takes effect.

Prior arthadolint DL4003 (overlaps) · hadolint DL4004 (overlaps)

COPY —from names no earlier stage (report-only · guidance)

Name a stage defined earlier in the Dockerfile, or a tagged image.

Prior arthadolint DL3022 (overlaps)

ARG before FROM is never used (report-only · guidance)

Use the ARG in a FROM line, declare it again in the stage that needs it, or remove it.

Relative WORKDIR (report-only · guidance)

Use an absolute WORKDIR path.

Prior arthadolint DL3000 (overlaps)

ADD of a remote URL without —checksum (report-only · guidance)

Add —checksum=sha256:<digest> to ADD of an http(s) URL.

apt-get update in its own RUN (report-only · guidance)

Run apt-get update and apt-get install in the same RUN.

Prior artCheckov CKV_DOCKER_5 (overlaps)

Run against CloudFormation templates (JSON or YAML).

Circular resource dependency (merge-worthy · guidance)

Break the dependency cycle between resources.

Prior artcfn-lint E3004 (equivalent)

Extension constraint violation (merge-worthy · guidance)

Fix the cross-property constraint flagged by the cfn-lint extension schema.

Prior artcfn-lint (equivalent) · cfn-lint E3014 (equivalent) · cfn-lint E3021 (equivalent)

Redundant DependsOn (report-only · guidance)

Remove DependsOn already implied by a Ref/GetAtt.

Prior artcfn-lint W3005 (equivalent)

Deprecated Lambda runtime (report-only · guidance)

Upgrade to a supported Lambda runtime.

Prior artcfn-lint W2531 (equivalent) · Checkov CKV_AWS_363 (equivalent)

Child stack exports nothing (merge-worthy · guidance)

Add stackOutput() exports the parent can reference.

Nested stack outputs never referenced (report-only · guidance)

Reference the outputs or split into a separate build.

Circular dependency between nested stacks (merge-worthy · guidance)

Break the cycle between nested stacks.

Deprecated property (report-only · guidance)

Replace the deprecated CloudFormation property.

Missing tags on a taggable resource (report-only · guidance)

Add tags for cost allocation and compliance.

Prior artKICS Lambda Function Without Tags (extends) · KICS EFS Without Tags (extends)

S3 bucket missing public access block (merge-worthy · guidance)

Add a PublicAccessBlockConfiguration blocking all public access.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artAWS Guard Rules Registry S3_BUCKET_LEVEL_PUBLIC_ACCESS_PROHIBITED (equivalent) · Checkov CKV_AWS_53 (extends) · Checkov CKV_AWS_56 (extends)

Security group allows unrestricted ingress on a sensitive port (merge-worthy · guidance)

Restrict the CIDR on SSH/RDP/database ports to known sources.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artAWS Guard Rules Registry RESTRICTED_INCOMING_TRAFFIC (overlaps) · KICS EC2 Sensitive Port Is Publicly Exposed (overlaps) · Checkov CKV_AWS_24 (extends)

IAM policy uses a wildcard Action (merge-worthy · guidance)

Scope the policy to specific actions (least privilege).

AuthorityAWS — Security Pillar (Well-Architected)
Prior artCheckov CKV_AWS_63 (equivalent) · cfn_nag F4 (overlaps) · AWS Guard Rules Registry IAM_ROLE_NO_WILDCARD_ACTIONS_ON_PERMISSIONS (overlaps)

RDS storage not encrypted (merge-worthy · guidance)

Enable StorageEncrypted for encryption at rest.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artcfn_nag F27 (equivalent) · Checkov CKV_AWS_16 (equivalent) · AWS Guard Rules Registry RDS_STORAGE_ENCRYPTED (equivalent)

Lambda has no VpcConfig (report-only · guidance)

Consider a VpcConfig for network isolation if the function needs VPC resources.

Prior artcfn_nag W89 (equivalent) · Checkov CKV_AWS_117 (equivalent) · AWS Guard Rules Registry LAMBDA_INSIDE_VPC (equivalent)

CloudFront has no WAF web ACL (report-only · guidance)

Consider attaching a WAF web ACL.

Prior artCheckov CKV_AWS_68 (equivalent) · KICS CloudFront Without WAF (equivalent)

ALB access logging disabled (report-only · guidance)

Enable access logging for audit trails.

Prior artcfn_nag W52 (equivalent) · Checkov CKV_AWS_91 (equivalent) · KICS ELBv2 ALB Access Log Disabled (equivalent)

SNS topic not encrypted (merge-worthy · guidance)

Set KmsMasterKeyId for encryption at rest.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artcfn_nag W47 (equivalent) · Checkov CKV_AWS_26 (equivalent) · AWS Guard Rules Registry SNS_ENCRYPTED_KMS (equivalent)

SQS queue not encrypted (merge-worthy · guidance)

Enable SqsManagedSseEnabled or set KmsMasterKeyId.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artCheckov CKV_AWS_27 (equivalent) · KICS SQS With SSE Disabled (equivalent) · cfn_nag W48 (overlaps)

DynamoDB point-in-time recovery disabled (report-only · guidance)

Enable PITR for recovery.

Prior artcfn_nag W78 (equivalent) · Checkov CKV_AWS_28 (equivalent) · AWS Guard Rules Registry DYNAMODB_PITR_ENABLED (equivalent)

EBS volume not encrypted (merge-worthy · guidance)

Enable encryption at rest.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artcfn_nag F1 (equivalent) · Checkov CKV_AWS_3 (equivalent) · AWS Guard Rules Registry ENCRYPTED_VOLUMES (equivalent)

Invalid DependsOn target (merge-worthy · guidance)

Fix the dangling/self DependsOn reference.

Prior artcfn-lint E3005 (equivalent)

Missing DependsOn for a known ordering pattern (report-only · guidance)

Add the DependsOn the pattern requires.

EKS Addon missing ServiceAccountRoleArn (report-only · guidance)

Set ServiceAccountRoleArn (IRSA) for addons that need it.

EFS transit encryption disabled on Fargate (merge-worthy · guidance)

Enable transit encryption for the EFS volume.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artCheckov CKV_AWS_97 (equivalent) · KICS EFS Volume With Disabled Transit Encryption (equivalent)

Solr heap exceeds Fargate task memory (merge-worthy · guidance)

Lower SOLR_HEAP or raise task memory.

Fargate Solr task under-provisioned (report-only · guidance)

Allocate >= 2048MB for the Solr task.

Solr container missing nofile ulimit (report-only · guidance)

Set a nofile ulimit >= 65535.

Non-ASCII characters in resource properties (merge-worthy · guidance)

Remove non-ASCII characters rejected at changeset time.

Null values in resource properties (merge-worthy · guidance)

Fix the invalid AttrRef producing null property values.

RDS instance is publicly accessible (merge-worthy · guidance)

Set PubliclyAccessible: false and reach the database through the VPC.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artcfn_nag F22 (equivalent) · Checkov CKV_AWS_17 (equivalent) · KICS RDS DB Instance Publicly Accessible (equivalent)

RDS automated backups disabled (merge-worthy · guidance)

Set a positive BackupRetentionPeriod.

Prior artcfn_nag W75 (equivalent) · AWS Guard Rules Registry DB_INSTANCE_BACKUP_ENABLED (equivalent) · KICS RDS With Backup Disabled (equivalent)

RDS deletion protection disabled (full tier) (merge-worthy · guidance)

Set DeletionProtection: true on the full/production tier.

Prior artcfn_nag F80 (equivalent) · AWS Guard Rules Registry RDS_INSTANCE_DELETION_PROTECTION_ENABLED (equivalent) · KICS RDS DB Instance With Deletion Protection Disabled (equivalent)

RDS Proxy does not require TLS (merge-worthy · guidance)

Set RequireTLS: true on the DB proxy.

AuthorityAWS — Security Pillar (Well-Architected)

S3 bucket missing a TLS-only bucket policy (merge-worthy · guidance)

Add a Deny statement keyed on aws:SecureTransport = false.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artAWS Guard Rules Registry S3_BUCKET_SSL_REQUESTS_ONLY (equivalent) · KICS S3 Bucket Without SSL In Write Actions (overlaps)

KMS key rotation disabled (merge-worthy · guidance)

Set EnableKeyRotation: true on the customer-managed key.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artcfn_nag F19 (equivalent) · Checkov CKV_AWS_7 (equivalent) · AWS Guard Rules Registry CMK_BACKING_KEY_ROTATION_ENABLED (equivalent)

ALB HTTP listener does not redirect to HTTPS (full tier) (merge-worthy · guidance)

Add a redirect DefaultAction (Protocol: HTTPS) to the HTTP listener on the full/production tier.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artCheckov CKV_AWS_2 (overlaps) · cfn_nag W56 (overlaps)

ALB listener uses a weak or missing TLS policy (merge-worthy · guidance)

Set SslPolicy to a TLS 1.2+ predefined policy.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artcfn_nag W55 (equivalent) · Checkov CKV_AWS_103 (equivalent) · AWS Guard Rules Registry ELBV2_LISTENER_SSL_POLICY_RULE (equivalent)

ECS container passes a secret via plaintext Environment (merge-worthy · guidance)

Move the value to Secrets (Secrets Manager/SSM Parameter Store).

AuthorityAWS — Security Pillar (Well-Architected)

ECS container runs privileged (merge-worthy · guidance)

Remove Privileged: true from the container definition.

AuthorityAWS — Security Pillar (Well-Architected)

ECS container missing log configuration (report-only · guidance)

Add a LogConfiguration (e.g. awslogs) to the container.

Security group allows unrestricted ingress on a non-ALB port (merge-worthy · guidance)

Restrict the CIDR; only ALB:80/443 is exempt from this rule.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artcfn_nag W2 (overlaps) · AWS Guard Rules Registry EC2_SECURITY_GROUP_INGRESS_OPEN_TO_WORLD_RULE (overlaps) · KICS Unrestricted Security Group Ingress (overlaps)

Cognito advanced security disabled (merge-worthy · guidance)

Set UserPoolAddOns.AdvancedSecurityMode to AUDIT or ENFORCED.

AuthorityAWS — Security Pillar (Well-Architected)

Cognito UserPoolClient allows the implicit OAuth grant (merge-worthy · guidance)

Drop “implicit” from AllowedOAuthFlows; use the code grant.

AuthorityAWS — Security Pillar (Well-Architected)

Cognito MFA not required (full tier) (merge-worthy · guidance)

Set MfaConfiguration: ON on the full/production tier.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artcfn_nag F78 (overlaps) · AWS Guard Rules Registry COGNITO_USER_POOL_MFA_CONFIGURATION_RULE (overlaps) · KICS Cognito UserPool Without MFA (overlaps)

ECR repository does not scan images on push (merge-worthy · guidance)

Set ImageScanningConfiguration.ScanOnPush: true.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artcfn_nag W79 (equivalent) · Checkov CKV_AWS_163 (equivalent) · AWS Guard Rules Registry ECR_REPO_SCAN_ON_PUSH (equivalent)

ECR repository allows mutable image tags (merge-worthy · guidance)

Set ImageTagMutability: IMMUTABLE.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artCheckov CKV_AWS_51 (equivalent) · KICS ECR Image Tag Not Immutable (equivalent)

CloudWatch Logs log group has no retention period (report-only · guidance)

Set an explicit RetentionInDays.

Prior artcfn_nag W86 (equivalent) · Checkov CKV_AWS_66 (equivalent) · AWS Guard Rules Registry CW_LOGGROUP_RETENTION_PERIOD_CHECK (equivalent)

SCP guardrail has no Deny statement (merge-worthy · guidance)

Add a Deny statement — SCPs only filter permissions, so a Deny-less SCP guards nothing.

AuthorityAWS — Security Pillar (Well-Architected)

SCP guardrail attached to no targets (merge-worthy · guidance)

Attach the SCP to the organization root or an OU via TargetIds.

AuthorityAWS — Security Pillar (Well-Architected)

Organization audit trail dropped or scoped down (merge-worthy · guidance)

Keep an organization CloudTrail with IsLogging: true and IsMultiRegionTrail: true.

AuthorityAWS — Security Pillar (Well-Architected)
Prior artAWS Guard Rules Registry MULTI_REGION_CLOUD_TRAIL_ENABLED (overlaps) · Checkov CKV_AWS_67 (overlaps) · KICS CloudTrail Logging Disabled (overlaps)

Wildcard Resource where the declared graph enumerates the touched set (report-only · guidance)

Tighten Resource from ”*” to the Fn::GetAtt Arn list of the declared resources the role’s consumers touch.

Prior artcfn_nag W12 (overlaps) · cfn_nag W11 (overlaps) · AWS Guard Rules Registry IAM_POLICYDOCUMENT_NO_WILDCARD_RESOURCE (overlaps)

IAM policy attached to no principal (report-only · guidance)

Attach the policy via Roles/Users/Groups or reference it from a principal’s ManagedPolicyArns — unattached it grants nothing.

Subnet CidrBlock not contained in its VPC’s CidrBlock (merge-worthy · guidance)

Fix the subnet’s CidrBlock so it falls within the VPC’s CidrBlock range.

Prior artcfn-lint E3059 (equivalent)

Duplicate export name or explicit resource name within a template (merge-worthy · guidance)

Give each duplicated Export/name a distinct literal value.

Prior artcfn-lint E3019 (overlaps)

IAM policy denies an action another attached policy on the same role allows (merge-worthy · guidance)

Remove or narrow the Deny, or move the Allow off this role — the explicit Deny always wins.

Transit Gateway route table declares a Blackhole route (report-only · guidance)

Confirm the traffic drop is intentional; remove the route if it isn’t.

Transit Gateway route table wiring is incomplete (report-only · guidance)

Add the missing TransitGatewayRouteTablePropagation, or wire the orphaned attachment into a route table.

Private subnet’s route table has no working default route (merge-worthy · guidance)

Add a 0.0.0.0/0 route to a NAT gateway/Transit Gateway that exists in the template.

Single-AZ NAT gateway serves multi-AZ private subnets (report-only · guidance)

Add one NAT gateway per Availability Zone and point each AZ’s subnets at its own.

VPN Gateway or Transit Gateway has only one attached VPN Connection (report-only · guidance)

Attach a second VPNConnection (ideally to a separate Customer Gateway) for redundancy.

Template references a condition it never declares (merge-worthy · guidance)

Declare the condition in the Conditions section (new Condition(…)), or fix the referenced name.

Prior artcfn-lint E8002 (equivalent)

Ref or Fn::GetAtt names something the template doesn’t declare (merge-worthy · guidance)

Reference a resource or parameter in this template. A value from another lexicon’s resource arrives as a parameter.

Prior artcfn-lint E1012 (equivalent) · cfn-lint E1010 (overlaps)

Tags are in the wrong property or the wrong shape for the resource type (merge-worthy · guidance)

Write the tags in the property the type uses and in the shape it takes, which is a list of Key and Value pairs for most types and a map for some, such as UserPoolTags on AWS::Cognito::UserPool.

Prior artcfn-lint E3002 (overlaps) · cfn-lint E3012 (overlaps)

Run against ARM deployment templates (JSON).

Redundant dependsOn (report-only · guidance)

Remove dependsOn already implied by reference()/resourceId().

Prior artBicep linter no-unnecessary-dependson (equivalent)

Missing or invalid apiVersion (merge-worthy · guidance)

Set a valid YYYY-MM-DD apiVersion on every resource.

Prior artARM Template Toolkit (arm-ttk) apiVersions-Should-Be-Recent (overlaps)

Deprecated API version (report-only · guidance)

Move to a current apiVersion.

Prior artARM Template Toolkit (arm-ttk) apiVersions-Should-Be-Recent (overlaps) · Bicep linter use-recent-api-versions (overlaps)

Resource missing location (merge-worthy · guidance)

Add the required location property.

Storage account allows public blob access (merge-worthy · guidance)

Set allowBlobPublicAccess to false.

AuthorityMicrosoft Cloud Security Benchmark
Prior artPSRule for Azure Azure.Storage.BlobPublicAccess (equivalent) · Checkov CKV_AZURE_59 (equivalent)

Storage account missing encryption (merge-worthy · guidance)

Enable encryption services for data at rest.

AuthorityMicrosoft Cloud Security Benchmark

Key Vault soft-delete not enabled (report-only · guidance)

Enable soft-delete.

Prior artPSRule for Azure Azure.KeyVault.SoftDelete (equivalent) · Checkov CKV_AZURE_111 (equivalent) · KICS Key Vault Not Recoverable (overlaps)

Key Vault purge protection not enabled (report-only · guidance)

Enable purge protection.

Prior artPSRule for Azure Azure.KeyVault.PurgeProtect (equivalent) · Checkov CKV_AZURE_110 (equivalent) · KICS Key Vault Not Recoverable (overlaps)

SQL Server missing auditing (report-only · guidance)

Enable auditing for compliance and threat detection.

Prior artPSRule for Azure Azure.SQL.Auditing (equivalent) · Checkov CKV_AZURE_23 (equivalent) · KICS SQL Server Database Without Auditing (equivalent)

SQL database missing TDE (merge-worthy · guidance)

Enable Transparent Data Encryption.

AuthorityMicrosoft Cloud Security Benchmark
Prior artPSRule for Azure Azure.SQL.TDE (equivalent)

App Service missing managed identity (report-only · guidance)

Enable a system- or user-assigned identity.

Prior artPSRule for Azure Azure.AppService.ManagedIdentity (equivalent) · Checkov CKV_AZURE_71 (equivalent)

App Service not HTTPS-only (merge-worthy · guidance)

Set httpsOnly to true.

AuthorityMicrosoft Cloud Security Benchmark
Prior artPSRule for Azure Azure.AppService.UseHTTPS (equivalent) · Checkov CKV_AZURE_14 (equivalent) · KICS Website Not Forcing HTTPS (equivalent)

App Service min TLS below 1.2 (merge-worthy · guidance)

Set minTlsVersion to 1.2+.

AuthorityMicrosoft Cloud Security Benchmark
Prior artPSRule for Azure Azure.AppService.MinTLS (equivalent) · Checkov CKV_AZURE_15 (equivalent) · KICS Web App Not Using TLS Last Version (equivalent)

VM not using a managed disk (report-only · guidance)

Use a managed disk.

Prior artPSRule for Azure Azure.VM.UseManagedDisks (equivalent) · Checkov CKV_AZURE_92 (equivalent)

VM missing boot diagnostics (report-only · guidance)

Enable boot diagnostics.

AKS cluster missing RBAC (report-only · guidance)

Enable Kubernetes RBAC.

Prior artPSRule for Azure Azure.AKS.UseRBAC (equivalent) · Checkov CKV_AZURE_5 (equivalent) · KICS AKS Cluster RBAC Disabled (equivalent)

AKS cluster missing network policy (report-only · guidance)

Configure a networkPolicy.

Prior artPSRule for Azure Azure.AKS.NetworkPolicy (equivalent) · Checkov CKV_AZURE_7 (equivalent) · KICS AKS Cluster Network Policy Not Configured (equivalent)

Container Registry admin user enabled (merge-worthy · guidance)

Disable the admin user; use Azure AD / service principals.

AuthorityMicrosoft Cloud Security Benchmark
Prior artPSRule for Azure Azure.ACR.AdminUser (equivalent) · Checkov CKV_AZURE_137 (equivalent)

Network interface missing NSG (report-only · guidance)

Associate an NSG to control traffic.

Managed disk missing encryption (merge-worthy · guidance)

Enable encryption for data at rest.

AuthorityMicrosoft Cloud Security Benchmark
Prior artCheckov CKV_AZURE_2 (equivalent) · KICS Azure Managed Disk Without Encryption (equivalent) · PSRule for Azure Azure.VM.ADE (overlaps)

Resource at unsupported template scope (merge-worthy · guidance)

Move the resource to a project deployed at a scope its schema supports.

Policy assignment not enforced (DoNotEnforce) (merge-worthy · guidance)

Set enforcementMode to Default so the assigned guardrail applies.

AuthorityMicrosoft Cloud Security Benchmark

Custom policy definition assigned nowhere (merge-worthy · guidance)

Pair the policy definition with a policy assignment — unassigned it enforces nothing.

AuthorityMicrosoft Cloud Security Benchmark

Subscriptions may leave the tenant (merge-worthy · guidance)

Set blockSubscriptionsLeavingTenant: true on the Microsoft.Subscription/policies resource.

AuthorityMicrosoft Cloud Security Benchmark

Run against Config Connector (cnrm.cloud.google.com) manifests.

Storage/SQL without encryption configuration (merge-worthy · guidance)

Configure encryption (e.g. a CMEK key) for data at rest.

AuthorityGoogle Cloud — Security best practices
Prior artGoogle Cloud Policy Library GCPStorageCMEKEncryptionConstraintV1 (overlaps)

Public IAM member (allUsers/allAuthenticatedUsers) (merge-worthy · guidance)

Remove allUsers/allAuthenticatedUsers bindings.

AuthorityGoogle Cloud — Security best practices
Prior artCheckov CKV_GCP_28 (overlaps) · KICS Cloud Storage Anonymous or Publicly Accessible (overlaps) · Google Cloud Policy Library GCPStorageBucketWorldReadableConstraintV1 (overlaps)

Missing project-id annotation (report-only · guidance)

Add the cnrm.cloud.google.com/project-id annotation.

Bucket without uniform bucket-level access (merge-worthy · guidance)

Enable uniformBucketLevelAccess.

AuthorityGoogle Cloud — Security best practices
Prior artCheckov CKV_GCP_29 (overlaps) · KICS Google Storage Bucket Level Access Disabled (overlaps) · Google Cloud Policy Library GCPStorageBucketPolicyOnlyConstraintV1 (overlaps)

Cloud SQL open to 0.0.0.0/0 (merge-worthy · guidance)

Restrict authorizedNetworks to known sources.

AuthorityGoogle Cloud — Security best practices
Prior artCheckov CKV_GCP_11 (overlaps) · KICS SQL DB Instance Publicly Accessible (overlaps) · Google Cloud Policy Library GCPSQLWorldReadableConstraintV1 (overlaps)

Missing deletion-policy annotation (report-only · guidance)

Add the cnrm.cloud.google.com/deletion-policy annotation.

Bucket versioning disabled (report-only · guidance)

Enable object versioning.

Prior artCheckov CKV_GCP_78 (overlaps) · KICS Cloud Storage Bucket Versioning Disabled (overlaps)

Cloud SQL backups disabled (report-only · guidance)

Enable backup configuration.

Prior artCheckov CKV_GCP_14 (overlaps) · KICS SQL DB Instance Backup Disabled (overlaps) · Google Cloud Policy Library GCPSQLBackupConstraintV1 (overlaps)

Firewall open to 0.0.0.0/0 (merge-worthy · guidance)

Restrict sourceRanges to known sources.

AuthorityGoogle Cloud — Security best practices
Prior artGoogle Cloud Policy Library GCPRestrictedFirewallRulesConstraintV1 (overlaps) · Checkov CKV2_GCP_12 (overlaps)

KMS key without rotation (merge-worthy · guidance)

Set a rotationPeriod on the CryptoKey.

AuthorityGoogle Cloud — Security best practices
Prior artCheckov CKV_GCP_43 (overlaps) · KICS High Google KMS Crypto Key Rotation Period (overlaps) · Google Cloud Policy Library GCPCMEKRotationConstraintV1 (overlaps)

Reference to an undefined resource (merge-worthy · guidance)

Point the reference at a resource in the output.

Missing or invalid apiVersion (merge-worthy · guidance)

Set a valid cnrm.cloud.google.com apiVersion.

Alpha API version (report-only · guidance)

Move to a beta/GA API version.

Missing managed-by label (report-only · guidance)

Add the app.kubernetes.io/managed-by label.

Cluster without Workload Identity (merge-worthy · guidance)

Enable Workload Identity on the ContainerCluster.

AuthorityGoogle Cloud — Security best practices
Prior artGoogle Cloud Policy Library GCPGKEEnableWorkloadIdentityConstraintV1 (overlaps) · Checkov CKV_GCP_69 (overlaps)

Node pool uses broad cloud-platform scope (merge-worthy · guidance)

Use narrowly-scoped OAuth scopes instead of cloud-platform.

AuthorityGoogle Cloud — Security best practices
Prior artGoogle Cloud Policy Library GCPGKEAllowedNodeSAConstraintV1 (overlaps) · Checkov CKV_GCP_31 (overlaps) · KICS VM With Full Cloud Access (overlaps)

Compute instance without Shielded VM (report-only · guidance)

Enable Shielded VM configuration.

Prior artCheckov CKV_GCP_39 (overlaps) · KICS Shielded VM Disabled (overlaps)

No IAMAuditConfig found (report-only · guidance)

Configure audit logging via IAMAuditConfig.

Prior artGoogle Cloud Policy Library GCPIAMAuditLogConstraint (overlaps) · Checkov CKV2_GCP_5 (overlaps)

No Service (enabled APIs) found (report-only · guidance)

Declare the GCP APIs you depend on.

No VPC Service Controls perimeter (report-only · guidance)

Consider an AccessContextManager ServicePerimeter.

Prior artGoogle Cloud Policy Library GCPVPCSCEnsureProjectConstraintV1 (overlaps)

Unknown field in resource spec (merge-worthy · guidance)

Remove the unknown spec field.

Missing required spec field (merge-worthy · guidance)

Add the required spec field.

Spec field has wrong type/structure (merge-worthy · guidance)

Fix the field’s type/structure.

Org Policy guardrail not enforced (merge-worthy · guidance)

Enable enforce on the rule (or remove the policy deliberately) — a disabled org policy constrains nothing.

AuthorityGoogle Cloud — Security best practices

Org Policy guardrail defines no rules (merge-worthy · guidance)

Add rules to the OrgPolicyPolicy — without them the constraint binds nothing.

AuthorityGoogle Cloud — Security best practices

Audit logging dropped or scoped down (merge-worthy · guidance)

Keep auditLogConfigs populated and remove exemptedMembers from the IAMAuditConfig.

AuthorityGoogle Cloud — Security best practices
Prior artGoogle Cloud Policy Library GCPIAMAuditLogConstraint (overlaps) · Checkov CKV2_GCP_5 (overlaps) · KICS IAM Audit Not Properly Configured (overlaps)

Run against Helm charts (Chart.yaml + templates).

Sub-chart wrapper with no templates (report-only · guidance)

Deploy the upstream chart directly instead of an empty wrapper.

Prior arthelm lint templatesDirExists (overlaps)

Chart.yaml missing required fields (merge-worthy · guidance)

Set apiVersion (v2), name, and version in Chart.yaml.

Prior arthelm lint Chartfile (validateChartName, validateChartAPIVersion, validateChartVersion) (equivalent) · chart-testing (ct) ct lint --chart-yaml-schema (overlaps)

Missing values.schema.json (report-only · guidance)

Add a values.schema.json to validate values.

Invalid Go template syntax (merge-worthy · guidance)

Fix the unbalanced template braces.

Prior arthelm lint Templates (render error) (equivalent)

Missing NOTES.txt (report-only · guidance)

Add templates/NOTES.txt for application charts.

Missing _helpers.tpl (report-only · guidance)

Add templates/_helpers.tpl.

Missing standard Helm labels (report-only · guidance)

Add the recommended app.kubernetes.io labels.

Hook weights undefined (report-only · guidance)

Define hook weights when multiple hooks exist.

Undocumented values (report-only · guidance)

Document values via schema or comments.

Dependencies pinned, not ranged (report-only · guidance)

Use semver ranges for chart dependencies.

No Helm test (report-only · guidance)

Add at least one Helm test for application charts.

Container resources not set (report-only · guidance)

Set limits/requests via values or defaults.

Prior artkube-score container-resources (overlaps) · KubeLinter unset-cpu-requirements (overlaps) · Fairwinds Polaris cpuRequestsMissing (overlaps)

Container image uses :latest or no tag (merge-worthy · guidance)

Pin the image to an explicit version tag.

AuthorityOSSF Scorecard — Pinned-Dependencies
Prior artkube-score container-image-tag (equivalent) · KICS Invalid Image Tag (equivalent) · Datree ensure-image-pinned-version (equivalent)

Container may run as root (merge-worthy · guidance)

Set runAsNonRoot in the security context.

AuthorityKubernetes — Pod Security Standards
Prior artkubesec containers[] .securityContext .runAsNonRoot == true (equivalent) · KICS Container Running As Root (equivalent) · kube-score container-security-context-user-group-id (overlaps)

Root filesystem writable (merge-worthy · guidance)

Set readOnlyRootFilesystem.

AuthorityKubernetes — Pod Security Standards
Prior artkubesec containers[] .securityContext .readOnlyRootFilesystem == true (equivalent) · KICS Root Container Not Mounted Read-only (equivalent) · kube-score container-security-context-readonlyrootfilesystem (equivalent)

Privileged container (merge-worthy · guidance)

Remove privileged mode.

AuthorityKubernetes — Pod Security Standards
Prior artkubesec containers[] .securityContext .privileged == true (equivalent) · KICS Container Is Privileged (equivalent) · kube-score container-security-context-privileged (equivalent)

Resource specs missing cpu/memory (report-only · guidance)

Set cpu and memory in limits/requests.

Prior artCheckov CKV_K8S_10 (overlaps) · Checkov CKV_K8S_12 (overlaps) · kubesec containers[] .resources .limits .memory (overlaps)

CRDs in crds/ are never upgraded (report-only · guidance)

Manage CRD upgrades outside Helm or via a separate chart.

Inline Secret data (merge-worthy · guidance)

Use ExternalSecret/SealedSecret instead of inline Secret data.

AuthorityKubernetes — Good practices for Secrets
Prior artKICS Using Kubernetes Native Secret Management (overlaps)

Unused values key (report-only · guidance)

Remove values defined but never referenced.

Deprecated/invalid Kubernetes API version (merge-worthy · guidance)

Update to a supported apiVersion.

Prior artPluto detect-files (equivalent) · helm lint validateNoDeprecations (equivalent) · kube-score stable-version (equivalent)

Pinned render carries Secret data (merge-worthy · guidance)

Declare the value with runtimeSlot() or replace the Secret with HelmExternalSecret.

AuthorityKubernetes — Good practices for Secrets
Prior artKICS Using Kubernetes Native Secret Management (overlaps)

Dead value assignment (merge-worthy · guidance)

Remove supplied values that never survive coalescing (shadowed, disabled subchart, or unknown subchart).

Run against fountain manifests (apiVersion: fountain.dev/v1) — standalone fountain apply YAML is parsed back into the entity graph, so the same rules fire on chant build and chant audit.

Literal credential in a fountain declaration (merge-worthy · guidance)

Use a ${VAR} substitution reference or an environment secret; never a literal in source.

AuthorityOWASP Top 10 for LLM Applications — LLM01: Prompt Injection

Environment does not set networking_type explicitly (merge-worthy · guidance)

Set networking_type — an open sandbox by silence is not a reviewed decision.

AuthorityManagoat: Environment, Vault and Agent primitives

Environment uses networking_type: unrestricted (merge-worthy · guidance)

Prefer limited with an allowed_hosts allowlist; an empty list denies all egress.

AuthorityManagoat: Environment, Vault and Agent primitives

Cloud-credential-shaped key or value in Environment env_vars (merge-worthy · guidance)

env_vars is plaintext config — move credentials to a secret, or serve the capability outside the sandbox.

AuthorityOWASP Top 10 for LLM Applications — LLM01: Prompt Injection

Agent ${VAR} reference does not resolve against its environment (report-only · guidance)

Declare the key on the environment, or confirm a vault supplies it at conversation create.

Vault key shadows a declared Environment key (report-only · guidance)

Vault values win on key collision silently — rename the key or confirm the override is intended.

Secret-shaped MCP env key is a literal, not a ${VAR} reference (merge-worthy · guidance)

Reference the value with ${VAR} so it resolves at spawn instead of living in source.

AuthorityOWASP Top 10 for LLM Applications — LLM01: Prompt Injection
Prior artagent-audit auth-bypass/env-secret-in-config (overlaps) · mcp-audit (APIsec) Secrets Detection (overlaps)

Agent runtime or model is not a valid value (merge-worthy · guidance)

Use a known runtime and a canonical provider/model_id.

Two declarations of one kind resolve to the same fountain name (merge-worthy · guidance)

fountain reconciles by name, so rename one. Otherwise the second silently overwrites the first.

Agent runtime “acp” is missing runtime_command, or another runtime carries one (merge-worthy · guidance)

Pair the acp runtime with the command it speaks the protocol over, and drop the field elsewhere.

Environment setup_timeout_seconds is outside 1 to 900, or not a whole number (merge-worthy · guidance)

Use an integer from 1 to 900, or omit the field for fountain’s default of 120. Changing the value invalidates the environment’s checkpoints.

A declaration uses a kind or value Managoat removed (merge-worthy · guidance)

Replace a Teammate, Schedule or Webhook, a persistent sandbox_mode, a daytona or runner provider, or the opencode runtime with what the message names. Managoat answers each with 404 or 422.

Run against Terraform root modules (a directory of .tf files) parsed into the entity graph, so the same rules fire on chant build over terraform.roots and on chant audit (#2083).

Root module declares no remote backend (merge-worthy · guidance)

Add a backend "\<type>" block (s3, gcs, azurerm, http) or a cloud \{} block to the root module’s terraform block, then terraform init -migrate-state.

Provider implied by the root has no required_providers entry (merge-worthy · guidance)

Add the provider to the terraform block’s required_providers, with both source and version set, so a future provider release can’t silently change behavior.

Prior arttflint-ruleset-terraform terraform_required_providers (equivalent) · HashiCorp reference Sentinel policies require-all-providers-have-version-constraint (equivalent) · AWS prescriptive guidance for Terraform Add automated version checks (equivalent)

Root module’s terraform block has no required_version (merge-worthy · guidance)

Set required_version = ">= \<lowest supported version>" in the terraform block.

Prior arttflint-ruleset-terraform terraform_required_version (equivalent) · HashiCorp reference Sentinel policies restrict-terraform-versions (overlaps) · HashiCorp Terraform style guide Version pinning (overlaps)

Registry-sourced module block has no version (merge-worthy · guidance)

Add a version constraint to the module block (e.g. ~> 5.0).

Prior arttflint-ruleset-terraform terraform_module_version (equivalent) · Checkov CKV_TF_2 (equivalent)

Git/hg module source is unpinned, or pinned to a mutable ref (merge-worthy · guidance)

Pin the module’s ?ref= to a tag or a full commit SHA.

Prior arttflint-ruleset-terraform terraform_module_pinned_source (equivalent) · Checkov CKV_TF_1 (extends) · KICS 3a81fc06-566f-492a-91dd-7448e409e2cd (overlaps)

Default value on a sensitive variable (merge-worthy · guidance)

Delete the default and require the caller to supply the value at apply time, through a tfvars file kept out of version control, a TF_VAR_ entry in the environment, or a workspace input.

Prior arttflint-ruleset-avm (Azure Verified Modules) avm_terraform_sensitive_variable_default_disallowed (equivalent)

Plaintext secret in a variable default or a locals value (merge-worthy · guidance)

Remove the literal, mark the variable sensitive = true, and read the value from a secret manager data source or an input at apply time, then rotate the credential, which is already in version control history.

Prior arttfsec general-secrets-sensitive-in-variable (equivalent) · tfsec general-secrets-sensitive-in-local (equivalent)

Provider block configures a hardcoded credential (merge-worthy · guidance)

Delete the credential from the provider block and let the provider read it from the environment, a shared credentials file, or an OIDC role assumption. Rotate the credential.

Prior artCheckov CKV_AWS_41 (overlaps) · KICS d7b9d850-3e06-4a75-852f-c46c2e92240b (overlaps) · Semgrep Registry rules terraform.aws.security.aws-provider-static-credentials (overlaps)

Credential-named variable is not marked sensitive (merge-worthy · guidance)

Add sensitive = true to the variable so its value is not printed in plan and apply output. The value is still stored in plaintext in state, so keep the state remote and encrypted.

AuthorityHashiCorp Terraform style guide — Variables
Prior artHashiCorp Terraform style guide Variables: for sensitive variables, such as passwords and private keys, set the sensitive parameter to true (equivalent)

Variable declares no type constraint (report-only · guidance)

Add a type to the variable (string, number, bool, list(string), object(\{...})).

Prior arttflint-ruleset-terraform terraform_typed_variables (equivalent) · KICS fc5109bf-01fd-49fb-8bde-4492b543c34a (equivalent)

Undocumented variable (report-only · guidance)

Add a description saying what the value is for and what a valid one looks like.

Prior arttflint-ruleset-terraform terraform_documented_variables (equivalent) · KICS 2a153952-2544-4687-bcc9-cc8fea814a9b (equivalent) · HashiCorp reference Sentinel policies validate-variables-have-descriptions (equivalent)

Undocumented output (report-only · guidance)

Write a description for the output, covering what the value is and what a caller can rely on it for.

Prior arttflint-ruleset-terraform terraform_documented_outputs (equivalent) · KICS 59312e8a-a64e-41e7-a252-618533dd1ea8 (equivalent)

lifecycle ignore_changes is set to all (merge-worthy · guidance)

Replace ignore_changes = all with the list of attributes that genuinely change outside Terraform, so every other attribute is still reconciled.

Prior arttflint-ruleset-redeploy terraform_ignore_changes_all (equivalent)

Child module configures a provider block (merge-worthy · guidance)

Move the provider configuration to the root module and pass it into the module with providers = \{ ... }, leaving at most an alias-only block in the module.

Prior arttflint-ruleset-avm (Azure Verified Modules) avm_terraform_provider_block_disallowed (equivalent) · Google Cloud Terraform best-practices series Build reusable modules: modules must not configure providers (equivalent) · AWS prescriptive guidance for Terraform Structure: declare provider configurations in the root module (equivalent)

Child module declares a backend or cloud block (merge-worthy · guidance)

Delete the backend/cloud block from the child module. State belongs to the root module that calls it, one state for the whole tree.

Prior artGoogle Cloud Terraform best-practices series Build reusable modules: state configuration belongs to the root module (equivalent)

Attribute value is a quoted interpolation of a single expression (report-only · deterministic)

Drop the quotes and the $\{}: write x = var.y, not x = "$\{var.y}".

Prior arttflint-ruleset-terraform terraform_deprecated_interpolation (overlaps)

Module block uses depends_on (report-only · guidance)

Remove depends_on from the module call and pass an attribute of the dependency into a module input, so Terraform derives the narrower edge itself.

Prior arttflint-ruleset-redeploy terraform_module_depends_on (equivalent)

Output value is a whole resource or data source (report-only · guidance)

Return the attribute the caller needs (.id, .arn, .endpoint) instead of the whole block.

Prior arttflint-ruleset-redeploy terraform_output_resource (equivalent)

Meta-argument explicitly set to its default of false (report-only · deterministic)

Deleting the line is the whole fix. sensitive, ephemeral, prevent_destroy and create_before_destroy are false unless set.

Prior arttflint-ruleset-redeploy terraform_redundant_default (equivalent)

Declaration is never referenced in its module scope (report-only · guidance)

Delete the variable, local, data source or aliased provider, or reference it where it was meant to be used.

Prior arttflint-ruleset-terraform terraform_unused_declarations (overlaps)

count builds instance identities from count.index where for_each is safer (report-only · guidance)

Switch to for_each over a map or set so each instance is addressed by a stable key, then terraform state mv the existing indexed instances onto their new keys.

Prior arttflint-ruleset-redeploy terraform_prefer_for_each (overlaps) · choudoufu RuleCountIndex (overlaps) · HashiCorp Terraform style guide Resources: use for_each for a dynamic resource count (overlaps)

Credential-named resource attribute holds a plaintext literal (merge-worthy · guidance)

Replace the constant with a lookup, either an input the caller supplies or a data source pointed at whatever vault owns the credential, and rotate what was committed.

Prior arttfsec general-secrets-no-plaintext-exposure (overlaps) · KICS a88baa34-e2ad-44ea-ad6f-8cac87bc7c71 (overlaps)

Terraform state committed to the repository (merge-worthy · guidance)

Delete the state file (or .terraform/) from version control, add it to .gitignore, move the state to a remote backend, and rotate every credential the file held.

AuthorityHashiCorp Terraform style guide — .gitignore
Prior artHashiCorp Terraform style guide .gitignore: do not commit terraform.tfstate, terraform.tfstate.* backups, or the .terraform directory (equivalent)

Live root declares a backend or cloud block, which choudoufu ignores (merge-worthy · guidance)

Keep a backend block if other roots read this estate’s outputs or the record store should be derived from its bucket; declare record_store to put records elsewhere. Remove a cloud block, which choudoufu drops entirely, or swap it for a backend block.

Prior artchoudoufu RuleStateBackend (equivalent)

Live root references a non-default terraform.workspace, which choudoufu refuses (merge-worthy · guidance)

Remove workspace from the root’s terraform.roots config, and remove any terraform.workspace reference from its HCL; choudoufu refuses any workspace but “default” on a live root.

Live root declares delete: “never” but its policy leaves undeclared_tagged at “delete” (merge-worthy · guidance)

Add undeclared_tagged = “keep” (or “untag” or “report”) to the live root’s policy block, or change terraform.roots.<name>.delete to “owned-only” or “gated” if an owned orphan should be deleted after all.

Live root’s policy block sets undeclared_untagged = “delete” (merge-worthy · guidance)

Remove undeclared_untagged = “delete” from the live root’s policy block. chant never proposes deleting a resource it does not own; narrow the estate’s own ownership answer (undeclared_tagged) instead of the account’s.

Prior artchoudoufu RulePolicyScope (extends)

Live root is watched by a TerraformWatchOp built without live: true (merge-worthy · guidance)

Set live: true on the TerraformWatchOp that names this root, so the Plan phase runs choudoufuLivePlan and reports the unowned and adoptable counts as well as drift. Drop the root’s estate instead if it is not a live root.

Live root names its estate both in chant.config and in its own HCL (merge-worthy · guidance)

Pick one. A root whose directory is shared across environments declares no estate in HCL and names it per root with terraform.roots.<name>.estate; a root with its own live block already has an estate and needs nothing in chant.config. The declaration wins today, so the config value is written down and never used.

Security group rule allows unrestricted ingress on a sensitive port (merge-worthy · guidance)

Restrict the CIDR on SSH, RDP, MySQL and PostgreSQL ports to the sources that need them, or reach the host through a bastion, a VPN or SSM Session Manager.

AuthorityAWS Well-Architected Framework, Security Pillar
Prior artCheckov CKV_AWS_24 (overlaps) · Checkov CKV_AWS_25 (overlaps) · tfsec aws-vpc-no-public-ingress-sgr (overlaps) · trivy-checks aws-ec2-no-public-ingress-sgr (overlaps) · KICS 381c3f2a-ef6f-4eff-99f7-b169cda3422c (overlaps) · HashiCorp reference Sentinel policies restrict-ingress-sg-rule-ssh (overlaps) · HashiCorp reference Sentinel policies restrict-ingress-sg-rule-rdp (overlaps)

IAM policy allows a wildcard Action or Resource (merge-worthy · guidance)

Name the actions the workload calls and the ARNs it touches. For the few actions that accept only Resource ”*” (ecr:GetAuthorizationToken, sts:GetCallerIdentity), keep that statement on its own and suppress it with # chant-ignore-block: TF031. A policy TF031 reports as not determined is built from an expression; it is not a finding.

AuthorityAWS IAM security best practices (Apply least-privilege permissions)
Prior arttfsec aws-iam-no-policy-wildcards (overlaps) · Checkov CKV_AWS_63 (overlaps) · Checkov CKV_AWS_49 (extends) · Checkov CKV_AWS_355 (overlaps) · Checkov CKV_AWS_356 (overlaps)

ECS container definition passes a credential as a plaintext environment value (merge-worthy · guidance)

Move the value from the container’s environment to its secrets, with a valueFrom naming a Secrets Manager secret or SSM parameter, and rotate the committed value.

AuthorityAmazon ECS Developer Guide: Pass sensitive data to an Amazon ECS container
Prior arttfsec aws-ecs-no-plaintext-secrets (overlaps) · trivy-checks aws-ecs-no-plaintext-secrets (overlaps)

RDS DB instance or cluster storage is not encrypted (merge-worthy · guidance)

Set storage_encrypted = true (and kms_key_id for a customer managed key). An existing database cannot be encrypted in place: restore an encrypted copy of a snapshot. An Aurora cluster, or a database created from a snapshot or replica, is reported as not determined, not as a finding.

AuthorityAmazon RDS User Guide: Encrypting Amazon RDS resources
Prior arttfsec aws-rds-encrypt-instance-storage-data (overlaps) · tfsec aws-rds-encrypt-cluster-storage-data (overlaps) · trivy-checks aws-rds-encrypt-instance-storage-data (overlaps) · trivy-checks aws-rds-encrypt-cluster-storage-data (overlaps) · Checkov CKV_AWS_16 (overlaps) · Checkov CKV_AWS_96 (overlaps) · KICS 08bd0760-8752-44e1-9779-7bb369b2b4e4 (overlaps)

SNS topic has no server-side encryption (merge-worthy · guidance)

Set kms_master_key_id to a customer managed KMS key, or to "alias/aws/sns" for the AWS managed one. No AWS default encrypts a topic that names no key.

AuthorityAmazon SNS Developer Guide: Securing Amazon SNS data with server-side encryption
Prior arttfsec aws-sns-enable-topic-encryption (equivalent) · trivy-checks aws-sns-enable-topic-encryption (equivalent) · Checkov CKV_AWS_26 (equivalent) · KICS 28545147-2fc6-42d5-a1f9-cf226658e591 (equivalent)

SQS queue turns server-side encryption off (merge-worthy · guidance)

Remove sqs_managed_sse_enabled = false (new queues are encrypted with SSE-SQS by default), set it to true, or set kms_master_key_id. A queue that sets neither attribute is encrypted and is not reported.

AuthorityAmazon SQS Developer Guide: Encryption at rest in Amazon SQS
Prior arttfsec aws-sqs-enable-queue-encryption (overlaps) · trivy-checks aws-sqs-enable-queue-encryption (overlaps) · Checkov CKV_AWS_27 (overlaps) · KICS 6e8849c1-3aa7-40e3-9063-b85ee300f29f (overlaps)

EBS volume does not ask for encryption (merge-worthy · guidance)

Set encrypted = true (and kms_key_id for a customer managed key). A volume that leaves encrypted unset depends on the Region’s EBS encryption by default and is reported as not determined, not as a finding.

AuthorityAmazon EBS User Guide: Amazon EBS encryption
Prior arttrivy-checks aws-ec2-enable-volume-encryption (overlaps) · Checkov CKV_AWS_3 (overlaps) · KICS cc997676-481b-4e93-aa81-d19f8c5e9b12 (overlaps)

ECR repository allows mutable image tags (merge-worthy · guidance)

Set image_tag_mutability = "IMMUTABLE", or "IMMUTABLE_WITH_EXCLUSION" with an image_tag_mutability_exclusion_filter naming the few moving tags (latest) that must stay mutable. The provider default is MUTABLE.

AuthorityAmazon ECR User Guide: Preventing image tags from being overwritten
Prior arttfsec aws-ecr-enforce-immutable-repository (overlaps) · trivy-checks aws-ecr-enforce-immutable-repository (overlaps) · Checkov CKV_AWS_51 (overlaps) · KICS d1846b12-20c5-4d45-8798-fc35b79268eb (overlaps)

OCI module source has no tag or digest, or a mutable tag (merge-worthy · guidance)

Pin the oci:// source with ?digest=sha256:... (a digest cannot move) or an exact version tag (?tag=1.4.0). A source with no tag pulls latest.

Registry module version is a range, not an exact version (report-only · guidance)

Set an exact version (version = "1.4.0") for projects that pin modules. Off by default.

Root has no committed .terraform.lock.hcl (report-only · guidance)

Run terraform init in the root and commit the .terraform.lock.hcl it writes. Off by default; checked only where the root’s directory is known.

Terragrunt dependency lets mock_outputs stand in for apply (merge-worthy · guidance)

Set mock_outputs_allowed_terraform_commands = ["validate", "plan"] on every dependency that sets mock_outputs. Terragrunt reads a missing or empty list as every command, apply included.

Terragrunt dependency sets skip_outputs together with mock_outputs (merge-worthy · guidance)

Drop skip_outputs, or pass the values as inputs. With skip_outputs = true the upstream outputs are never read, so every run uses the mocks.

Terragrunt terraform.source names no version (git ref, tfr version or oci tag) (merge-worthy · guidance)

Pin the source: ?ref= for git, ?version= for tfr://, ?digest= or ?tag= for oci://.

Terragrunt config keeps state in a local backend (merge-worthy · guidance)

Use a shared backend (S3, GCS) in remote_state. State written by backend = "local" stays on the runner and is lost with it.

No Terragrunt config sets terragrunt_version_constraint (report-only · guidance)

Set terragrunt_version_constraint = ">= 1.1.0" in the root config. Off by default; judged only across the configs scanned.

Live root resolves to the local record store in a CI run (report-only · guidance)

Keep or add a backend block of type s3, gcs or azurerm with a literal bucket, so choudoufu derives the record store from it, or declare record_store in the live block or estate.chdf.hcl. The rule is off by default and terragucci turns it on for its users; an emulator or test lane that keeps the local store on purpose sets CHANT_ALLOW_LOCAL_RECORD_STORE=1.

Live root pins a module version the known-module catalog has no row for, or one with refusals (report-only · guidance)

Run choudoufu live-check on the root to see each refused site, or pin a version whose examples are clear in the static tier of choudoufu’s module table (https://intentius.io/choudoufu/aws/compatibility/#modules). Off by default; terragucci turns it on for its users.

Lexicon-independent — scans the raw text of every scanned file for likely credentials, regardless of which audit lexicons are installed. Matched values are always redacted; see suppressing false positives.

AWS access key ID found (merge-worthy · guidance)

Remove the key from source, rotate it in IAM, and load it from a secret store or environment variable instead.

AuthorityGitHub — About secret scanning
Prior artgitleaks aws-access-token (equivalent) · TruffleHog aws (overlaps) · detect-secrets AWSKeyDetector (equivalent)

AWS secret access key found (merge-worthy · guidance)

Remove the key from source, rotate it in IAM, and load it from a secret store or environment variable instead.

AuthorityGitHub — About secret scanning
Prior artgitleaks generic-api-key (overlaps) · TruffleHog aws (overlaps) · detect-secrets AWSKeyDetector (overlaps)

GitHub token found (merge-worthy · guidance)

Remove the token from source and revoke it at github.com/settings/tokens; use a GitHub Actions secret instead.

AuthorityGitHub — About secret scanning
Prior artgitleaks github-pat (overlaps) · TruffleHog github (equivalent) · detect-secrets GitHubTokenDetector (overlaps)

Slack token found (merge-worthy · guidance)

Remove the token from source and revoke it in the Slack app’s OAuth settings.

AuthorityGitHub — About secret scanning
Prior artgitleaks slack-bot-token (overlaps) · TruffleHog slack (overlaps) · detect-secrets SlackDetector (overlaps)

Google API key found (merge-worthy · guidance)

Remove the key from source and regenerate it in the Google Cloud Console credentials page.

AuthorityGitHub — About secret scanning
Prior artgitleaks gcp-api-key (equivalent) · TruffleHog googlegemini (overlaps)

Stripe live secret key found (merge-worthy · guidance)

Remove the key from source and roll it in the Stripe dashboard immediately — this is a live-mode key.

AuthorityGitHub — About secret scanning
Prior artgitleaks stripe-access-token (overlaps) · TruffleHog stripe (overlaps) · detect-secrets StripeDetector (overlaps)

Private key block found (merge-worthy · guidance)

Remove the private key from source, rotate the keypair, and load the key from a secret store instead.

AuthorityGitHub — About secret scanning
Prior artgitleaks private-key (equivalent) · TruffleHog privatekey (equivalent) · detect-secrets PrivateKeyDetector (equivalent)

Bearer/authorization token found (merge-worthy · guidance)

Remove the token from source; if it’s long-lived, revoke and reissue it via the issuing service.

AuthorityGitHub — About secret scanning
Prior artgitleaks curl-auth-header (overlaps)

Credentials embedded in a connection string (merge-worthy · guidance)

Move the username/password out of the URI into a secret store, and rotate the credential.

AuthorityGitHub — About secret scanning
Prior artdetect-secrets BasicAuthDetector (equivalent) · TruffleHog uri (overlaps) · gitleaks curl-auth-user (overlaps)

High-entropy string — possible secret (merge-worthy · guidance)

Confirm whether this is a live credential; if so, remove it from source and rotate it. If it’s a false positive, suppress with a chant-audit-ignore comment or an allowlist entry.

AuthorityGitHub — About secret scanning
Prior artdetect-secrets Base64HighEntropyString (overlaps) · detect-secrets HexHighEntropyString (overlaps) · gitleaks generic-api-key (overlaps)

Lexicon-independent, audit-only (#446) — scans wrangler.toml, Cloudflare Workers’ native deploy config, which the engine cannot otherwise parse (it is not YAML/JSON). No authoring surface: chant does not write Wrangler config, it only reads it for these checks.

*Production environment exposed on .workers.dev (merge-worthy · guidance)

Remove workers_dev (or set it to false) for this environment and rely on its custom domain/route instead of the shared public subdomain.

AuthorityCloudflare Workers — workers.dev

Credential-shaped key stored in [vars] (merge-worthy · guidance)

Move the value out of [vars] and into wrangler secret put \<name> so it isn’t committed to source or visible in wrangler dev/the dashboard.

AuthorityCloudflare Workers — Secrets

Observability explicitly disabled (report-only · guidance)

Set observability.enabled = true (or remove the override) so Workers Logs are recorded for this deployment.

Unscoped wildcard route (merge-worthy · guidance)

Scope the route pattern to the intended zone (e.g. “example.com/”) instead of a bare "" or ”/” that matches every zone on the account.

AuthorityCloudflare Workers — Routes

Non-production environment shares a data store with production (merge-worthy · guidance)

Give the non-production environment its own KV namespace/R2 bucket/D1 database id instead of reusing production’s.

AuthorityCloudflare Workers — Wrangler environments

Static assets served from the project root (merge-worthy · guidance)

Point [site].bucket / [assets].directory at a dedicated public output folder, not the project root, so non-public files (config, source maps, .git) aren’t served.

AuthorityCloudflare Workers — Static assets

Lexicon-independent, audit-only (#1979) — parses nginx’s native directive/block config (nginx.conf and .conf files under nginx-ish directories, confirmed by content). No authoring surface: chant does not write nginx config, it only reads it for these checks.

Deprecated TLS protocol enabled (merge-worthy · guidance)

Remove SSLv2/SSLv3/TLSv1/TLSv1.1 from ssl_protocols and serve TLSv1.2 and TLSv1.3 only.

AuthorityMozilla — Server Side TLS
Prior artgixy-ng (maintained Gixy fork) weak_ssl_tls (overlaps)

Weak cipher suite enabled (merge-worthy · guidance)

Remove the RC4/DES/MD5/NULL/EXPORT-class entries from ssl_ciphers and use a modern cipher list (e.g. Mozilla’s intermediate configuration).

AuthorityMozilla — Server Side TLS
Prior artgixy-ng (maintained Gixy fork) weak_ssl_tls (overlaps)

Directory listing enabled (merge-worthy · guidance)

Remove autoindex on (or scope it to a directory that is genuinely meant to be enumerated) so file listings aren’t served to anyone who asks.

AuthorityCWE-548 — Exposure of Information Through Directory Listing

alias path traversal (merge-worthy · guidance)

End the location prefix with ”/” so it matches the trailing slash of the alias target — without it, a request for “<prefix>../” escapes the aliased directory.

AuthorityGixy — alias traversal
Prior artGixy alias_traversal (equivalent) · gixy-ng (maintained Gixy fork) alias_traversal (equivalent)

Status endpoint with no access restriction (merge-worthy · guidance)

Restrict the stub_status location with allow/deny (or auth_basic/auth_request) so connection metrics aren’t public reconnaissance.

Authoritynginx — ngx_http_stub_status_module
Prior artgixy-ng (maintained Gixy fork) status_page_exposed (overlaps)

Server version disclosure (report-only · guidance)

Add server_tokens off; in the http block so nginx stops advertising its exact version in the Server header and error pages.

Prior artgixy-ng (maintained Gixy fork) version_disclosure (equivalent)

Access logging disabled at server scope (report-only · guidance)

Re-enable access_log at http/server scope (silencing a single noisy location is fine) so requests are recorded for incident investigation.

Run by chant audit --agents against the agent configuration on a machine — instruction files, MCP servers, skills, plugins, and permissions at system, user, and project scope. Unlike every other family here, these do not fire on repository YAML.

MCP server runs an unpinned package (merge-worthy · guidance)

Pin the package spec to an exact version (server@1.2.3), so a new upstream release can’t execute on this machine unreviewed.

AuthorityOSSF Scorecard — Pinned-Dependencies

Literal credential in agent config (merge-worthy · guidance)

Replace the value with an environment reference ($\{TOKEN}) and keep the secret in a secret store — agent config files sync, back up, and get shared.

AuthorityCWE-798 — Use of Hard-coded Credentials
Prior artagent-audit auth-bypass/env-secret-in-config (equivalent) · mcp-audit (APIsec) Secrets Detection (overlaps) · Snyk Agent Scan (formerly mcp-scan) W008 (overlaps)

MCP server reached over cleartext HTTP (merge-worthy · guidance)

Use an https:// endpoint. Tool arguments and results — including data the agent read locally — otherwise cross the network in the clear.

AuthorityCWE-319 — Cleartext Transmission of Sensitive Information

Remote skill or plugin is unpinned (merge-worthy · guidance)

Pin the source to a tag or commit sha, so the instructions the agent follows can’t change upstream without a local edit.

AuthorityOSSF Scorecard — Pinned-Dependencies

Tool permission granted without constraint (merge-worthy · guidance)

Scope the grant to the specific commands you run (Bash(git status:*)), and re-enable the confirmation prompt for dangerous operations.

User-scope config applies to every project (report-only · guidance)

Move project-specific instructions, MCP servers, and skills to that project’s own config so they don’t follow you into unrelated repos.

MCP server declared in multiple files (report-only · guidance)

Delete the shadowed declarations. The harness silently picks one, so the file you read may not be the one that decides what runs.

Instruction file exceeds the attention budget (report-only · guidance)

Move situational guidance into skills that load on demand, so the always-on instructions stay short enough to be followed reliably.

chant’s rules were written against the output chant emits, but much of what they check was checked first by a dedicated tool. Each rule above that has a counterpart names it under Prior art, with the upstream rule id and how the two relate.

  • equivalent is the same condition at the same scope.
  • overlaps shares the core condition, with one side narrower or broader, or expressed for a different dialect of the same control.
  • extends means chant checks a strict superset of the upstream rule.

This is credit rather than authority, and it never changes a rule’s tier or category. A credit counts once per upstream rule cited, so a chant rule that names two zizmor audits adds two.

ToolKindLicenceCredits
CheckovscannerApache-2.079
KICSscannerApache-2.056
zizmorscannerMIT38
cfn_nagscannerMIT20
GitLab CI/CD YAML referencespecificationCC-BY-SA-4.020
AWS Guard Rules RegistryscannerApache-2.019
Fairwinds PolarisscannerApache-2.018
KubeLinterscannerApache-2.017
kube-scorescannerMIT15
cfn-lintscannerMIT-014
PSRule for AzurescannerMIT13
Google Cloud Policy LibraryscannerApache-2.012
poutinescannerApache-2.011
OpenSSF ScorecardscannerApache-2.011
tfsecscannerMIT11
gitleaksscannerMIT10
octoscanscannerGPL-3.010
detect-secretsscannerApache-2.09
tflint-ruleset-terraformscannerMPL-2.09
actionlintscannerMIT8
hadolintscannerGPL-3.08
trivy-checksscannerMIT8
TruffleHogscannerAGPL-3.08
gixy-ng (maintained Gixy fork)scannerMPL-2.05
kubesecscannerApache-2.05
HashiCorp reference Sentinel policiesspecificationMPL-2.05
tflint-ruleset-redeployscanner0BSD5
DatreescannerApache-2.04
HashiCorp Terraform style guidespecificationn/a4
helm lintvendor-validatorApache-2.04
choudoufuscannerMPL-2.03
Flux Kustomization API referencespecificationn/a3
agent-auditscannerMIT2
ARM Template Toolkit (arm-ttk)scannerMIT2
AWS prescriptive guidance for Terraformspecificationn/a2
Bicep linterscannerMIT2
DocklescannerApache-2.02
Google Cloud Terraform best-practices seriesspecificationn/a2
mcp-audit (APIsec)scannerMIT2
tflint-ruleset-avm (Azure Verified Modules)scannerMIT2
Snyk Agent Scan (formerly mcp-scan)scannerApache-2.01
chart-testing (ct)vendor-validatorApache-2.01
GixyscannerMPL-2.01
PlutoscannerApache-2.01
Semgrep Registry rulesscannerSemgrep Rules License v1.0 (proprietary, not an SPDX id)1

chant