> For the complete documentation index, see [llms.txt](https://docs.nullify.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.nullify.ai/capabilities/scpm/rules.md).

# Rules Reference

Every SCPM finding names the rule that raised it. This page lists each rule id, what it detects, and the section a finding's documentation link resolves to. Severity grading is described in the service's severity rubric. There is no per-tenant `off`/`warn`/`block` UI: a finding blocks a merge when its effective severity is CRITICAL or higher, and a confirmed threat — a package the malware index or a compromised-action index has verified — always blocks regardless of severity, whatever the CRITICAL floor says. A repository can lower or silence a finding for itself with `.nullify/scpm-ignore.yml`, downgrade-only, and a confirmed threat cannot be named in that file.

## Scope: what a pull request check reports

Every rule runs on every scan, and a branch scan persists everything each one finds. The **Scope** column decides only what a *pull request* check is allowed to report back on the pull request itself.

* **PR-scoped** — the finding sits on a line the file currently contains: a dependency entry, a `run:` step, a `FROM` directive. A pull request check can honestly intersect it with the lines the pull request added, so the author sees only what they introduced.
* **branch-only** — the finding's evidence is an *absence* or a whole-repository property: no lockfile beside the manifest, no updater configured, no permissions block, no attestation in the release workflow. There is no added line to anchor it to, so reporting it on a pull request would blame whoever opened it for a gap the branch already had. These appear in the repository's findings and in the branch scan, never as a pull request annotation.

Scope is not an enablement switch and not a severity. A branch-only rule is not a weaker rule; it is one whose finding belongs to the repository rather than to a change.

## CI platform: which CI systems a rule reads

The **CI platform** column names the CI systems whose configuration a rule reads. It is blank (`—`) for every rule that is not a CI/CD rule.

Coverage depends on the CI systems detected and eligible for the repository, not just where its source is hosted. **33 of the 52 CI/CD rules read GitHub Actions configuration only.** Azure Pipelines, GitLab CI and other systems have different applicable rule sets; a repository can use more than one system. Read the scan's coverage and this table before interpreting an empty result.

Two things follow:

* A `.github/workflows` directory **mirrored** onto a non-GitHub repository does not execute there, so SCPM does not run the GitHub rules over it. Nothing runs those workflows, so a finding on one would name a risk that cannot be taken.
* Every scan reports what could not apply. The coverage account lists CI/CD rules that do not apply to the detected systems, so an inapplicable rule is not mistaken for a passed check.

**2 of the 52 CI/CD rules apply on every CI system** — `scpm-cicd-unpinned-action` and `scpm-cicd-malicious-action` — because they grade a *reference* (an action, an orb, a plugin, a shared library) rather than a workflow document, so they read the same fact wherever it is declared. `scpm-cicd-self-hosted-runner` reads GitHub Actions and Bitbucket Pipelines, where the file declares a runner and can be written to clear the finding; it does not read Buildkite, which has no hosted tier at all, so a blanket finding on every Buildkite pipeline would name nothing the file could fix. `scpm-cicd-docker-socket` and `scpm-cicd-unpinned-images` each read GitHub Actions and GitLab CI.

## CI systems SCPM does not read

Seven CI systems are recognised but not graded. SCPM sees their configuration during the walk and reports it as a coverage gap rather than parsing it, so a pipeline defined in one of them is outside every CI/CD rule above:

| CI system          | Configuration the scan sees | Reported as          |
| ------------------ | --------------------------- | -------------------- |
| Drone              | `.drone.yml`                | `drone`              |
| AWS CodeBuild      | `buildspec.yml`             | `aws-codebuild`      |
| Google Cloud Build | `cloudbuild.yaml`           | `google-cloud-build` |
| AppVeyor           | `appveyor.yml`              | `appveyor`           |
| Codemagic          | `codemagic.yaml`            | `codemagic`          |
| Semaphore          | `.semaphore/semaphore.yml`  | `semaphore`          |
| Woodpecker         | `.woodpecker.yml`           | `woodpecker`         |

A scan that finds one of these names it on its coverage account, so a clean CI/CD result on a repository built by Drone or CodeBuild reads as "these pipelines were not inspected" rather than as "these pipelines are fine". CircleCI, Travis CI, Buildkite, Jenkins and Tekton are **not** in this list: SCPM parses all five, the reference rules above grade the orbs, plugins, shared libraries, bundles and images they pull in, and `scpm-cicd-ci-script-injection` grades what their shell steps interpolate.

## Overlap with SAST's GitHub Actions rules

`sast/tools/opengrep/rules/yaml/github-actions/` is a separate opengrep rule pack that also reads `.github/workflows`. It predates most of the CI/CD rules above and was not folded into them; six of its eight rules name the same construct one of these does, so a GitHub Actions workflow with, for example, a `pull_request_target` head checkout gets a finding from both SAST and SCPM. Neither rule set defers to the other today — this is recorded here rather than resolved, and no SAST rule is removed by it:

| SAST opengrep rule                            | Overlapping SCPM rule                                        |
| --------------------------------------------- | ------------------------------------------------------------ |
| `pull-request-target-code-checkout`           | `scpm-cicd-dangerous-trigger`                                |
| `workflow-run-target-code-checkout`           | `scpm-cicd-dangerous-trigger`, `scpm-cicd-workflow-run-risk` |
| `run-shell-injection`                         | `scpm-cicd-script-injection`                                 |
| `github-script-injection`                     | `scpm-cicd-github-script-injection`                          |
| `allowed-unsecure-commands`                   | `scpm-cicd-insecure-commands`                                |
| `third-party-action-not-pinned-to-commit-sha` | `scpm-cicd-unpinned-action`                                  |

`curl-eval` (an eval of curl'd data) and `unsafe-add-mask-workflow-command` (an `::add-mask::` a `::stop-commands::` payload can defeat) have no SCPM counterpart.

## License policy baseline

`scpm-license-restricted` (the repository's own declared license) and `scpm-license-dependency-restricted` (a dependency's registry-declared license) both evaluate against the org's license policy. A tenant with no accepted-licenses list configured is not "permit everything": the default baseline denies **strong (network) copyleft only**, matched by exact SPDX id — `AGPL-1.0`/`AGPL-3.0`, `GPL-2.0`/`GPL-3.0` (both the modern `-only`/`-or-later` ids and their pre-SPDX-3.0 bare spellings, which registry metadata still commonly reports) and `SSPL-1.0` — at MEDIUM severity. Weak and source-available licenses (LGPL, MPL, EPL, CDDL, Elastic, EUPL, ...) are **not** flagged by this default; matching is always exact, never by family substring, so an LGPL id is never caught by a GPL deny entry. An SPDX OR/AND expression is evaluated by its own structure — an OR is denied only when every branch is denied, an AND only when every atom is — so a dual license with an acceptable branch, or an AND with an acceptable choice nested inside an OR, is not denied just because one branch names a denied id.

A tenant that configures an accepted-licenses list switches `scpm-license-dependency-restricted` to full allowlist semantics: only the listed licenses pass, and everything else — including weak copyleft the default baseline lets through — is denied. `scpm-license-restricted` never consults that allowlist; it always evaluates the repository's own declared license against the constant copyleft baseline above, regardless of tenant configuration.

A dependency coordinate the license index could not resolve is counted and marked incomplete on the scan's own coverage, rather than reading as a license that was checked and passed.

`scpm-metadata-copyleft-license` is a separate, independently-configured rule: it reports the full copyleft spectrum (including weak copyleft, at LOW) on every scan, with no accepted-licenses concept, and is unaffected by the baseline above.

## Finding types SCPM does not raise

SCPM reads a repository's dependency **manifests** out of a git checkout, and asks the registries and the malware index about the coordinates it finds there. It never downloads a published package's own source. Three families of supply-chain signal therefore belong to other parts of the platform, and no SCPM rule will ever raise them:

* **Signals inside a published package's code** — obfuscated or minified code, encrypted payloads, hidden code, `eval` usage, embedded telemetry, native code, network, filesystem or environment-variable access, self-propagating code, high-entropy strings. These require fetching and analysing the package itself.
* **Signals that need a live feed** — a maintainer-account compromise, a CDN domain takeover. (A known-malware verdict is not one of these: `scpm-known-malware` holds every exactly-pinned dependency against the malware index. That index is a platform service, so the rule is live on a platform scan and reports itself *incomplete*, never clean, on a scan that has no index behind it — which is what a local `nullify scpm scan` has. The same is true of every `scpm-cooldown-*` rule: cooldown is evaluated against the tenant's policy, so a local scan raises none.)
* **Signals that need registry history** — whether a package's maintainer set changed between versions (`unstable_ownership`) or whether its publishing account is newly created (`new_author`). SCPM's registry lookups read one current document per package; neither is versioned and none carries an account-creation date.

What SCPM *can* see about a package's stewards it does raise: see `scpm-intelligence-steward` above.

| Rule id                                        | Name                                             | Scope       | CI platform                             | Detects                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------------------------------------- | ------------------------------------------------ | ----------- | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `scpm-cicd-ai-risk`                            | AI/ML Action with Secret Access                  | PR-scoped   | GitHub Actions                          | AI/ML action or integration processes untrusted input (PR content, issues, comments) with access to repository secrets, enabling prompt injection attacks                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `scpm-cicd-artifact-token-leak`                | CI/CD Artifact Token Leak Risk                   | PR-scoped   | GitHub Actions                          | Workflow uploads artifacts that may include git credentials from checkout, enabling token exfiltration (ArtiPACKED)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-cicd-azure-agent-security`               | Azure Self-Hosted Agent Security                 | PR-scoped   | Azure Pipelines                         | Pipeline uses self-hosted agent pool which may expose persistent credentials, build artifacts, and internal network access                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-cicd-azure-pipeline-access-ctrl`         | Azure Pipeline Access Control                    | PR-scoped   | Azure Pipelines                         | Pipeline has excessive job authorization scope or broad variable group access, violating least privilege                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `scpm-cicd-azure-pipeline-injection`           | Azure Pipeline YAML Injection                    | PR-scoped   | Azure Pipelines                         | User-controlled input is interpolated into pipeline YAML via macro syntax or template expressions, enabling command injection                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `scpm-cicd-azure-secrets-exposure`             | Azure Pipeline Secrets Exposure                  | PR-scoped   | Azure Pipelines                         | Secrets from variable groups or service connections may be exposed in pipeline scripts via echo, logging, or direct interpolation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `scpm-cicd-azure-service-connections`          | Azure Pipeline Service Connection Usage          | PR-scoped   | Azure Pipelines                         | Pipeline uses service connections that may have overly permissive access to external services (Azure, AWS, K8s, Docker registries)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `scpm-cicd-bitbucket-untrusted-privilege`      | Privileged Bitbucket Pull-Request Pipeline       | PR-scoped   | Bitbucket Pipelines                     | A pull-requests pipeline step claims a deployment environment or an OIDC identity token, giving code from a contributor's branch the credentials of a trusted build                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-cicd-bot-conditions`                     | Spoofable Bot Actor Check                        | PR-scoped   | GitHub Actions                          | Workflow condition uses github.actor to check for bot identity, which can be spoofed                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `scpm-cicd-cache-poisoning`                    | Cache Poisoning in Release Workflow              | PR-scoped   | GitHub Actions                          | Release or publish workflow uses cached artifacts which could be poisoned by a prior malicious build                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `scpm-cicd-ci-script-injection`                | CI Script Injection                              | PR-scoped   | Jenkins, CircleCI, Buildkite, Travis CI | Attacker-controlled pipeline variable is interpolated into a shell body, enabling arbitrary command execution                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `scpm-cicd-concurrency-limits`                 | Missing Concurrency Controls                     | branch-only | GitHub Actions                          | Workflow lacks concurrency limits, allowing unbounded parallel runs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-cicd-dangerous-trigger`                  | Dangerous CI/CD Trigger Configuration            | PR-scoped   | GitHub Actions                          | Workflow uses a trigger configuration that can execute untrusted code with elevated privileges                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `scpm-cicd-default-branch-push`                | Direct Push to Default Branch                    | PR-scoped   | GitHub Actions                          | Workflow pushes directly to the default branch, bypassing branch protection rules and code review                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `scpm-cicd-dispatch-toctou`                    | Dispatch TOCTOU Race Condition                   | PR-scoped   | GitHub Actions                          | workflow\_dispatch validates inputs in one step but uses them in a later step, enabling a time-of-check-time-of-use race condition                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `scpm-cicd-docker-socket`                      | Docker Socket Mounting                           | PR-scoped   | GitHub Actions, GitLab CI               | Workflow mounts the Docker daemon socket, giving containers full host Docker access enabling escape and lateral movement                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `scpm-cicd-environment-bypass`                 | Environment Protection Bypass                    | branch-only | GitHub Actions                          | Workflow can circumvent GitHub Environment protection rules via dynamic environment names or missing environment declarations on deployment jobs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-cicd-excessive-permissions`              | Excessive CI/CD Workflow Permissions             | PR-scoped   | GitHub Actions                          | Workflow or job uses overly permissive token permissions                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `scpm-cicd-github-env`                         | Dangerous GITHUB\_ENV/GITHUB\_PATH Write         | PR-scoped   | GitHub Actions                          | Workflow writes to GITHUB\_ENV or GITHUB\_PATH in a context triggerable by external contributors                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-cicd-github-script-injection`            | GitHub Script Injection                          | PR-scoped   | GitHub Actions                          | Untrusted input used in actions/github-script enables JavaScript injection with access to the GitHub API via octokit                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `scpm-cicd-gitlab-include-injection`           | GitLab CI Remote Include Injection               | PR-scoped   | GitLab CI                               | Pipeline includes remote configuration that could inject malicious jobs, scripts, or variable overrides                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `scpm-cicd-gitlab-runner-exposure`             | GitLab Self-Managed Runner Exposure              | PR-scoped   | GitLab CI                               | Self-managed runner is used in merge request pipelines, exposing internal infrastructure to untrusted code                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-cicd-gitlab-script-injection`            | GitLab CI Script Injection                       | PR-scoped   | GitLab CI                               | Attacker-controlled CI variable is used in a script block, enabling arbitrary command execution                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `scpm-cicd-gitlab-secrets-exposure`            | GitLab MR Secrets Exposure                       | PR-scoped   | GitLab CI                               | Merge request pipeline job accesses CI/CD variables or secrets, enabling exfiltration via malicious MRs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `scpm-cicd-gitlab-token-exposure`              | GitLab CI Token Exposure                         | PR-scoped   | GitLab CI                               | Pipeline token (CI\_JOB\_TOKEN or deploy token) is used in a context where it may be leaked to untrusted services or logs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `scpm-cicd-gitlab-unpinned-include`            | GitLab CI Unpinned Include                       | PR-scoped   | GitLab CI                               | Remote or project include does not pin to a specific ref/SHA, enabling supply chain attacks via upstream changes                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-cicd-gitlab-unsafe-checkout`             | GitLab MR Unsafe Checkout                        | PR-scoped   | GitLab CI                               | Merge request pipeline checks out and executes code from the attacker-controlled source branch with access to protected variables or runners                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `scpm-cicd-insecure-commands`                  | Insecure Workflow Commands Enabled               | PR-scoped   | GitHub Actions                          | Workflow re-enables deprecated unsafe commands that allow stdout-based environment injection                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `scpm-cicd-issue-comment-auth`                 | Issue Comment Without Author Validation          | PR-scoped   | GitHub Actions                          | Workflow triggered by comment, review, issue or discussion content executes commands without validating the author's association, allowing any user to trigger it                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `scpm-cicd-local-action-modification`          | Local Action Modification via PR                 | PR-scoped   | GitHub Actions                          | Workflow uses local composite actions from the checked-out repository with pull\_request\_target, allowing attackers to modify the action in their fork and execute arbitrary code with base repo permissions                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `scpm-cicd-malicious-action`                   | Known Compromised CI/CD Action                   | PR-scoped   | all CI systems                          | CI/CD action has been identified as compromised or malicious                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `scpm-cicd-missing-attestation`                | Missing Artifact Attestation in Release          | branch-only | GitHub Actions                          | Release workflow does not generate artifact attestations or SBOMs for provenance verification                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `scpm-cicd-missing-permissions`                | Missing Top-Level Permissions Block              | branch-only | GitHub Actions                          | Workflow does not declare explicit permissions, inheriting the repository's default (often read-write-all)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-cicd-obfuscation`                        | Obfuscated Workflow Pattern                      | PR-scoped   | GitHub Actions                          | Workflow contains obfuscated expressions or paths that hinder security auditing                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `scpm-cicd-oidc-overscope`                     | Shared OIDC Token Audience                       | PR-scoped   | GitHub Actions                          | Workflow sets the same OIDC audience on more than one login, so a token minted for one relying party can be replayed against the other                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `scpm-cicd-overprovisioned-secrets`            | Wholesale Secrets Exposure                       | PR-scoped   | GitHub Actions                          | Workflow exposes the entire secrets context via toJSON(secrets), leaking all secrets at once                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `scpm-cicd-privileged-checkout`                | Persisted Credentials in Checkout                | PR-scoped   | GitHub Actions                          | actions/checkout leaves GITHUB\_TOKEN in .git/config by default, accessible to all subsequent steps including third-party actions                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `scpm-cicd-ref-version-mismatch`               | Stale Version Comment on Pinned Action           | PR-scoped   | GitHub Actions                          | Hash-pinned action has a version comment that does not match the actual pinned commit SHA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `scpm-cicd-script-injection`                   | CI/CD Script Injection                           | PR-scoped   | GitHub Actions                          | Untrusted input is used directly in a run block, or in an action input the action executes as code, enabling arbitrary command execution                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `scpm-cicd-secrets-exposure`                   | CI/CD Secrets Exposure Risk                      | PR-scoped   | GitHub Actions                          | Secrets may be exposed in workflow logs through echo, print, or direct use in run blocks                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `scpm-cicd-secrets-inherit`                    | Blanket Secret Forwarding                        | PR-scoped   | GitHub Actions                          | Reusable workflow call uses 'secrets: inherit' which forwards all secrets including those not needed                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `scpm-cicd-self-hosted-runner`                 | Self-Hosted Runner Exposure                      | PR-scoped   | GitHub Actions, Bitbucket Pipelines     | Workflow uses self-hosted runners which lack ephemeral isolation and may expose persistent credentials or internal network access                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `scpm-cicd-step-output-injection`              | Step Output Injection in Run Block               | PR-scoped   | GitHub Actions                          | Step or job output is interpolated directly into a run block via ${{ steps.*.outputs.* }} or ${{ needs.*.outputs.* }}, which can enable command injection if the output contains untrusted data (filenames, PR metadata)                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `scpm-cicd-unpinned-action`                    | Unpinned CI/CD Action Reference                  | PR-scoped   | all CI systems                          | CI/CD action or template is referenced by a mutable tag or branch instead of a commit SHA                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `scpm-cicd-unpinned-images`                    | Unpinned Container Image                         | PR-scoped   | GitHub Actions, GitLab CI               | Container image is not pinned to a SHA256 digest, allowing supply chain attacks via tag manipulation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `scpm-cicd-unprotected-deployment`             | Missing Environment Protection on Deployment     | branch-only | GitHub Actions                          | Deployment workflow does not use GitHub environment protection rules, allowing unreviewed deployments                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `scpm-cicd-unredacted-secrets`                 | Unredacted Secret Access                         | PR-scoped   | GitHub Actions                          | Secret parsed as structured data bypasses GitHub's automatic log redaction                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-cicd-unsound-condition`                  | Unsound Workflow Condition                       | PR-scoped   | GitHub Actions                          | Workflow condition uses YAML block scalar syntax which silently makes conditions always true                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `scpm-cicd-unsound-contains`                   | Unsafe contains() Usage                          | PR-scoped   | GitHub Actions                          | Workflow condition uses contains() for string matching, which does substring matching and may allow bypass                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-cicd-unverified-action`                  | Third-Party Action in Privileged Workflow        | PR-scoped   | GitHub Actions                          | Workflow with elevated permissions uses a third-party action from an unverified publisher                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `scpm-cicd-use-trusted-publishing`             | Missing OIDC Trusted Publishing                  | branch-only | GitHub Actions                          | Package publishing workflow uses long-lived credentials instead of OIDC trusted publishing                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-cicd-workflow-run-risk`                  | Workflow Run Privilege Escalation                | PR-scoped   | GitHub Actions                          | workflow\_run triggered workflow downloads and uses artifacts from untrusted triggering run, enabling privilege escalation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-confusion-dependency`                    | Dependency Confusion                             | PR-scoped   | —                                       | Package name suggests internal package but comes from public registry                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `scpm-cooldown-absolute-pin-stale`             | Absolute Cooldown Cutoff Is Stale                | branch-only | —                                       | A native cooldown pins an absolute cutoff date so old that it freezes dependencies instead of delaying them                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `scpm-cooldown-dependabot-below-threshold`     | Dependabot Cooldown Below Threshold              | branch-only | —                                       | A Dependabot block's cooldown is shorter than the configured window                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-cooldown-dependabot-disabled`            | Dependabot Updates Disabled                      | branch-only | —                                       | A Dependabot block sets open-pull-requests-limit to 0, so it can never open update PRs and any cooldown is inert                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-cooldown-dependabot-missing`             | Dependabot Cooldown Missing                      | branch-only | —                                       | A Dependabot package-ecosystem block sets no cooldown                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `scpm-cooldown-dependabot-partial`             | Dependabot Cooldown Partial Coverage             | branch-only | —                                       | A Dependabot block cools only some bump types or an allowlisted subset, leaving the rest uncovered                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `scpm-cooldown-ecosystem-uncovered`            | Ecosystem Missing Cooldown Coverage              | branch-only | —                                       | The organization mandates a cooldown for an ecosystem the repository ships dependencies in, but no updater or native config covers it                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `scpm-cooldown-native-below-threshold`         | Native Package-Manager Cooldown Below Threshold  | branch-only | —                                       | A native package-manager cooldown is shorter than the configured cooldown window                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-cooldown-native-disabled`                | Native Package-Manager Cooldown Disabled         | branch-only | —                                       | A native package-manager cooldown is explicitly set to zero, disabling install-time protection                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `scpm-cooldown-native-partial`                 | Native Package-Manager Cooldown Partial Coverage | branch-only | —                                       | A native package-manager cooldown exempts named packages, leaving them uncovered                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-cooldown-no-updater`                     | No Dependency-Updater Cooldown Configured        | branch-only | —                                       | The organization mandates a cooldown but the repository ships no Renovate or Dependabot cooldown configuration                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `scpm-cooldown-pm-unsupported`                 | Package Manager Predates Cooldown Support        | branch-only | —                                       | The repository pins a package manager version that cannot enforce the configured dependency cooldown                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `scpm-cooldown-recent-publish`                 | Recently-Published Dependency                    | PR-scoped   | —                                       | Dependency version was published within the configured cooldown window                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `scpm-cooldown-recent-publish-transitive`      | Recently-Published Transitive Dependency         | PR-scoped   | —                                       | Lockfile-resolved transitive dependency version was published within the configured cooldown window                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-cooldown-renovate-below-threshold`       | Renovate Cooldown Below Threshold                | branch-only | —                                       | Renovate minimumReleaseAge is shorter than the configured cooldown window                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `scpm-cooldown-renovate-disabled`              | Renovate Cooldown Disabled                       | branch-only | —                                       | Renovate neutralises its release-age cooldown (enabled:false, internalChecksFilter:none, or a blanket-neutralising packageRule)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `scpm-cooldown-renovate-missing`               | Renovate Cooldown Missing                        | branch-only | —                                       | Renovate is configured but no minimumReleaseAge cooldown is set                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `scpm-cooldown-renovate-partial`               | Renovate Cooldown Partial Coverage               | branch-only | —                                       | Renovate sets a cooldown only for some packages (packageRules), leaving the rest uncovered                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-cooldown-renovate-partial-exemption`     | Renovate Cooldown Package Exemptions             | branch-only | —                                       | Renovate exempts named packages from the cooldown (ignoreDeps or a neutralised packageRule), leaving them uncovered                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-cooldown-renovate-unparseable`           | Renovate Config Unparseable                      | branch-only | —                                       | The package.json embedded renovate config could not be decoded, so its cooldown cannot be verified                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `scpm-cooldown-renovate-unverifiable`          | Renovate Cooldown Unverifiable                   | branch-only | —                                       | Renovate cooldown is inherited from shared presets or an unparseable value and cannot be verified                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `scpm-cooldown-unverifiable-ecosystem`         | Cooldown Unverifiable For Ecosystem              | branch-only | —                                       | The repository uses dependencies from an ecosystem with no registry intelligence source, so the cooldown window and the registry-backed rules cannot be verified                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-cooldown-updater-automation`             | Unsafe Dependency-Updater Automation             | branch-only | —                                       | Dependency updater merges, or executes code, without the human review every cooldown and typosquat finding depends on                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `scpm-cooldown-updater-config-unparseable`     | Updater Config Unparseable                       | branch-only | —                                       | The organization mandates a cooldown but the repository's updater configuration could not be parsed, so it enforces nothing                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `scpm-docker-compose-unpinned`                 | Unpinned Docker Compose Image                    | PR-scoped   | —                                       | Docker Compose service uses an image without a version tag or digest, defaulting to :latest which is mutable                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `scpm-docker-insecure-registry`                | Insecure Docker Registry                         | PR-scoped   | —                                       | Docker image references a private or insecure registry that may use HTTP or lack authentication                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `scpm-docker-unpinned-base`                    | Unpinned Docker Base Image                       | PR-scoped   | —                                       | Dockerfile uses a base image without a digest pin, making builds non-reproducible and vulnerable to tag mutation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-git-submodule-integrity`                 | Git Submodule Integrity                          | PR-scoped   | —                                       | .gitmodules fetches a submodule over plaintext or runs a command on every update, so the checkout is decided off-repository                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `scpm-gitops-source-ref`                       | Unpinned GitOps Source                           | PR-scoped   | —                                       | Argo CD or Flux points the cluster at a repository on a mutable revision, or over plaintext HTTP, so what the cluster runs is decided at sync time rather than in the repository                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-helm-chart-dependency`                   | Unpinned Helm Chart Dependency                   | PR-scoped   | —                                       | Helm chart declares a subchart on a mutable version constraint or fetches it from a plaintext HTTP repository, so the chart installed into the cluster is decided at build time                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `scpm-intelligence-ai-hallucination`           | AI Hallucination Hijack                          | PR-scoped   | —                                       | Dependency matches a low-popularity hallucinated package name                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `scpm-intelligence-analysis`                   | Supply Chain Intelligence                        | PR-scoped   | —                                       | Detects supply chain intelligence signals such as dependency hijacking via git-fork versions and replace directives                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-intelligence-phantom-package`            | Phantom Package                                  | PR-scoped   | —                                       | Direct dependency is absent from its public registry                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `scpm-intelligence-phantom-package-transitive` | Phantom Transitive Package                       | PR-scoped   | —                                       | Lockfile-resolved transitive dependency is absent from its public registry                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-intelligence-rapid-publish`              | Rapid Publish Pattern                            | PR-scoped   | —                                       | Multiple package versions were published in a short window                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-intelligence-steward`                    | Package Steward                                  | PR-scoped   | —                                       | The registry or source host reports that nobody, or no verifiable party, stands behind a dependency: an archived, stale or missing source repository, no listed maintainer, or a single maintainer account behind the whole package                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-known-malware`                           | Known Malicious Package                          | PR-scoped   | —                                       | A dependency at an exact version the malware index has confirmed malicious; direct and transitive, blocked by the platform default policy whatever the enforcement floor                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `scpm-kubernetes-unpinned-image`               | Unpinned Kubernetes Image                        | PR-scoped   | —                                       | Kubernetes workload or Helm values reference a container image by mutable tag rather than digest, so the artifact that runs is decided at deploy time                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `scpm-kustomize-remote-base`                   | Unpinned Kustomize Remote Base                   | PR-scoped   | —                                       | Kustomization pulls a remote base or chart on a mutable ref, or over plaintext HTTP, so the manifests applied to the cluster are decided at build time                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `scpm-license-dependency-mismatch`             | Dependency License Mismatch                      | PR-scoped   | —                                       | Dependency metadata declares multiple licenses                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `scpm-license-dependency-restricted`           | Dependency License Restricted                    | PR-scoped   | —                                       | Dependency license is denied by org policy                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `scpm-license-dependency-unlicensed`           | Unlicensed Dependency                            | PR-scoped   | —                                       | Dependency metadata declares no license                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `scpm-license-local-mismatch`                  | License Mismatch                                 | branch-only | —                                       | Manifest license contradicts the shipped license file                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `scpm-license-missing`                         | Missing License                                  | branch-only | —                                       | Project manifest declares no license                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `scpm-license-restricted`                      | Restricted License                               | PR-scoped   | —                                       | Project license is denied by org policy                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `scpm-lockfile-missing`                        | Missing Lock File                                | branch-only | —                                       | Lock file missing for manifest, allowing non-deterministic dependency resolution                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-lockfile-out-of-sync`                    | Manifest And Lockfile Out Of Sync                | branch-only | —                                       | A required direct npm dependency has no resolution in the sibling npm-shrinkwrap.json or package-lock.json (v1/v2/v3); a non-npm packageManager declaration or competing lockfile without an explicit npm declaration excludes the check                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `scpm-lockfile-patched-dependency`             | Dependency Patched At Install Time               | PR-scoped   | —                                       | A dependency is rewritten by a patch the repository ships (pnpm `patchedDependencies`, the yarn `patch:` protocol), so the code that runs is not the code the lockfile's integrity hash verifies                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `scpm-lockfile-removed`                        | Lock File Removed                                | PR-scoped   | —                                       | Pull request deletes a lock file whose manifest survives, returning every declared range to whatever the registry serves at install time                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `scpm-lockfile-version-drift`                  | Locked Version Outside Declared Range            | PR-scoped   | —                                       | A committed lock file resolves a dependency to a version the manifest's declared range excludes, so the manifest no longer describes what installs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `scpm-metadata-analysis`                       | Package Metadata Analysis                        | PR-scoped   | —                                       | Detects suspicious package metadata such as unmaintained, deprecated, or trivial packages                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `scpm-metadata-copyleft-license`               | Copyleft License Detection                       | PR-scoped   | —                                       | Detects copyleft licenses (GPL, AGPL, LGPL, SSPL, EUPL) that may impose viral licensing obligations                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-metadata-deprecated-upstream`            | Deprecated Upstream                              | PR-scoped   | —                                       | Package version is marked deprecated by its registry                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `scpm-package-manager-integrity`               | Package Manager Integrity Setting Disabled       | PR-scoped   | —                                       | A package-manager setting re-enables install scripts or switches off the Go checksum database or module proxy, an environment variable turns off image signature or certificate revocation checking, or a build-time fetcher outside the package managers (a Terraform module source or provider, a Terraform CLI provider override, a pre-commit hook revision or its additional\_dependencies) resolves without an immutable pin, removing an integrity control the toolchain ships on                                                                                                                                                                       |
| `scpm-registry-source-trust`                   | Untrusted Package Source                         | PR-scoped   | —                                       | Dependencies resolve from a host, under a registry configuration, or from a package repository the build file declares for itself (a plaintext Gradle or Maven repository, an `allowInsecureProtocol` opt-out, `mavenLocal` ahead of Maven Central, a composer.json `repositories` entry off Packagist) that cannot be trusted to serve the packages the manifest names; also a committed default-registry redirect (`.npmrc registry=`, `pip.conf index-url`, `.yarnrc.yml npmRegistryServer`, a `Gemfile source`) and NuGet sources configured with no `packageSourceMapping`, and a lockfile entry verified against a broken hash algorithm (`sha1`, `md5`) |
| `scpm-scan-manifest-unreadable`                | Manifest Could Not Be Read                       | PR-scoped   | —                                       | A dependency manifest could not be parsed or exceeded the scan size cap, so its dependencies were graded by no rule                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-scripts-cargo-config-exec`               | Cargo Build Executes a Configured Program        | PR-scoped   | —                                       | A committed .cargo/config.toml names a program Cargo runs during the build (rustc-wrapper, target runner/linker, a shell alias, or a rustflags linker override)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `scpm-scripts-install`                         | Install Scripts Detected                         | PR-scoped   | —                                       | Package has install scripts that execute during installation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `scpm-scripts-remote-add`                      | Unverified Remote ADD                            | PR-scoped   | —                                       | Dockerfile ADD fetches a remote URL without a --checksum, so the artifact is not integrity-verified                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-scripts-shell-install`                   | Unpinned Install In Build Script                 | PR-scoped   | —                                       | Build script fetches or installs dependencies without pinning, a common supply-chain injection vector                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `scpm-scripts-unmanaged-dependencies`          | Dependencies Installed Outside A Package Manager | branch-only | —                                       | Build scripts install dependencies that no manifest or lockfile records, so no dependency scanner inventories or analyses them                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `scpm-suppression-file-changed`                | SCPM Exception File                              | PR-scoped   | —                                       | The repository carries a `.nullify/scpm-ignore.yml` that lowers or silences supply-chain rules, so a verdict was moved by a repository file rather than by the organisation                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `scpm-typosquat`                               | Typosquat                                        | PR-scoped   | —                                       | Package name closely resembles a significantly more popular package, suggesting typosquatting                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `scpm-unpinned-floating-version`               | Floating Version Specifier                       | PR-scoped   | —                                       | Dependency uses a floating version specifier that may resolve to different versions                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `scpm-unpinned-git-dependency`                 | Git/HTTP Dependency                              | PR-scoped   | —                                       | Dependency is sourced from a git URL, an HTTP URL or any other arbitrary `https://` URL instead of a package registry, bypassing registry security controls                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |

### Lockfile coverage limits

The missing-lockfile rule skips C# projects with no declared package items, project references, imports, sibling packages.config or ancestor Directory.Build.props, Directory.Build.targets or Directory.Packages.props. Dependency evidence filenames are matched without case sensitivity. This is a check of declared dependencies: SDK-implied framework packages such as NETStandard.Library and Microsoft.NETCore.App alone do not require a finding.

The npm consistency rule checks required direct resolutions, not exact range text or obsolete root metadata. Optional and local dependencies are excluded. Manifests without required direct dependencies skip lock inspection. Malformed manifests and unreadable, unsupported or empty required lock indexes mark this rule incomplete, preventing absence of a detection from retiring an existing finding. Version mismatches remain the separate HIGH version-drift rule; missing resolutions are MEDIUM.
