Skip to content

pinned_references

Require executable references in supported CI and container files to identify immutable artifacts rather than mutable tags or branches.

With format: auto (the default), the repository-relative filename selects GitHub Actions workflows and action.yml, pre-commit, CircleCI, GitLab CI, Cloud Build, or Dockerfile semantics. Set format: explicitly for a nonstandard filename. The rule checks GitHub steps[*].uses, reusable-workflow jobs.*.uses, composite-action steps, job/service images, pre-commit rev, CircleCI orbs and images, GitLab images and services, Cloud Build step images, Dockerfile FROM, and HTTP(S) ADD.

GitHub and pre-commit references must end in a full 40- or 64-hex Git object id. Container references must carry @sha256: plus 64 lowercase hexadecimal characters; a readable tag may remain before the digest. CircleCI registry orbs accept an exact major.minor.patch version because published orb versions are immutable. Local GitHub ./… actions, pre-commit local/meta repositories, FROM scratch, and local Dockerfile ADD sources are exempt. Remote ADD requires --checksum=sha256:<64-hex>.

YAML aliases and merge keys are resolved with explicit-key precedence, while findings retain navigable source ranges. Unknown auto-detected paths and malformed/non-UTF-8 inputs fail as analysis failures instead of passing silently. Variable references fire because the checked file does not prove an immutable value. Check-only and offline: resolving a tag to a SHA/digest is a network-gated suggestion, not a deterministic edit.

OptionTypeRequiredDefaultDescription
formatone of auto | github_actions | pre_commit | circleci | gitlab_ci | cloud_build | dockerfileautoParser and semantic selector set. auto infers it from the path.

Plus the common paths, level, id, when, scope_filter, and expect_matches fields. This table is generated from the JSON Schema; option types and defaults are authoritative.

Mutable CI and container references are reported

Section titled "Mutable CI and container references are reported"

The rule fires on this repository:

  • .circleci/
  • .circleci/config.yml

    ✗ error immutable-build-inputs

    3:9 CircleCI orb is not pinned to an exact immutable version

  • .github/
  • .github/workflows/
  • .github/workflows/ci.yml

    ✗ error immutable-build-inputs

    3:11 GitHub Actions reference is not pinned to a full commit SHA

  • .gitlab-ci.yml

    ✗ error immutable-build-inputs

    2:10 container image is not pinned to a full sha256 digest

  • .pre-commit-config.yaml

    ✗ error immutable-build-inputs

    3:10 pre-commit repository is not pinned to a full commit SHA

    ✗ error immutable-build-inputs

    4:11 external pre-commit repository has no pinned `rev`

  • Dockerfile

    ✗ error immutable-build-inputs

    1:1 Dockerfile base image is not pinned to a full sha256 digest

    ✗ error immutable-build-inputs

    2:1 remote Dockerfile ADD source has no full sha256 checksum

  • actions/
  • actions/demo/
  • actions/demo/action.yml

    ✗ error immutable-build-inputs

    4:13 GitHub Actions reference is not pinned to a full commit SHA

  • cloudbuild.yaml

    ✗ error immutable-build-inputs

    2:11 container image is not pinned to a full sha256 digest

.circleci/config.yml
version: 2.1
orbs:
node: circleci/node@volatile
.github/workflows/ci.yml
jobs:
call:
uses: owner/repo/.github/workflows/test.yml@main
.gitlab-ci.yml
test:
image: alpine:latest
script: echo test
.pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
- repo: https://example.test/missing-rev
Dockerfile
FROM rust:1.90
ADD https://example.test/tool /usr/local/bin/tool
actions/demo/action.yml
runs:
using: composite
steps:
- uses: actions/checkout@v4
cloudbuild.yaml
steps:
- name: gcr.io/cloud-builders/docker:latest

With this .alint.yml:

version: 1
rules:
- id: immutable-build-inputs
kind: pinned_references
paths:
- .github/workflows/*.yml
- "**/action.yml"
- .pre-commit-config.yaml
- .circleci/config.yml
- .gitlab-ci.yml
- cloudbuild.yaml
- Dockerfile
level: error

alint check reports:

Terminal window
--- .circleci/config.yml -------------------------------------------------------
x error immutable-build-inputs
3:9 CircleCI orb is not pinned to an exact immutable version
--- .github/workflows/ci.yml ---------------------------------------------------
x error immutable-build-inputs
3:11 GitHub Actions reference is not pinned to a full commit SHA
--- .gitlab-ci.yml -------------------------------------------------------------
x error immutable-build-inputs
2:10 container image is not pinned to a full sha256 digest
--- .pre-commit-config.yaml ----------------------------------------------------
x error immutable-build-inputs
3:10 pre-commit repository is not pinned to a full commit SHA
x error immutable-build-inputs
4:11 external pre-commit repository has no pinned `rev`
--- Dockerfile -----------------------------------------------------------------
x error immutable-build-inputs
1:1 Dockerfile base image is not pinned to a full sha256 digest
x error immutable-build-inputs
2:1 remote Dockerfile ADD source has no full sha256 checksum
--- actions/demo/action.yml ----------------------------------------------------
x error immutable-build-inputs
4:13 GitHub Actions reference is not pinned to a full commit SHA
--- cloudbuild.yaml ------------------------------------------------------------
x error immutable-build-inputs
2:11 container image is not pinned to a full sha256 digest
Summary (9 violations):
x 9 errors
0 passing * 1 failing

Full commits digests exact orbs and local references pass

Section titled "Full commits digests exact orbs and local references pass"

This repository is compliant:

  • .circleci/
  • .circleci/config.yml✓
  • .github/
  • .github/workflows/
  • .github/workflows/ci.yml✓
  • .gitlab-ci.yml✓
  • .pre-commit-config.yaml✓
  • Dockerfile✓
  • actions/
  • actions/demo/
  • actions/demo/action.yml✓
.circleci/config.yml
version: 2.1
orbs:
node: circleci/node@5.2.0
jobs:
test:
docker:
- image: cimg/base:current@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
.github/workflows/ci.yml
jobs:
call:
uses: owner/repo/.github/workflows/test.yml@0123456789abcdef0123456789abcdef01234567
build:
container: ubuntu:24.04@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
steps:
- uses: ./actions/local
.gitlab-ci.yml
test:
image: alpine:latest@sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
script: echo test
.pre-commit-config.yaml
repos:
- repo: local
- repo: meta
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: 0123456789abcdef0123456789abcdef01234567
Dockerfile
FROM scratch
ADD local-tool /usr/local/bin/tool
ADD --checksum=sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef https://example.test/tool /usr/local/bin/remote-tool
actions/demo/action.yml
runs:
using: composite
steps:
- uses: actions/checkout@0123456789abcdef0123456789abcdef01234567

With this .alint.yml:

version: 1
rules:
- id: immutable-standard-inputs
kind: pinned_references
paths:
- .github/workflows/*.yml
- "**/action.yml"
- .pre-commit-config.yaml
- .circleci/config.yml
- .gitlab-ci.yml
- Dockerfile
level: error

alint check reports:

Terminal window
v All 1 rule(s) passed.