Is your feature request related to a problem? Please describe.
The Controls documentation page currently lists all compliance controls with their "Problem" and "Impact" columns, but does not explain how to fix each issue when a control fails. When Plumber reports a non-compliant control, users must figure out on their own how to remediate it — searching GitLab docs, Stack Overflow, or guessing at .plumber.yaml configuration.
This creates friction for adoption (especially for teams new to CI/CD security) and increases time-to-remediation.
Inspiration: Popeye K8s error codes page
The Kubernetes linter Popeye maintains a comprehensive error codes reference that maps every error code to a structured description and severity level. This is a great pattern for tools that detect issues and need to guide users toward fixes.
However, Popeye only lists codes and messages — it does NOT provide remediation guidance. Plumber's documentation can go further and be a differentiator.
Describe the solution you'd like
Expand the existing controls.mdx page (or create a dedicated sub-page) to include, for each control:
- Control name — the YAML identifier as used in
.plumber.yaml (e.g., containerImageMustNotUseForbiddenTags)
- What it checks — clear description
- Why it matters — security/compliance impact (already exists)
- Non-compliant example ❌ — concrete
.gitlab-ci.yml or GitLab settings that trigger the control
- Compliant example ✅ — the corrected version
- How to fix — step-by-step remediation instructions
.plumber.yaml configuration — how to configure/tune the control
Example for one control
### containerImageMustNotUseForbiddenTags
**What it checks:** Verifies that container images in CI/CD pipelines
do not use mutable tags like `latest`, `dev`, or `stable`.
**Why it matters:** Mutable tags can resolve to different image versions
over time, introducing supply chain risks and breaking reproducibility.
**Non-compliant example** ❌
build:
image: node:latest
script:
- npm ci && npm run build
**Compliant example** ✅
build:
image: node:22.5.1
script:
- npm ci && npm run build
**How to fix:**
1. Identify the exact version of the image you need
2. Replace the mutable tag with a specific version tag (e.g., `node:22.5.1`)
3. For maximum security, pin by digest: `node@sha256:abc123...`
**Configuration (`.plumber.yaml`):**
controls:
containerImageMustNotUseForbiddenTags:
enabled: true
tags: [latest, dev, stable]
containerImagesMustBePinnedByDigest: false
Controls to document (CLI — 9 controls)
| Control ID |
Category |
containerImageMustNotUseForbiddenTags |
Container Images |
containerImageMustComeFromAuthorizedSources |
Container Images |
branchMustBeProtected |
Access & Authorization |
pipelineMustNotIncludeHardcodedJobs |
Pipeline Composition |
includesMustBeUpToDate |
Pipeline Composition |
includesMustNotUseForbiddenVersions |
Pipeline Composition |
pipelineMustIncludeComponent |
Pipeline Composition |
pipelineMustIncludeTemplate |
Pipeline Composition |
pipelineMustNotEnableDebugTrace |
CI/CD Variables |
Platform controls (MR approvals, member quotas, security policy) should also be documented with the same format.
Implementation details
- File:
src/docs/data/docs/en/use-plumber/controls.mdx (expand existing) or new controls-reference.mdx
- MDX components available:
Aside, Badge, Steps, Tabs/TabsContent (useful for bad/good config toggles)
- Frontmatter:
section: "main", appropriate sidebar.order
- Each control's YAML identifier should match
.plumber.yaml for cross-reference
Describe alternatives you've considered
- Keep as-is: Users rely on trial-and-error or GitLab docs to fix issues
- Separate page per control: More granular but may fragment the doc too much for 9 controls
- Only add config examples: Half-measure; users still wouldn't know what to change in their CI
Additional context
- The current
controls.mdx page has the right structure but needs enrichment — this is additive, not a rewrite
- When SARIF output lands (plumber#91), each rule's
helpUri should link to the relevant section of this page
- This follows the proven pattern from Popeye's codes.md, but goes further by adding actionable remediation (which Popeye doesn't have)
Is your feature request related to a problem? Please describe.
The Controls documentation page currently lists all compliance controls with their "Problem" and "Impact" columns, but does not explain how to fix each issue when a control fails. When Plumber reports a non-compliant control, users must figure out on their own how to remediate it — searching GitLab docs, Stack Overflow, or guessing at
.plumber.yamlconfiguration.This creates friction for adoption (especially for teams new to CI/CD security) and increases time-to-remediation.
Inspiration: Popeye K8s error codes page
The Kubernetes linter Popeye maintains a comprehensive error codes reference that maps every error code to a structured description and severity level. This is a great pattern for tools that detect issues and need to guide users toward fixes.
However, Popeye only lists codes and messages — it does NOT provide remediation guidance. Plumber's documentation can go further and be a differentiator.
Describe the solution you'd like
Expand the existing
controls.mdxpage (or create a dedicated sub-page) to include, for each control:.plumber.yaml(e.g.,containerImageMustNotUseForbiddenTags).gitlab-ci.ymlor GitLab settings that trigger the control.plumber.yamlconfiguration — how to configure/tune the controlExample for one control
Controls to document (CLI — 9 controls)
containerImageMustNotUseForbiddenTagscontainerImageMustComeFromAuthorizedSourcesbranchMustBeProtectedpipelineMustNotIncludeHardcodedJobsincludesMustBeUpToDateincludesMustNotUseForbiddenVersionspipelineMustIncludeComponentpipelineMustIncludeTemplatepipelineMustNotEnableDebugTracePlatform controls (MR approvals, member quotas, security policy) should also be documented with the same format.
Implementation details
src/docs/data/docs/en/use-plumber/controls.mdx(expand existing) or newcontrols-reference.mdxAside,Badge,Steps,Tabs/TabsContent(useful for bad/good config toggles)section: "main", appropriatesidebar.order.plumber.yamlfor cross-referenceDescribe alternatives you've considered
Additional context
controls.mdxpage has the right structure but needs enrichment — this is additive, not a rewritehelpUrishould link to the relevant section of this page