Skip to content

Open source CLI to check compliance of your GitLab CI/CD pipelines and repos

License

Notifications You must be signed in to change notification settings

getplumber/plumber

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

126 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Plumber

CI/CD compliance scanner for GitLab pipelines

Build Status Latest Release Go Version GitHub Downloads Docker Pulls License

Website β€’ Discord β€’ Issues


πŸ€” What is Plumber?

Plumber is a compliance scanner for GitLab. It reads your .gitlab-ci.yml and repository settings, then checks for security and compliance issues like:

  • Container images using mutable tags (latest, dev)
  • Container images from untrusted registries
  • Unprotected branches
  • Hardcoded jobs not from includes/components
  • Outdated includes/templates
  • Forbidden version patterns (e.g., main, HEAD)
  • Missing required components or templates

How does it work? Plumber connects to your GitLab instance via API, analyzes your pipeline configuration, and reports any issues it finds. You define what's allowed in a config file (.plumber.yaml), and Plumber tells you if your project complies.

Plumber Demo

πŸ’‘ Want to see it in action? Check out our example projects:

πŸš€ Two Ways to Use Plumber

Choose one of these methods. You don't need both:

Method Best for How it works
CLI Quick evaluation, local testing, one-off scans Install binary and run from terminal
GitLab CI Component Automated checks on every pipeline run Add 2 lines to your .gitlab-ci.yml

πŸ“– Table of Contents


Option 1: CLI

Try Plumber in 2 minutes! No commits, no CI changes, just run it.

Step 1: Install

Choose one of the following:

Homebrew

brew tap getplumber/plumber
brew install plumber

Mise

mise use -g github:getplumber/plumber

Requires mise activation in your shell, or run with mise exec -- plumber.

Direct Download

# For Linux/MacOs
curl -LO "https://github.com/getplumber/plumber/releases/latest/download/plumber-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/')"
chmod +x plumber-* && sudo mv plumber-* /usr/local/bin/plumber

πŸ“¦ See Installation for Windows, Docker, or building from source.

Step 2: Generate a Config File

plumber config generate

This creates .plumber.yaml with default compliance rules. You can customize it later.

Step 3: Create & Set Your Token

  1. In GitLab, go to User Settings β†’ Access Tokens (direct link)
  2. Create a Personal Access Token with read_api + read_repository scopes
  3. Export it in your terminal:

⚠️ Important: The token must belong to a user with Maintainer role (or higher) on the project to access branch protection settings and other project configurations.

export GITLAB_TOKEN=glpat-xxxx

Step 4: Run Analysis

Plumber auto-detects the GitLab URL and project from your git remote but requires the remote to be set to 'origin'.

# if in git remote with remote = origin, run:
plumber analyze

# Or specify the project explicitly:
plumber analyze --gitlab-url https://gitlab.com --project mygroup/myproject

It reads your .plumber.yaml config and outputs a compliance report. You can also tell it to store the output in JSON format with the --output flag.

πŸ’‘ Like what you see? Add Plumber to your CI/CD with the GitLab CI Component for automated checks on every pipeline.


Option 2: GitLab CI Component

Add Plumber to your GitLab pipeline: it will run automatically on the default branch, tags and open merge requests.

πŸ’¬ These instructions are for gitlab.com. Self-hosted? See Self-Hosted GitLab.

Step 1: Create a GitLab Token

  1. In GitLab, go to User Settings β†’ Access Tokens (or create one here)
  2. Create a Personal Access Token with read_api + read_repository scopes
  3. Go to your project's Settings β†’ CI/CD β†’ Variables
  4. Add the token as GITLAB_TOKEN (masked recommended)

⚠️ Important: The token must belong to a user with Maintainer role (or higher) on the project to access branch protection settings and other project configurations.

Step 2: Add to Your Pipeline

Add this to your .gitlab-ci.yml:

include:
  - component: gitlab.com/getplumber/plumber/plumber@v0.1.21
  • Get the latest version from the Catalog

Step 3: Run Your Pipeline

