For the complete documentation index, see llms.txt. This page is also available as Markdown.

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.

Last updated