Skip to content

prior-art: 247 upstream rules with no chant counterpart — the baseline the monthly sweep starts from #2080

Description

@lex00

Filed from the prior-art research behind #2079 (2026-09-04). While mapping chant's audit rules to the open-source tools that check the same things, each pass also noted upstream rules with no chant counterpart. This is that list: 247 rules across 37 tools, one line each, as the researcher recorded them. It is a candidate backlog, not a commitment; many are out of scope by design (Terraform-only controls, live-cluster reads, Ansible), and some are things chant refuses to do (guessing at intent).

The monthly prior-art-sweep workflow will surface new upstream rules from here on; this issue is the baseline it starts from.

How to read a line: tool rule then what it checks that chant does not. Family headings follow the research passes.

GitHub Actions

actionlint

  • Unexpected keys: typos and case errors in workflow keys
  • Unexpected mapping values: values whose type does not match the schema
  • Syntax check for expression ${{ }}: lexical/parse errors inside expressions
  • Type checks for expression syntax in ${{ }}: static type errors in expressions, incl. steps/matrix/needs contextual typing and comparison operators
  • Contexts and built-in functions: unknown contexts, properties or functions, and their availability per workflow key
  • shellcheck integration for run:: runs shellcheck on run: shell scripts
  • pyflakes integration for run:: runs pyflakes on run: python scripts
  • Matrix values: duplicate matrix values and exclude: entries that match no combination
  • Webhook events validation: unknown event names, activity types and filter/event compatibility
  • Workflow dispatch event validation: workflow_dispatch input types and defaults
  • Glob filter pattern syntax validation: branch/tag/path glob syntax
  • CRON syntax and IANA timezone string at on.schedule: schedule cron and timezone validity
  • Runner labels: runs-on labels not in the GitHub-hosted/preset list or actionlint.yaml config (inverse of WFJ011)
  • Action format in uses:: malformed uses: references (missing owner/ref, empty docker tag, local path prefix)
  • Local action inputs validation at with:: with: inputs vs local action.yml definitions
  • Popular action inputs validation at with:: with: inputs vs bundled metadata for popular actions
  • Outdated popular actions detection at uses:: popular action versions running on a retired Node runtime
  • Shell name validation at shell:: unknown shell names
  • Job ID and step ID uniqueness: duplicate job or step IDs (case-insensitive); not workflow names
  • Environment variable names: invalid env var names
  • Permissions: unknown permission scopes or access levels (validity only, not least-privilege)
  • Reusable workflows: workflow_call inputs/secrets/outputs consistency between caller and callee
  • ID naming convention: job/step ID character rules
  • Action metadata syntax validation: action.yml structure
  • Deprecated inputs usage: with: inputs marked deprecated by the action
  • YAML anchors: anchor/alias correctness

octoscan

  • dangerous-action: actions that download untrusted artifacts (e.g. from a workflow_run trigger)
  • local-action: any local action use (flagged because the tool cannot parse it)
  • repo-jacking: uses: referencing a non-existent GitHub user/org (needs network)
  • shellcheck: runs shellcheck on run: scripts (from actionlint)
  • oidc-action: debug rule: presence of OIDC cloud-auth actions
  • debug-external-trigger: debug rule: workflow can be externally triggered
  • debug-artefacts: debug rule: workflow uploads any artifact
  • debug-js-exec: debug rule: github-script steps that exec system commands

poutine

  • debug_enabled: ACTIONS_RUNNER_DEBUG / ACTIONS_STEP_DEBUG set in the workflow
  • github_action_from_unverified_creator_used: action owner is not a GitHub Marketplace verified creator
  • known_vulnerability_in_build_platform: self-hosted GitLab/GHES build platform version with an OSV advisory
  • unpinnable_action: composite action whose own transitive uses:/downloads are mutable, so pinning it is ineffective