That's it! Plumber will now run on every pipeline and report compliance issues.

πŸ’‘ Want to customize? See Configuration to set thresholds, enable/disable controls, and whitelist trusted images.


βš™οΈ Configuration

GitLab CI Component Inputs

Override any input to fit your needs:

include:
  - component: gitlab.com/getplumber/plumber/plumber@v0.1.21
    inputs:
      threshold: 80                           # Minimum % to pass (default: 100)
      config_file: configs/my-plumber.yaml    # Custom config path
      server_url: https://gitlab.example.com  # Self-hosted GitLab
      branch: develop                         # Specific branch to analyze
      verbose: true                           # Debug output

πŸ“¦ Find the latest version on the GitLab CI/CD Catalog

All available inputs
Input Default Description
server_url $CI_SERVER_URL GitLab instance URL
project_path $CI_PROJECT_PATH Project to analyze
branch $CI_COMMIT_REF_NAME Branch to analyze
gitlab_token $GITLAB_TOKEN GitLab API token (requires read_api + read_repository)
threshold 100 Minimum compliance % to pass
config_file (auto-detect) Path to config file (relative to repo root)
output_file plumber-report.json Path to write JSON results
print_output true Print text output to stdout
stage .pre Pipeline stage for the job
image getplumber/plumber:0.1 Docker image to use
allow_failure false Allow job to fail without blocking
verbose false Enable debug output

Configuration File

Generate a default configuration file with:

plumber config generate

Flags:
  -f, --force           Overwrite existing file
  -o, --output string   Output file path (default ".plumber.yaml")

This creates .plumber.yaml with sensible defaults. Customize it to fit your needs.

Available Controls

Plumber includes 8 compliance controls. Each can be enabled/disabled and customized in .plumber.yaml:

1. Container images must not use forbidden tags

Detects container images using mutable tags that can change unexpectedly.

containerImageMustNotUseForbiddenTags:
  enabled: true
  tags:
    - latest
    - dev
    - development
    - staging
    - main
    - master
2. Container images must come from authorized sources

Ensures container images come from trusted registries only.

