dpndncY

dpndncY Pipeline Trust Firewall

The Pipeline Trust Firewall extends dependency admission control to CI/CD actions. It evaluates uses: references before merge or deploy, records every decision, detects mutable-ref drift over time, and can emit signed pipeline evidence that downstream systems verify offline.

#Product Surface

  • Repository, archive, and local path scans now automatically attach a pipelineSecurity block to the saved scan result. The Pipeline result tab reads this same stored evidence from scan history.
  • POST /api/pipeline/actions/evaluate evaluates one uses: value.
  • POST /api/pipeline/actions/evaluate-batch evaluates up to 100 action references.
  • POST /api/pipeline/actions/evaluate-workflow scans submitted GitHub Actions YAML content and evaluates all discovered uses: references.
  • POST /api/pipeline/actions/scan-path scans .github/workflows/*.yml|yaml under a validated local project path.
  • GET /api/pipeline/admission/events returns the immutable admission log used for drift detection.
  • GET /api/pipeline/actions/compromised exposes the bundled compromised-action intelligence feed.
  • GET /api/pipeline/posture/platforms lists supported CI/CD posture scanners.
  • POST /api/pipeline/posture/evaluate-workflow scans one pipeline config for software-factory trust-boundary risk. The provider field can be auto, github-actions, gitlab-ci, jenkins, bitbucket-pipelines, circleci, azure-pipelines, buildkite, drone, or tekton.
  • POST /api/pipeline/posture/evaluate-file is an alias for direct single-file posture scans.
  • POST /api/pipeline/posture/scan-path discovers and scans supported pipeline files under a local repository path.
  • POST /api/pipeline/install-risk/package-json analyzes npm package lifecycle scripts as install-time code execution.
  • POST /api/pipeline/install-risk/file analyzes one supported ecosystem file by path/name.
  • POST /api/pipeline/install-risk/diff-package-json detects new or changed install-time lifecycle scripts between package versions.
  • POST /api/pipeline/install-risk/scan-path scans supported install/build-risk files under a local repository path.
  • POST /api/pipeline/attestations/build builds a DSSE-compatible pipeline attestation from evaluation results.
  • POST /api/pipeline/attestations/verify verifies a signed attestation with a public key.

#Default Decision Model

The evaluator returns the same admission shape as the dependency firewall: allow, warn, review, or block.

Default mode is observe, so a policy-level block is surfaced as review while preserving policyDecision: "block". Switch to policy.mode: "enforce" when teams are ready to fail builds or block merge.

High-value checks include:

  • Bundled compromised-action database: tj-actions/changed-files@*, reviewdog/action-setup@v1.
  • Mutable references: branch refs, major tags, ambiguous refs, short SHAs, semver tags.
  • Docker actions without sha256 digest pinning.
  • Local actions that execute repository-controlled code.
  • GitHub resolution to commit SHA.
  • Repository missing, archived, disabled, renamed, or transferred.
  • Repository identity drift and owner identity drift compared with the prior admission event.
  • Previously admitted mutable ref now resolving to a different commit SHA.
  • Recent repository or owner creation.
  • Low public adoption for untrusted owners.

Every response includes decisionTrace, signals, resolvedSha, previousResolvedSha, and the effective policy summary so a reviewer can see why the gate made its decision.

#Workflow Posture Rules

The posture scanner models a pipeline as:

trigger -> job -> permissions -> runner -> checkout -> cache -> install -> artifact -> publish/deploy

During normal scans, dpndncY builds a combined pipeline verdict:

  • fail: critical trust-boundary risk or a GitHub Action admission block. This also marks the saved scan policy verdict as failed.
  • review: high-severity pipeline or install-time execution risk.
  • warn: medium-severity pipeline hygiene findings.
  • pass: pipeline/install evidence was found and no current rule triggered.

The stored pipelineSecurity object contains:

  • summary: file counts, finding counts, platform counts, GitHub Action counts, and admission blocks.
  • posture: multi-platform CI/CD configuration findings.
  • installRisk: package/build file install-time execution findings.
  • actionFirewall: GitHub Actions uses: admission decisions evaluated in observe mode without network resolution.
  • recommendations: the next operational actions for AppSec or platform teams.
  • findings: a merged evidence table used by the frontend Pipeline tab.

Supported CI/CD platforms:

  • GitHub Actions: .github/workflows/*.yml|yaml
  • GitLab CI: .gitlab-ci.yml|yaml
  • Jenkins: Jenkinsfile, Jenkinsfile.*
  • Bitbucket Pipelines: bitbucket-pipelines.yml|yaml
  • CircleCI: .circleci/config.yml|yaml
  • Azure Pipelines: azure-pipelines.yml|yaml, .azure-pipelines/*.yml|yaml
  • Buildkite: .buildkite/*.yml|yaml
  • Drone CI: .drone.yml|yaml
  • Tekton: tekton/**/*.yml|yaml, .tekton/**/*.yml|yaml