zizmor

  • adhoc-packages: run: steps that install packages (npm/gem/bundle/yarn) outside a managed lockfile
  • impostor-commit: uses: pins a commit that exists only in a fork of the referenced repo's network (needs network)
  • insecure-url-scheme: plaintext http:// or git:// URLs in pre-commit configs
  • ref-confusion: symbolic ref that is ambiguous between a branch and a tag of the same name (needs network)
  • self-repository: in-repo action references not using the newer self-repository ($/...) syntax
  • stale-action-refs: hash-pinned commit that does not correspond to any tag or release (needs network)
  • undocumented-permissions: explicit permissions: block without an explanatory comment (pedantic)
  • unpinned-tools: tools installed in run: steps without a pinned version
  • unredacted-secrets: secrets treated as structured values (fromJSON(secrets.X).field) so the runner cannot redact them
  • unsound-ternary: cond && value || fallback pseudo-ternaries whose true arm is statically falsy

GitLab CI

checkov

  • CKV_GITLABCI_1: Script line starting with curl that references a $CI* variable (exfiltration heuristic); chant has no curl-with-CI-variable check.
  • CKV_GITLABCI_2: Two or more rules:if clauses on CI_PIPELINE_SOURCE == merge_request_event / push (double pipelines); distinct condition from WGL023's when: always.
  • CKV_GITLABCI_3: Inventory-only: enumerates image/services usage and always PASSES; not a digest-pinning check, so not lineage for WGL031.

poutine

Kubernetes and Helm

chart-testing

  • ct lint --check-version-increment: chart version must be bumped when chart files change; also validates maintainers against the repo

checkov

  • CKV_K8S_40: container UID is low / may collide with host users (also KICS 02323c00)
  • CKV_K8S_43: image not pinned by digest (also KICS 7c81d34c, Datree ensure-digest-tag)
  • CKV_K8S_153: NGINX Ingress annotation snippets (CVE-2021-25742), with CKV_K8S_152/154
  • CKV_K8S_155: ClusterRole controls admission webhook configurations; CKV_K8S_156-158 cover CSR approval, bind and escalate verbs

datree

  • ensure-cronjob-scheduler-valid: CronJob schedule expression is not valid cron

helm-lint

  • validateChartIconPresence: Chart.yaml icon recommended (info)
  • validateMetadataName: rendered object name violates Kubernetes naming rules
  • validateDependenciesUnique: duplicate dependency name/alias in Chart.yaml

kube-linter

  • privilege-escalation-container: allowPrivilegeEscalation not set to false (also Polaris privilegeEscalationAllowed, Checkov CKV_K8S_20, KICS 5572cc5e)
  • docker-sock: docker.sock hostPath mounted into a container (also kubesec spec-volumes-hostpath-path-var-run-docker-sock, Checkov CKV_K8S_27)
  • sensitive-host-mounts: sensitive host directories mounted (also KICS 5308a7a8)
  • writable-host-mount: hostPath mounted read-write (also Datree ensure-hostpath-mounts-readonly)
  • unsafe-sysctls: pod specifies unsafe sysctls
  • unsafe-proc-mount: procMount=Unmasked
  • default-service-account: pod runs as the default ServiceAccount (also Checkov CKV_K8S_41/42, Datree ensure-default-service-account-not-used)
  • non-existent-service-account: pod references a ServiceAccount not present in the manifests
  • wildcard-in-rules: Role/ClusterRole uses '*' (also Checkov CKV_K8S_49, KICS 6b896afb)
  • cluster-admin-role-binding: binding to cluster-admin (also Polaris clusterrolebindingClusterAdmin)
  • access-to-secrets: subject can get/list/watch Secrets (also Checkov CKV2_K8S_5)
  • dangling-service: Service selector matches no workload (also kube-score service-targets-pod, KICS 3ca03a61)
  • no-anti-affinity: multi-replica workload without podAntiAffinity (also kube-score deployment-has-host-podantiaffinity)
  • duplicate-env-var: duplicate env var names (also kube-score environment-variable-key-duplication)
  • liveness-port: probe targets a port the container does not expose (also readiness-port, startup-port)
  • pdb-max-unavailable: PDB maxUnavailable=0 blocks all disruptions (also pdb-min-available)
  • job-ttl-seconds-after-finished: standalone Job lacks ttlSecondsAfterFinished
  • ssh-port: container exposes port 22
  • exposed-services: NodePort/LoadBalancer Service types (also kube-score service-type)
  • deprecated-service-account-field: pod uses spec.serviceAccount instead of serviceAccountName