containerImageMustComeFromAuthorizedSources:
  enabled: true
  trustDockerHubOfficialImages: true
  trustedUrls:
    - docker.io/docker:*
    - gcr.io/kaniko-project/*
    - $CI_REGISTRY_IMAGE:*
    - $CI_REGISTRY_IMAGE/*
    - getplumber/plumber:*
    - docker.io/getplumber/plumber:*
    - registry.gitlab.com/security-products/*
3. Branch must be protected

Verifies that critical branches have proper protection settings.

branchMustBeProtected:
  enabled: true
  defaultMustBeProtected: true
  namePatterns:
    - main
    - master
    - release/*
    - production
    - dev
  allowForcePush: false
  codeOwnerApprovalRequired: false
  minMergeAccessLevel: 30   # Developer
  minPushAccessLevel: 40    # Maintainer
4. Pipeline must not include hardcoded jobs

Detects jobs defined directly in .gitlab-ci.yml instead of coming from includes/components.

pipelineMustNotIncludeHardcodedJobs:
  enabled: true
5. Includes must be up to date

Checks if included templates/components have newer versions available.

includesMustBeUpToDate:
  enabled: true
6. Includes must not use forbidden versions

Prevents use of mutable version references for includes that can change unexpectedly.

includesMustNotUseForbiddenVersions:
  enabled: true
  forbiddenVersions:
    - latest
    - "~latest"
    - main
    - master
    - HEAD
  defaultBranchIsForbiddenVersion: false
7. Pipeline must include component

Ensures required GitLab CI/CD components are included in the pipeline.

There are two ways to define requirements (use one, not both):

Expression syntax β€” a natural boolean expression using AND, OR, and parentheses:

pipelineMustIncludeComponent:
  enabled: true
  # AND binds tighter than OR, so "a AND b OR c" means "(a AND b) OR c"
  required: components/sast/sast AND components/secret-detection/secret-detection

  # With alternatives:
  # required: (components/sast/sast AND components/secret-detection/secret-detection) OR your-org/full-security/full-security

Array syntax β€” a list of groups using "OR of ANDs" logic:

pipelineMustIncludeComponent:
  enabled: true
  # Outer array = OR (at least one group must be satisfied)
  # Inner array = AND (all components in group must be present)
  requiredGroups:
    - ["components/sast/sast", "components/secret-detection/secret-detection"]
    - ["your-org/full-security/full-security"]
8. Pipeline must include template

Ensures required templates (project includes) are present in the pipeline.

There are two ways to define requirements (use one, not both):

Expression syntax β€” a natural boolean expression using AND, OR, and parentheses:

pipelineMustIncludeTemplate:
  enabled: true
  required: templates/go/go AND templates/trivy/trivy AND templates/iso27001/iso27001

  # With alternatives:
  # required: (templates/go/go AND templates/trivy/trivy) OR templates/full-go-pipeline

Array syntax β€” a list of groups using "OR of ANDs" logic:

pipelineMustIncludeTemplate:
  enabled: true
  requiredGroups:
    - ["templates/go/go", "templates/trivy/trivy", "templates/iso27001/iso27001"]
    - ["templates/full-go-pipeline"]

Outputs

By default, Plumber prints a colorized detail and a summary of a project's compliance

  • You can disable the printing via the config flags

You can also configure Plumber to output a json file with the results.

  • This is enabled by default if using Plumber Component in Gitlab

Example Output

Plumber provides colorized terminal output for easy scanning:

Plumber Output Example

  • Green checkmarks (βœ“) indicate passing controls
  • Red crosses (βœ—) indicate failing controls
  • Yellow bullets (β€’) highlight specific issues found
  • Summary tables show compliance percentages at a glance

πŸ“¦ Installation

Homebrew

brew tap getplumber/plumber
brew install plumber

To install a specific version:

brew install getplumber/plumber/plumber@0.1.26

Note: Versioned formulas are keg-only. Use the full path for example /usr/local/opt/plumber@0.1.26/bin/plumber or run brew link plumber@0.1.26 to add it to your PATH.

Mise

mise use -g github:getplumber/plumber

Requires mise activation in your shell, or run with mise exec -- plumber.

Binary Download

Linux (amd64)
curl -LO https://github.com/getplumber/plumber/releases/latest/download/plumber-linux-amd64
chmod +x plumber-linux-amd64
sudo mv plumber-linux-amd64 /usr/local/bin/plumber
Linux (arm64)
curl -LO https://github.com/getplumber/plumber/releases/latest/download/plumber-linux-arm64
chmod +x plumber-linux-arm64
sudo mv plumber-linux-arm64 /usr/local/bin/plumber
macOS (Apple Silicon)
curl -LO https://github.com/getplumber/plumber/releases/latest/download/plumber-darwin-arm64
chmod +x plumber-darwin-arm64
sudo mv plumber-darwin-arm64 /usr/local/bin/plumber
macOS (Intel)
curl -LO https://github.com/getplumber/plumber/releases/latest/download/plumber-darwin-amd64
chmod +x plumber-darwin-amd64
sudo mv plumber-darwin-amd64 /usr/local/bin/plumber
Windows (PowerShell)
Invoke-WebRequest -Uri https://github.com/getplumber/plumber/releases/latest/download/plumber-windows-amd64.exe -OutFile plumber.exe
Verify checksum
curl -LO https://github.com/getplumber/plumber/releases/latest/download/checksums.txt
sha256sum -c checksums.txt --ignore-missing

Docker

docker pull getplumber/plumber:latest

docker run --rm \
  -e GITLAB_TOKEN=glpat-xxxx \
  getplumber/plumber:latest analyze \
  --gitlab-url https://your-gitlab-instance.com \ 
  --project mygroup/myproject

Build from Source

Requires Go 1.24+ and Make.

git clone https://github.com/getplumber/plumber.git
cd plumber
make build # or make install to build and copy to /usr/local/bin/

πŸ” CLI Reference

plumber analyze

Run compliance analysis on a GitLab project.

plumber analyze [flags]

Flags

Flag Required Default Description
--gitlab-url No* auto-detect GitLab instance URL
--project No* auto-detect Project path (e.g., group/project)
--config No .plumber.yaml Path to config file
--threshold No 100 Minimum compliance % to pass (0-100)
--branch No default Branch to analyze
--output No β€” Write JSON results to file
--print No true Print text output to stdout

* Auto-detected from git remote (origin) if not specified. Supports both SSH and HTTPS remote URLs.

Environment Variables

Variable Required Description
GITLAB_TOKEN Yes GitLab API token with read_api + read_repository scopes (from a Maintainer or higher)

Exit Codes

Code Meaning
0 Compliance β‰₯ threshold
1 Compliance < threshold or error

plumber config generate

Generate a default .plumber.yaml configuration file.

plumber config generate [flags]
Flag Default Description
--output, -o .plumber.yaml Output file path
--force, -f false Overwrite existing file

Examples:

# Generate default config
plumber config generate

# Custom filename
plumber config generate --output my-plumber.yaml

# Overwrite existing conf file
plumber config generate --force

plumber config view

Display a clean, human-readable view of the effective configuration without comments.

plumber config view [flags]
Flag Default Description
--config, -c .plumber.yaml Path to configuration file
--no-color false Disable colorized output

Booleans are colorized for quick scanning: true in green, false in red. Color is automatically disabled when piping output.

Examples:

# View the default .plumber.yaml
plumber config view

# View a specific config file
plumber config view --config custom-plumber.yaml

# View without colors (for piping or scripts)
plumber config view --no-color

⚠️ Self-Hosted GitLab

If you're running a self-hosted GitLab instance, you'll need to host your own copy of the component.

Step-by-step setup

Step 1: Import the repository

  • Go to New Project β†’ Import project β†’ Repository by URL
  • URL: https://gitlab.com/getplumber/plumber.git
  • Choose a group/project name (e.g., infrastructure/plumber)

Step 2: Enable CI/CD Catalog

  • Go to Settings β†’ General
  • Make sure the project has a description (required for CI/CD Catalog)
  • Expand Visibility, project features, permissions
  • Toggle CI/CD Catalog resource to enabled
  • Click Save changes

Step 3: Create a release

  • Go to Code β†’ Tags β†’ New tag
  • Enter a version (e.g., 1.0.0)
  • Click Create tag

Step 4: Create a GitLab Token

In the project you want to scan:

  1. Go to User Settings β†’ Access Tokens on your GitLab instance
  2. Create a Personal Access Token with read_api + read_repository scopes
  3. Go to the project's Settings β†’ CI/CD β†’ Variables
  4. Add the token as GITLAB_TOKEN (masked recommended)

⚠️ The token must belong to a user with Maintainer role (or higher) on the project.

Step 5: Use in your pipelines

include:
  - component: gitlab.example.com/infrastructure/plumber/plumber@v1.0.0

πŸ’‘ Format: <your-gitlab-host>/<project-path>/plumber@<tag>


πŸ”§ Troubleshooting

Issue Solution
GITLAB_TOKEN environment variable is required Set GITLAB_TOKEN in CI/CD Variables or export it locally
401 Unauthorized Token needs read_api + read_repository scopes, from a Maintainer or higher
403 Forbidden on MR settings Expected on non-Premium GitLab; continues without that data
404 Not Found Verify project path and GitLab URL are correct
Configuration file not found Use absolute path in Docker, relative path otherwise

πŸ’‘ Need help? Open an issue or join our Discord


🀝 Contributing

Contributions are welcome! Please read our Contributing Guide for details on how to submit pull requests, report issues, and coding conventions.

πŸ“„ License

Mozilla Public License 2.0 (MPL-2.0)

About

Open source CLI to check compliance of your GitLab CI/CD pipelines and repos

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 5

Languages