GitHub Actions rule coverage:

  • GHA-PRT-001: pull_request_target checks out untrusted pull request code.
  • GHA-PRT-002: pull_request_target runs dependency install steps.
  • GHA-PERM-001: workflow-level permissions: write-all.
  • GHA-PERM-002: missing explicit workflow/job permissions.
  • GHA-PERM-003: job-level permissions: write-all.
  • GHA-OIDC-001: id-token: write outside a tightly isolated publish/deploy job, or on untrusted triggers.
  • GHA-TOKEN-001: pull request-controlled jobs with write-capable GITHUB_TOKEN scopes.
  • GHA-INSTALL-001: dependency install steps running with secrets, OIDC, or write token exposure.
  • GHA-RUNNER-001: self-hosted runners exposed to pull request execution.
  • GHA-CACHE-001: cache use in a risky trust-boundary context.
  • GHA-ARTIFACT-001: privileged release/workflow_run job consuming downloaded artifacts.
  • GHA-ACTION-001: third-party GitHub Action not pinned to a full commit SHA.
  • GHA-RELEASE-001: release job consuming upstream job outputs without explicit provenance checks.

Multi-platform posture coverage:

  • *-INSTALL-001: dependency install steps running with secrets, OIDC, CI tokens, or credential-bearing contexts.
  • *-PR-001: pull-request or merge-request execution path can reach release, publish, or deploy behavior.
  • *-REMOTE-001: pipeline downloads remote content and executes it through a shell.
  • *-CRED-002: pipeline references cloud metadata endpoints, OIDC internals, runner memory, or /proc credential paths.
  • *-CACHE-001: cache use in PR/MR or release contexts where state can cross trust boundaries.
  • *-ARTIFACT-001: release paths move artifacts without explicit producer trust/provenance checks.
  • *-RUNTIME-001: privileged containers, Docker-in-Docker, Docker socket mounts, or privileged Tekton steps.
  • *-IMAGE-001: mutable or unpinned CI container images.
  • GITLAB-INCLUDE-001..002: remote or unpinned GitLab CI includes.
  • GITLAB-OIDC-001: GitLab id_tokens outside isolated protected release jobs.
  • JENKINS-AGENT-001: change-request pipelines can run on broad Jenkins agents.
  • JENKINS-CRED-001: Jenkins withCredentials is available to install/release shell steps.
  • JENKINS-LIB-001: Jenkins shared library is not pinned.
  • BITBUCKET-OIDC-001: Bitbucket OIDC is enabled outside an isolated deployment step.
  • BITBUCKET-DEPLOY-001: Bitbucket pull-request pipeline includes deployment behavior.
  • CIRCLECI-ORB-001: CircleCI orb version is broad or mutable.
  • CIRCLECI-CONTEXT-001: CircleCI context secrets may be exposed to install or PR-controlled jobs.
  • AZURE-TOKEN-001: Azure checkout persists credentials in a PR pipeline.
  • AZURE-VARGROUP-001: Azure variable group is available during dependency installation.
  • AZURE-RESOURCE-001: Azure external repository resource is not pinned.
  • BUILDKITE-PLUGIN-001: Buildkite plugin is not pinned.
  • BUILDKITE-AGENT-001: Buildkite pull-request pipeline selects customer-managed agents.
  • DRONE-SECRET-001: Drone secret is available to PR or install-time commands.
  • TEKTON-SA-001: Tekton task uses a service account during install or release behavior.
  • TEKTON-PARAM-001: Tekton script interpolates runtime parameters.