kube-score

  • pod-networkpolicy: pod not selected by any NetworkPolicy (also Checkov CKV2_K8S_6, kube-linter non-isolated-pod)
  • container-ephemeral-storage-request-and-limit: ephemeral-storage requests/limits missing
  • cronjob-has-deadline: CronJob lacks startingDeadlineSeconds (also KICS 192fe40b, Datree ensure-cronjob-deadline)
  • pod-probes-identical: readiness and liveness probes are identical
  • container-seccomp-profile: no seccomp profile (also Checkov CKV_K8S_31, KICS f377b83e)
  • statefulset-has-servicename: StatefulSet serviceName does not point at an existing headless Service
  • deployment-targeted-by-hpa-does-not-have-replicas-configured: static replicas on an HPA-managed Deployment (also KICS 5744cbb8)

kubesec

  • metadata .annotations .container.apparmor.security.beta.kubernetes.io/nginx: AppArmor profile annotation absent (also KICS 8b36775e)

nova

  • find: installed Helm release is behind the latest chart version in known repositories

polaris

  • automountServiceAccountToken: SA token automounted (also Checkov CKV_K8S_38, KICS 48471392)
  • linuxHardening: no AppArmor/Seccomp/SELinux/capability drop in use
  • dangerousCapabilities: container adds a dangerous capability such as SYS_ADMIN (also Checkov CKV_K8S_39, KICS 235236ee, kubesec capabilities-add-index-sys-admin)
  • hostPortSet: container binds a hostPort (also Checkov CKV_K8S_26)
  • clusterrolePodExecAttach: role grants pods/exec or pods/attach (also KICS c589f42c, d45330fd)
  • priorityClassNotSet: pod has no priorityClassName
  • topologySpreadConstraint: no topologySpreadConstraints on the pod (also kube-score pod-topology-spread-constraints)
  • pdbMinAvailableGreaterThanHPAMinReplicas: PDB minAvailable exceeds HPA minReplicas

CloudFormation

cfn-lint

  • E3060: Subnet CIDRs overlap other subnets in the same VPC
  • E3007: Duplicate resource/parameter logical names
  • W8001: Declared condition is never used
  • W1028: Fn::If branch can never be reached
  • I3011: Stateful resource lacks UpdateReplacePolicy/DeletionPolicy

cfn-nag

  • F38: IAM role allows iam:PassRole on a wildcard resource
  • F16: S3 bucket policy allows a wildcard principal
  • W35: S3 bucket has no access logging
  • W41: S3 bucket has no server-side encryption option set
  • W51: S3 bucket has no bucket policy at all
  • W58: Lambda function role lacks permission to write CloudWatch Logs
  • W9: Security group ingress CIDR is not a /32
  • W5: Security group egress open to world
  • W28: Resource declares an explicit physical name, blocking replacement updates
  • W74: DynamoDB table not encrypted with a KMS key
  • W10: CloudFront distribution has no access logging
  • W33: EC2 subnet auto-assigns public IPs on launch
  • F12: IAM managed policy attached directly to a user rather than a group
  • F10: IAM user has an inline policy
  • F665: WAF WebACL default action is ALLOW
  • W76: IAM policy SPCM complexity score above threshold
  • F26: RDS DBCluster storage not encrypted (chant covers DBInstance only)

