Skip to content

Guardrails / jenkins

Shared libraries are loaded at a fixed revision ​

jenkins/shared-library-pinned@v1

Every @Library annotation and library step names a tag or a commit SHA instead of a branch, so the library code a build runs can't change underneath it.

Idjenkins/shared-library-pinned
Versionv1
Categoryjenkins
Default severityerror
Interpreterpython3
Timeout30 seconds
Violations tolerated0
Collectsjenkins

Collectors ​

This guardrail doesn't gather anything itself. It relies on the collectors below, which the CLI runs once per build before any check, and reads what they found from GUARDRAIL_FACTS. If a collector collects nothing, this guardrail is skipped, not failed.

CollectorGathersInputs it is given
jenkinsThe Jenkinsfiles the repository carries, read in Jenkins's own vocabulary: whether each is a declarative pipeline or a scripted one, the agent it asks for, the stages in the order they are declared with the steps inside them, the timeouts its options blocks declare, the shared libraries it loads and how tightly each is pinned, and the credential ids it reaches for. A Jenkinsfile is Groovy rather than a declaration, so it is read by pattern and scanned says so. Names and ids only, never a credential, an environment value or a parameter value.jenkinsfiles

The inputs above are this guardrail's own inputs, passed straight through to the collector. Setting one in buildnote.json changes what is collected, and two guardrails configured the same way share a single collection.

Configuration ​

json
{
  "guardrails": {
      "failOn": "error",
      "checks": [
          {
              "use": "jenkins/shared-library-pinned@v1",
              "severity": "error",
              "with": {
                  "jenkinsfiles": "Jenkinsfile,Jenkinsfile.*,*.Jenkinsfile",
                  "allow": ""
              },
              "exemptions": []
          }
      ]
  }
}

Inputs ​

InputDescriptionDefaultEnvironment variable
jenkinsfilesComma separated globs naming the Jenkinsfiles to read.Jenkinsfile,Jenkinsfile.*,*.JenkinsfileGUARDRAIL_INPUT_JENKINSFILES
allowComma separated shared library names exempt from pinning, for libraries your own organisation publishes. Globs such as company-* are supported.``GUARDRAIL_INPUT_ALLOW

How to fix ​

Name a specific version, and make it one that doesn't move:

groovy
@Library('company-pipeline@1.4.2') _

A library loaded from a branch is code that anyone who can push to that branch can run inside your build, with every credential the job has in scope. Two builds of the same commit can also run different library code. A reference with no version at all is worse: it uses the default version configured on the controller, which is usually a branch and lives outside this repository, so you can't tell from the Jenkinsfile what ran.

Jenkins can't tell a tag from a branch by name, so this guardrail checks the shape of the ref: a 40 character commit SHA, or a version such as 1.4.2 or v1.4.2. Protect the tags you pin to, because git also lets a tag move.

Scripted pipelines are read too, but only by pattern. A library loaded through ordinary Groovy isn't detected, so a finding there is real but finding nothing is not proof. A scripted file doesn't suppress findings in its sibling files, and the check skips only when every Jenkinsfile is scripted and none of them names a library that could be read.

More in jenkins ​

  • jenkins/job-timeout-set. Every declarative pipeline declares how long it may run, either on the pipeline itself or on every stage, so a hung build is stopped instead of holding an executor.

All 2 jenkins guardrails

Buildnote Limited
Registered in England and Wales, Reg: 16140412