#Install-Risk Rules

Supported files:

  • npm: package.json
  • Composer: composer.json
  • Python: requirements*.txt, pyproject.toml, setup.py
  • Maven: pom.xml
  • Gradle: build.gradle, build.gradle.kts
  • Cargo/Rust: Cargo.toml, build.rs
  • Ruby: Gemfile, *.gemspec

package.json lifecycle scripts and equivalent ecosystem build/install hooks are treated as install-time code execution:

  • PKG-INSTALL-001: package defines install-time lifecycle script.
  • PKG-INSTALL-002: lifecycle script downloads or pipes remote content into a shell.
  • PKG-INSTALL-003: lifecycle script references secrets or credential stores.
  • PKG-INSTALL-004: lifecycle script contains obfuscation or dynamic execution.
  • PKG-INSTALL-005: lifecycle script probes cloud metadata or process-memory paths.
  • PKG-INSTALL-010: new or changed lifecycle script introduced between versions.
  • COMPOSER-INSTALL-001: Composer lifecycle script executes during install/update.
  • PY-INSTALL-001: Python install uses custom package index or find-links.
  • PY-INSTALL-002: Python dependency resolves from direct URL, VCS, editable, or local source.
  • PY-INSTALL-010: Python package uses custom PEP 517 build backend.
  • PY-INSTALL-020: setup.py can execute code during build/install.
  • MAVEN-BUILD-001..005: Maven build plugins, plaintext repositories, or dynamic versions.
  • GRADLE-BUILD-001..003: Gradle process execution, remote scripts, or plaintext repositories.
  • CARGO-BUILD-001..010: Cargo build scripts or alternate sources.
  • RUBY-INSTALL-001..002: Ruby VCS/path gems or gemspec native extension hooks.
  • GEN-INSTALL-002..005: cross-ecosystem shell download, secret access, obfuscation, metadata or process path probes.

#Example

POST /api/pipeline/actions/evaluate
{
  "uses": "tj-actions/changed-files@v45",
  "source": ".github/workflows/ci.yml",
  "record": true,
  "policy": { "mode": "observe" }
}

The first response records an event. Later evaluations of the same action ref compare the current GitHub resolution against that event and flag drift.

#Attestation Signing

Set one of these before building signed attestations:

$env:DPNDNCY_ATTESTATION_PRIVATE_KEY_PATH="C:\keys\dpndncy-attestation-private.pem"
$env:DPNDNCY_ATTESTATION_PUBLIC_KEY_PATH="C:\keys\dpndncy-attestation-public.pem"

The signer intentionally uses a separate attestation key, not the licensing key. Verification is offline:

node bin/dpndncy-verify.js attestation.json --public-key C:\keys\dpndncy-attestation-public.pem

The envelope uses payload type application/vnd.dpndncy.pipeline-attestation.v1+json and signs a DSSE PAE payload with RS256.

#Next Layers

The route and module boundaries are ready for:

  • GitLab, Jenkins, CircleCI, Azure Pipelines, Bitbucket, Tekton, Buildkite, and Drone scanners.
  • OpenSSF Advisory DB updater for action intelligence.
  • GitHub PR check integration that comments with decisionTrace.
  • Enforced branch protection using policyShouldFail.
  • Self-hosted runner runtime telemetry that attaches network/process evidence to the same attestation predicate.