checkov

  • CKV_AWS_62: IAM policy grants full : administrative privileges
  • CKV_AWS_110: IAM policy allows privilege escalation actions
  • CKV_AWS_107: IAM policy allows credential exposure actions
  • CKV_AWS_60: IAM role trust policy lets any principal assume it
  • CKV_AWS_45: Lambda environment variables contain hard-coded secrets (chant only covers ECS Environment)
  • CKV_AWS_173: Lambda environment variables not encrypted with a KMS key
  • CKV_AWS_364: Lambda permission for an AWS service lacks SourceArn/SourceAccount
  • CKV_AWS_258: Lambda function URL has AuthType NONE
  • CKV_AWS_19: S3 bucket has no server-side encryption
  • CKV_AWS_21: S3 bucket versioning disabled
  • CKV_AWS_35: CloudTrail logs not KMS-encrypted
  • CKV_AWS_36: CloudTrail log file validation disabled
  • CKV_AWS_58: EKS cluster secrets encryption disabled
  • CKV_AWS_100: EKS node group allows SSH from 0.0.0.0/0
  • CKV_AWS_42: EFS file system not encrypted at rest
  • CKV_AWS_119: DynamoDB table not encrypted with a customer-managed KMS key
  • CKV_AWS_161: RDS instance IAM database authentication disabled
  • CKV2_AWS_69: RDS instance not configured for encryption in transit (rds.force_ssl)
  • CKV_AWS_174: CloudFront viewer certificate below TLS 1.2
  • CKV_AWS_33: KMS key policy contains a wildcard principal

kics

  • Security Groups With Meta IP: Security group rule references the 169.254.169.254 metadata address
  • Lambda Functions Without Unique IAM Roles: Several Lambda functions share one execution role
  • ECS Task Definition Network Mode Not Recommended: Task definition uses a network mode other than awsvpc
  • VPC FlowLogs Disabled: VPC has no flow log resource

Azure and GCP

arm-ttk

  • Outputs-Must-Not-Contain-Secrets: Template outputs referencing secure parameters or list*() secrets
  • Secure-String-Parameters-Cannot-Have-Default: secureString/secureObject parameter with a non-empty default
  • adminPassword-Should-Not-Be-A-Literal: adminPassword set to a literal instead of a secure parameter
  • Parameters-Must-Be-Referenced: Declared parameter never referenced in the template
  • Location-Should-Not-Be-Hardcoded: Location literal instead of a location parameter

bicep-linter

  • outputs-should-not-contain-secrets: Bicep equivalent of Outputs-Must-Not-Contain-Secrets
  • secure-parameter-default: Secure parameter with a non-empty default value
  • no-hardcoded-location: Resource location not parameterized
  • no-unused-parameters: Declared parameter never used
  • protect-commandtoexecute-secrets: Script extension commandToExecute secrets outside protectedSettings

checkov

  • CKV_AZURE_9: NSG rule allows RDP (3389) from the internet
  • CKV_AZURE_10: NSG rule allows SSH (22) from the internet
  • CKV_AZURE_11: SQL server firewall rule spanning 0.0.0.0/0
  • CKV_AZURE_35: Storage account default network access rule not Deny
  • CKV_AZURE_131: secureString parameter with a hardcoded default (also KICS 4d2cf896)
  • CKV_GCP_60: Cloud SQL instance with a public IP (Terraform; policy-library GCPSQLPublicIpConstraintV1 is the asset-side version)
  • CKV_GCP_6: Cloud SQL instance not requiring SSL (Terraform; policy-library gcp_sql_ssl_v1 equivalent)
  • CKV_GCP_18: GKE control plane publicly reachable (Terraform)
  • CKV_GCP_40: Compute instance with an external IP (Terraform; policy-library gcp_compute_external_ip_address equivalent)
  • CKV_GCP_82: KMS CryptoKey without deletion protection (Terraform)
  • CKV_GCP_114: Storage bucket without public_access_prevention enforced (Terraform)

gcp-policy-library

  • GCPGKEMasterAuthorizedNetworksEnabledConstraintV1: GKE master authorized networks not enabled (gcp_gke_master_authorized_networks_enabled_v1)
  • GCPIAMRestrictServiceAccountKeyAgeConstraintV1: Service account keys older than a threshold (gcp_iam_restrict_service_account_key_age_v1)
  • GCPBigQueryDatasetWorldReadableConstraintV1: BigQuery dataset readable by allUsers/allAuthenticatedUsers (gcp_bigquery_dataset_world_readable_v1)
  • GCPNetworkEnableFlowLogsConstraintV1: VPC subnetwork without flow logs (gcp_network_enable_flow_logs_v1)

kics

  • Role Definitions Allow Custom Subscription Role Creation: ARM roleDefinition granting */Owner-equivalent at subscription scope (8fa9ceea-881f-4ef0-b0b8-728f589699a7)

psrule-azure

  • Azure.Storage.SecureTransfer: Storage account must set supportsHttpsTrafficOnly (encryption in transit); chant only checks at-rest encryption
  • Azure.Storage.MinTLS: Storage account minimumTlsVersion below 1.2
  • Azure.Storage.Firewall: Storage account network default action should be Deny
  • Azure.Storage.LocalAuth: Storage account should disable shared-key (local) authentication
  • Azure.KeyVault.Logs: Key Vault diagnostic audit logging not configured
  • Azure.KeyVault.RBAC: Key Vault should use RBAC authorization instead of access policies
  • Azure.SQL.AAD: SQL logical server without Entra ID administrator
  • Azure.SQL.MinTLS: SQL server minimalTlsVersion below 1.2
  • Azure.SQL.AllowAzureAccess: SQL firewall rule 0.0.0.0 allowing all Azure services
  • Azure.NSG.AnyInboundSource: NSG inbound allow rule with source Any/Internet
  • Azure.AKS.AuthorizedIPs: AKS API server not restricted to authorized IP ranges
  • Azure.AKS.LocalAccounts: AKS local accounts not disabled
  • Azure.AKS.ManagedIdentity: AKS cluster using service principal instead of managed identity
  • Azure.ACR.AnonymousAccess: Container registry allows anonymous pull
  • Azure.AppService.RemoteDebug: App Service remote debugging left enabled
  • Azure.VM.PublicKey: Linux VM with password auth instead of SSH keys
  • Azure.VM.ScriptExtensions: Custom Script Extension commandToExecute secrets not in protectedSettings
  • Azure.Deployment.OutputSecretValue: Deployment outputs a secure value (secret leak)
  • Azure.Deployment.SecureValue: Secret property set from a non-secure parameter/literal

Docker, nginx, secrets

checkov

  • CKV_DOCKER_2: Ensure HEALTHCHECK instructions have been added
  • CKV_DOCKER_5: Ensure update instructions are not used alone
  • CKV_DOCKER_8: Ensure the last USER is not root

detect-secrets

  • KeywordDetector: Secret-looking assignment by variable name (password=, api_key=)

dockle

  • CIS-DI-0006: Add HEALTHCHECK instruction to the container image
  • CIS-DI-0010: Do not store secrets in Dockerfiles (ENV/credential files in image)
  • CIS-DI-0008: Confirm safety of setuid/setgid files in the image
  • CIS-DI-0007: Do not use apt-get update alone in a single line
  • DKL-LI-0001: Avoid empty password (CVE-2019-5021 class)

gitleaks

  • jwt: JSON Web Token literal in source

gixy

  • ssrf: Server Side Request Forgery via proxy_pass with user-controlled host
  • http_splitting: HTTP response splitting via unescaped variables
  • host_spoofing: Request Host header forgery ($http_host vs $host)
  • origins: Weak Referer/Origin validation regex
  • add_header_redefinition: add_header in nested block drops parent headers
  • add_header_multiline: Multiline response headers
  • valid_referers: none in valid_referers

gixy-ng

  • hsts_header: Missing or weak Strict-Transport-Security header
  • allow_without_deny: allow directives without a trailing deny all
  • return_bypasses_allow_deny: return in a location bypasses allow/deny ACL
  • if_is_evil: if inside location context
  • resolver_external: External (public) DNS resolver configured
  • error_log_off: error_log off creates a file named off (adjacent to NGX007, which targets access_log)

hadolint

  • DL3002: Last USER should not be root (chant only checks for a missing USER)
  • DL3006: Always tag the version of an image explicitly (Dockerfile FROM)
  • DL3008: Pin versions in apt-get install
  • DL3018: Pin versions in apk add
  • DL3025: Use JSON notation for CMD and ENTRYPOINT
  • DL4006: Set SHELL -o pipefail before RUN with a pipe
  • DL3004: Do not use sudo (use gosu)
  • DL3064: Avoid sensitive data in ARG/ENV
  • DL4000: MAINTAINER is deprecated
  • DL3057: HEALTHCHECK instruction missing (off by default)

kics

  • privileged_containers_enabled: docker-compose: privileged: true
  • docker_socket_mounted_in_container: docker-compose: /var/run/docker.sock volume
  • shared_host_network_namespace: docker-compose: network_mode: host
  • volume_has_sensitive_host_directory: docker-compose: bind mount of sensitive host paths
  • no_new_privileges_not_set: docker-compose: security_opt no-new-privileges missing
  • container_capabilities_unrestricted: docker-compose: cap_drop ALL not set
  • healthcheck_not_set: docker-compose: service has no healthcheck

trufflehog

  • aws/session_keys: AWS temporary session credentials (ASIA + session token)

agents, Cedar, long tail

agent-audit

  • command-injection/shell-interpreter: MCP server command is a shell interpreter (bash/sh/python/node).
  • excessive-agency/high-privilege-concentration: One server aggregating shell, filesystem, database and network tools; needs tool listing, not config.
  • auth-bypass/ssl-disabled: TLS verification disabled in server source; nearest thing to AGT003 but checks server code, not the client URL scheme.

agent-scan

  • E001: Prompt injection / tool poisoning in MCP tool descriptions - requires connecting to the server; chant audits static config only.
  • E002: Cross-server tool reference (tool shadowing) across a client's configured servers.
  • W012: Skill fetches instructions from an external URL at runtime (unverifiable external dependency); adjacent to AGT004 but about runtime fetch, not pinning.
  • W021: Hidden Unicode characters in skills/tool descriptions.

cedar-validator

  • mixed-script / bidi warnings: Confusable-text warnings; chant only surfaces them through CEDE011, no dedicated rule.

cisco-mcp-scanner

  • HEUR-010: Overloaded tool scope (>5 verbs or any/all/everything) in tool descriptions; readiness analyzer runs against live or snapshotted servers.
  • Vulnerable Package Analyzer: CVE/PYSEC/GHSA lookup on MCP server dependencies.

cpln-cli

  • --dry-run: Since v3.16.0 create/update/patch/apply accept --dry-run: 'The platform validates the request and returns the resource that would be written'. Server-side; per-rule coverage of CPL020-CPL043 not documented.

flyctl

  • fly config validate --strict: Validates fly.toml against the platform, --strict flags unrecognized keys; chant's FLY rules target Machine configs, not fly.toml.

k3d

  • config JSON schema (v1alpha5): k3d validates the config file against its JSON schema at cluster create; nodeFilters are typed as free strings with examples only, so K3D101 is not covered.

kube-bench

  • k3s-cis-1.8 1.1.14: admin kubeconfig ownership root:root; runtime check on the node.

render-cli

  • render blueprints validate: 'Validates the structure of the specified render.yaml file'; available in CLI v2.7.0+, also exposed as a Validate Blueprint API endpoint.

temporal-workflowcheck

  • workflowcheck: Static non-determinism analysis of Go workflow code; no overlap with chant's namespace/schedule/ops rules.

🤖 Claude Code — https://claude.ai/code/session_015HFrNGLJa12qojpfwbDwyD

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:auditchant audit CLIprior-artPrior-art sweep findings

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions