Documentation
¶
Overview ¶
configuration/merge.go
Index ¶
- Constants
- Variables
- func FindClosestMatch(unknownKey string, validKeys []string) string
- func IsBenched(provider, controlName string) bool
- func IsControlApplicableTo(controlName, provider string) bool
- func ParseRequiredExpression(expr string) ([][]string, error)
- func ProviderNeedsActionMetadata(provider string) bool
- func ValidControlNames() []string
- func ValidFlatKeys() map[string]struct{}
- func ValidateKnownKeys(data []byte) []string
- type ActionAuthorizedSourcesControlConfig
- type ActionsPinnedByShaControlConfig
- type AuthConfig
- type BranchProtectionControlConfig
- type CacheActionSpec
- type CachePoisoningControlConfig
- type Configuration
- type ControlMeta
- type ControlsConfig
- type DebugTraceControlConfig
- type DockerInDockerControlConfig
- type EnabledOnlyControlConfig
- type HardcodedJobsControlConfig
- type ImageAuthorizedSourcesControlConfig
- type ImageForbiddenTagsControlConfig
- type IncludesForbiddenVersionsControlConfig
- type IncludesUpToDateControlConfig
- type JobVariablesOverrideControlConfig
- type MRApprovalRulesMinApprovalsControlConfig
- type MRApprovalSettingsControlConfig
- type MRSettingsControlConfig
- type PlumberConfig
- func (c *PlumberConfig) ControlsFor(provider string) *ControlsConfig
- func (c *PlumberConfig) GetBranchMustBeProtectedConfig() *BranchProtectionControlConfig
- func (c *PlumberConfig) GetCicdVariablesMustBeMaskedConfig() *EnabledOnlyControlConfig
- func (c *PlumberConfig) GetCicdVariablesMustBeProtectedConfig() *EnabledOnlyControlConfig
- func (c *PlumberConfig) GetContainerImageMustComeFromAuthorizedSourcesConfig() *ImageAuthorizedSourcesControlConfig
- func (c *PlumberConfig) GetContainerImageMustNotUseForbiddenTagsConfig() *ImageForbiddenTagsControlConfig
- func (c *PlumberConfig) GetIncludesMustBeUpToDateConfig() *IncludesUpToDateControlConfig
- func (c *PlumberConfig) GetIncludesMustNotUseForbiddenVersionsConfig() *IncludesForbiddenVersionsControlConfig
- func (c *PlumberConfig) GetMergeRequestApprovalRulesMustCoverAllProtectedBranchesConfig() *EnabledOnlyControlConfig
- func (c *PlumberConfig) GetMergeRequestApprovalRulesMustRequireMinimumApprovalsConfig() *MRApprovalRulesMinApprovalsControlConfig
- func (c *PlumberConfig) GetMergeRequestApprovalSettingsMustBeCompliantConfig() *MRApprovalSettingsControlConfig
- func (c *PlumberConfig) GetMergeRequestSettingsMustBeCompliantConfig() *MRSettingsControlConfig
- func (c *PlumberConfig) GetPipelineMustIncludeComponentConfig() *RequiredComponentsControlConfig
- func (c *PlumberConfig) GetPipelineMustIncludeTemplateConfig() *RequiredTemplatesControlConfig
- func (c *PlumberConfig) GetPipelineMustNotEnableDebugTraceConfig() *DebugTraceControlConfig
- func (c *PlumberConfig) GetPipelineMustNotExecuteUnverifiedScriptsConfig() *UnverifiedScriptsControlConfig
- func (c *PlumberConfig) GetPipelineMustNotIncludeHardcodedJobsConfig() *HardcodedJobsControlConfig
- func (c *PlumberConfig) GetPipelineMustNotOverrideJobVariablesConfig() *JobVariablesOverrideControlConfig
- func (c *PlumberConfig) GetPipelineMustNotUseDockerInDockerConfig() *DockerInDockerControlConfig
- func (c *PlumberConfig) GetPipelineMustNotUseUnsafeVariableExpansionConfig() *VariableInjectionControlConfig
- func (c *PlumberConfig) GetProjectMustHaveSecurityPolicySourceConfig() *SecurityPolicyControlConfig
- func (c *PlumberConfig) GetSecurityJobsMustNotBeWeakenedConfig() *SecurityJobsWeakenedControlConfig
- func (c *PlumberConfig) ProviderConfig(name string) *ProviderConfig
- func (c *PlumberConfig) Validate() error
- type ProviderConfig
- type RequiredActionsControlConfig
- type RequiredComponentsControlConfig
- type RequiredTemplatesControlConfig
- type SecurityJobsSubControlToggle
- type SecurityJobsWeakenedControlConfig
- type SecurityPolicyControlConfig
- type UnverifiedScriptsControlConfig
- type VariableInjectionControlConfig
Constants ¶
const ( ProviderGitLab = "gitlab" ProviderGitHub = "github" )
providerGitLab and providerGitHub are exported as constants so call sites can reference them by name instead of stringly-typed literals.
const DefaultScoreEndpoint = "https://score.getplumber.io"
DefaultScoreEndpoint is the built-in hosted Plumber Score badge service. A self-hosted score service is selected with the --score-endpoint flag / PLUMBER_ANALYZE_SCORE_ENDPOINT env (surfaced by the CI integration input), not from the config file; the OIDC audience the CLI mints then follows that value.
const ExtendsPlumberDefault = "plumber:default"
ExtendsPlumberDefault is the only value accepted by the top-level `extends:` key in v1. It selects overlay mode against the embedded baseline shipped in the binary.
Variables ¶
var ErrConfigNotFound = errors.New("config file not found")
ErrConfigNotFound is returned (wrapped) by LoadPlumberConfig when the config file does not exist. Callers that fall back to the embedded default on a missing file test for it with errors.Is, rather than substring-matching the error text, so a reworded message can never silently break the fallback.
Functions ¶
func FindClosestMatch ¶ added in v0.1.61
FindClosestMatch finds the closest matching valid key using Levenshtein distance. Returns an empty string if no reasonable match is found.
func IsBenched ¶ added in v0.3.0
IsBenched reports whether the given (provider, control) pair is currently on the dev-side bench. Findings matching are dropped before reaching any user-visible consumer, regardless of YAML state.
func IsControlApplicableTo ¶ added in v0.3.0
IsControlApplicableTo reports whether the named control applies to the given provider. Returns false for unknown control names.
func ParseRequiredExpression ¶ added in v0.1.34
ParseRequiredExpression parses a human-readable requirement expression and returns the equivalent DNF groups ([][]string).
Examples:
"a AND b" → [["a", "b"]] "a OR b" → [["a"], ["b"]] "(a AND b) OR c" → [["a", "b"], ["c"]] "a AND (b OR c)" → [["a", "b"], ["a", "c"]] "" → [] (empty — no requirements)
func ProviderNeedsActionMetadata ¶ added in v0.3.0
ProviderNeedsActionMetadata reports whether at least one control that depends on action-ref API metadata is currently shipping for the given provider. Returns false when every consumer is benched, letting the collector skip the GitHub API enrichment loop.
func ValidControlNames ¶ added in v0.1.44
func ValidControlNames() []string
ValidControlNames returns all known control names from the configuration schema.
func ValidFlatKeys ¶ added in v0.1.61
func ValidFlatKeys() map[string]struct{}
ValidFlatKeys returns every valid flattened key path recognized by the schema, e.g. "controls.branchMustBeProtected.enabled". This includes keys that may be commented out in the default config file.
func ValidateKnownKeys ¶ added in v0.1.43
ValidateKnownKeys checks for unknown configuration keys in .plumber.yaml at both the control level and the sub-key level. It accepts both the legacy v1 schema (top-level `controls:`) and the v2 schema (provider- nested `gitlab.controls:` / `github.controls:`). Returns a list of warning messages for unknown keys, with suggestions where a close known key exists.
Types ¶
type ActionAuthorizedSourcesControlConfig ¶ added in v0.3.62
type ActionAuthorizedSourcesControlConfig struct {
// Enabled controls whether this check runs.
Enabled *bool `yaml:"enabled,omitempty"`
// TrustGithubOfficialActions trusts the first-party GitHub-owned
// actions (`actions/*`, `github/*`) that any workflow already
// executes implicitly. Defaults to true when unset.
TrustGithubOfficialActions *bool `yaml:"trustGithubOfficialActions,omitempty"`
// TrustSameOrgActions trusts actions whose owner is the same org/user
// as the scanned repository — an org's own actions are already inside
// its trust boundary. Defaults to true when unset.
TrustSameOrgActions *bool `yaml:"trustSameOrgActions,omitempty"`
// MinimumStars, when > 0, trusts any action whose upstream
// repository has at least this many GitHub stars. 0 disables the
// star check. Requires GitHub API metadata; when the star count
// cannot be resolved the reference falls back to the allowlist
// rather than being flagged on missing data.
MinimumStars int `yaml:"minimumStars,omitempty"`
// TrustedGithubActions lists action sources that are always allowed.
// Each entry is either an exact `owner/repo` (e.g. `jdx/mise-action`)
// or an `owner/*` wildcard trusting a whole org (e.g. `mycompany/*`).
TrustedGithubActions []string `yaml:"trustedGithubActions,omitempty"`
// IncludePlumberDefaults, in overlay mode (extends: plumber:default),
// unions Plumber's curated default trusted list with TrustedGithubActions.
// Defaults to true. Set false to trust only the entries listed here.
// Ignored in legacy (no-extends) mode.
IncludePlumberDefaults *bool `yaml:"includePlumberDefaults,omitempty"`
}
ActionAuthorizedSourcesControlConfig configures the GitHub Actions authorized-sources supply-chain check (ISSUE-713). Only meaningful on GitHub workflows. A `uses:` reference is authorized when its owner is GitHub-official (when TrustGithubOfficialActions is on), its `owner/repo` matches an entry in TrustedGithubActions, or — when MinimumStars > 0 — the action repository has at least that many stars.
func (*ActionAuthorizedSourcesControlConfig) IsEnabled ¶ added in v0.3.62
func (c *ActionAuthorizedSourcesControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled
func (*ActionAuthorizedSourcesControlConfig) IsIncludePlumberDefaults ¶ added in v0.4.25
func (c *ActionAuthorizedSourcesControlConfig) IsIncludePlumberDefaults() bool
IsIncludePlumberDefaults reports whether the curated default trusted list is unioned in. Defaults to true when the config or field is nil.
type ActionsPinnedByShaControlConfig ¶ added in v0.3.0
type ActionsPinnedByShaControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// TrustedOwners lists action-owner prefixes that are exempt from the
// pin-by-SHA requirement. Only owners inside the workflow's existing
// trust boundary should be listed here — "actions" and "github"
// cover the first-party GitHub-owned actions the runtime trusts
// implicitly. Adding a third-party owner here re-opens the exact
// supply-chain risk the check exists to close.
TrustedOwners []string `yaml:"trustedOwners,omitempty"`
}
ActionsPinnedByShaControlConfig configures the GitHub Actions supply- chain pinning check (ISSUE-701). Only meaningful on GitHub workflows.
func (*ActionsPinnedByShaControlConfig) IsEnabled ¶ added in v0.3.0
func (c *ActionsPinnedByShaControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled
type AuthConfig ¶ added in v0.3.0
type AuthConfig struct {
// RequireAuth, when true, makes the analyze command exit non-zero
// if no provider credentials are available. Default false on GitHub
// (soft-degrade with visible banner, matching `gh` CLI ergonomics).
// Has no effect on GitLab today (GitLab already hard-fails without
// a token via CLI flag / env).
RequireAuth *bool `yaml:"requireAuth,omitempty"`
}
AuthConfig holds per-provider authentication knobs. Currently only GitHub uses this; the type is provider-agnostic so GitLab can adopt it later without a schema change.
func (*AuthConfig) IsRequireAuth ¶ added in v0.3.0
func (a *AuthConfig) IsRequireAuth() bool
IsRequireAuth returns whether requireAuth is set to true. Defaults to false when the section, the field, or the auth block is nil.
type BranchProtectionControlConfig ¶
type BranchProtectionControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// NamePatterns is a list of branch name patterns that must be protected (supports wildcards)
NamePatterns []string `yaml:"namePatterns,omitempty"`
// DefaultMustBeProtected requires the default branch to be protected
DefaultMustBeProtected *bool `yaml:"defaultMustBeProtected,omitempty"`
// AllowForcePush when false, force push must be disabled on protected branches
AllowForcePush *bool `yaml:"allowForcePush,omitempty"`
// CodeOwnerApprovalRequired when true, code owner approval is required
CodeOwnerApprovalRequired *bool `yaml:"codeOwnerApprovalRequired,omitempty"`
// MinMergeAccessLevel minimum access level required to merge (0=No one, 30=Developer, 40=Maintainer)
MinMergeAccessLevel *int `yaml:"minMergeAccessLevel,omitempty"`
// MinPushAccessLevel minimum access level required to push (0=No one, 30=Developer, 40=Maintainer)
MinPushAccessLevel *int `yaml:"minPushAccessLevel,omitempty"`
}
func (*BranchProtectionControlConfig) IsEnabled ¶
func (c *BranchProtectionControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type CacheActionSpec ¶ added in v0.3.101
type CacheActionSpec struct {
// Action is the `uses:` owner/repo prefix (e.g. "actions/setup-go").
Action string `yaml:"action"`
// Mode is "always", "default", or "opt-in".
Mode string `yaml:"mode"`
// DisableInput / DisableValue apply to mode "default": the action's
// `with:` input whose value turns caching off (e.g. cache=false for
// setup-go, cache-disabled=true for setup-gradle).
DisableInput string `yaml:"disableInput,omitempty"`
DisableValue *bool `yaml:"disableValue,omitempty"`
// EnableInput applies to mode "opt-in": the `with:` input that, when
// set to a package manager, turns caching on (e.g. cache=npm).
EnableInput string `yaml:"enableInput,omitempty"`
// EnableContains additionally requires EnableInput's value to contain
// this substring (case-insensitive) for the cache to count as active —
// e.g. build-push-action restores a GitHub Actions cache only when
// cache-from contains "type=gha".
EnableContains string `yaml:"enableContains,omitempty"`
}
CacheActionSpec describes one cache-restoring action and when it actually restores a cache. Mode is "always" (restores whenever present), "default" (restores unless DisableInput holds DisableValue), or "opt-in" (restores only when EnableInput names a manager).
type CachePoisoningControlConfig ¶ added in v0.3.101
type CachePoisoningControlConfig struct {
// Enabled controls whether this check runs.
Enabled *bool `yaml:"enabled,omitempty"`
// PublishActions are `uses:` owner/repo prefixes that mark a job as
// release intent (running one restores into a published build).
PublishActions []string `yaml:"publishActions,omitempty"`
// CacheActions is the full inventory of cache-restoring actions with
// their per-action semantics. The rego is a pure engine over this
// list — nothing about which actions cache (or how) is hardcoded.
CacheActions []CacheActionSpec `yaml:"cacheActions,omitempty"`
// PublishScriptPatterns are regexes matched against `run:` scripts to
// mark a job as release intent (e.g. `cargo publish`).
PublishScriptPatterns []string `yaml:"publishScriptPatterns,omitempty"`
// PublishScriptExcludePatterns are regexes that veto a
// PublishScriptPatterns match on the same `run:` block —
// verification-only forms that never publish (e.g.
// `npm publish --dry-run`, gradle `publishToMavenLocal`).
PublishScriptExcludePatterns []string `yaml:"publishScriptExcludePatterns,omitempty"`
// AllowedJobs are glob patterns matched against the namespaced job
// name (`<workflow>/<job>`). A job that matches is exempt from this
// control — the escape hatch for reviewed/accepted release jobs.
AllowedJobs []string `yaml:"allowedJobs,omitempty"`
}
CachePoisoningControlConfig configures the release cache-poisoning check (ISSUE-705). The action and script INVENTORIES are configurable so an org can add its own publish actions, cache actions, or publish commands without a plumber release. The built-in cache SEMANTICS (which setup-* actions cache by default vs on opt-in, and the github.ref* scope tokens) stay in code — that is GitHub behaviour, not org policy.
func (*CachePoisoningControlConfig) IsEnabled ¶ added in v0.3.101
func (c *CachePoisoningControlConfig) IsEnabled() bool
IsEnabled reports whether the control is enabled.
type Configuration ¶
type Configuration struct {
// GitLab connection settings
GitlabURL string // URL of the GitLab instance (e.g., https://gitlab.com)
GitlabToken string // GitLab API token
// GitHub connection settings
// GithubAPIHost is the GitHub API host. Empty means default
// (api.github.com). Set to a GitHub Enterprise Server host
// (e.g. "ghes.example.com" or "ghes.example.com/api/v3") to
// target a self-hosted instance. Auth is provided via the same
// resolution chain as default github.com (GH_TOKEN /
// GH_ENTERPRISE_TOKEN / GITHUB_TOKEN / gh auth).
GithubAPIHost string
// Project settings
ProjectPath string // Full path of the project (e.g., group/project)
ProjectID int // Project ID on GitLab
Branch string // Branch to analyze (from --branch flag, defaults to project's default branch)
// HTTP client settings
HTTPClientTimeout time.Duration // Timeout for HTTP clients (REST and GraphQL)
// HTTPClient, when non-nil, is used verbatim by the GitLab REST/GraphQL/HTTP
// client constructors instead of building the default retry-wrapped client.
// It exists so an EMBEDDING host (the Plumber platform, ADR-0021) can inject
// its single, shared, rate-limited/cached client per (provider, instance)
// (INVARIANTS rule J). The CLI's own runs leave this nil and get the default
// client unchanged — this field is purely additive and transparent.
HTTPClient *http.Client
// GitLab API retry configuration
GitlabRetryMaxRetries int // Maximum number of retries for GitLab API requests
GitlabRetryInitialBackoff time.Duration // Initial backoff time for GitLab API retries
GitlabRetryMaxBackoff time.Duration // Maximum backoff time for GitLab API retries
GitlabRetryBackoffFactor float64 // Backoff multiplication factor for exponential backoff
// CI configuration path override (from --ci-config-path flag)
CIConfigPathOverride string // When set, overrides the project's CI config file path (e.g., "my-custom-ci.yml")
// Local CI configuration (from local filesystem)
LocalCIConfigContent []byte // Content of local .gitlab-ci.yml (nil if using remote)
UsingLocalCIConfig bool // True when using local CI config file
GitRepoRoot string // Root of the git repository (empty if not in a git repo)
IsLocalProject bool // True when the local git repo matches the project being analyzed
// Version info
Version string
// Plumber Configuration (from .plumber.yaml file)
PlumberConfig *PlumberConfig
// ConfigFilePath is the path the Plumber config was loaded from, shown
// in the run header.
ConfigFilePath string
// Values must match .plumber.yaml control keys
// ControlsFilter runs only the listed controls when set;
ControlsFilter []string
// SkipControlsFilter skips the listed controls when set;
SkipControlsFilter []string
// ProgressFunc is an optional callback invoked during analysis to report progress.
// step: current step number (1-based), total: total number of steps, message: description.
ProgressFunc func(step int, total int, message string)
}
Configuration represents the simplified CLI configuration options
func NewDefaultConfiguration ¶
func NewDefaultConfiguration() *Configuration
NewDefaultConfiguration creates a Configuration with sensible defaults
type ControlMeta ¶ added in v0.3.0
type ControlMeta struct {
// Providers lists the providers this control is applicable to.
// "gitlab", "github", or both. Used by ValidateKnownKeys to warn
// when a control is placed under the wrong provider section.
Providers []string
}
ControlMeta describes a control's static properties: which providers it applies to and whether it is currently considered production- ready (i.e. NOT benched). Toggle semantics for individual users live in .plumber.yaml — this registry only describes the universe of controls the engine knows about.
type ControlsConfig ¶
type ControlsConfig struct {
// ContainerImageMustNotUseForbiddenTags control configuration
ContainerImageMustNotUseForbiddenTags *ImageForbiddenTagsControlConfig `yaml:"containerImageMustNotUseForbiddenTags,omitempty"`
// ContainerImageMustComeFromAuthorizedSources control configuration
ContainerImageMustComeFromAuthorizedSources *ImageAuthorizedSourcesControlConfig `yaml:"containerImageMustComeFromAuthorizedSources,omitempty"`
// BranchMustBeProtected control configuration
BranchMustBeProtected *BranchProtectionControlConfig `yaml:"branchMustBeProtected,omitempty"`
// MergeRequestApprovalRulesMustRequireMinimumApprovals control
// configuration (GitLab only). Flags approval rules covering all
// protected branches that require fewer approvals than the configured
// minimum (ISSUE-502).
MergeRequestApprovalRulesMustRequireMinimumApprovals *MRApprovalRulesMinApprovalsControlConfig `yaml:"mergeRequestApprovalRulesMustRequireMinimumApprovals,omitempty"`
// MergeRequestApprovalRulesMustCoverAllProtectedBranches control
// configuration (GitLab only). Flags a project where no approval rule
// applies to all protected branches (ISSUE-504). Config-free beyond
// `enabled`.
MergeRequestApprovalRulesMustCoverAllProtectedBranches *EnabledOnlyControlConfig `yaml:"mergeRequestApprovalRulesMustCoverAllProtectedBranches,omitempty"`
// CicdVariablesMustBeProtected control configuration (GitLab only).
// Flags project CI/CD settings variables that are not marked
// protected, so they are exposed to pipelines running on unprotected
// branches (ISSUE-201). Config-free; toggle via `enabled`.
CicdVariablesMustBeProtected *EnabledOnlyControlConfig `yaml:"cicdVariablesMustBeProtected,omitempty"`
// CicdVariablesMustBeMasked control configuration (GitLab only).
// Flags project CI/CD settings variables that are not masked, so
// their values print verbatim in every job log a project member can
// read (ISSUE-202). Config-free; toggle via `enabled`.
CicdVariablesMustBeMasked *EnabledOnlyControlConfig `yaml:"cicdVariablesMustBeMasked,omitempty"`
// MergeRequestApprovalSettingsMustBeCompliant control configuration
// (GitLab only). Checks the project's merge-request approval settings
// against per-setting optional expectations (ISSUE-503).
MergeRequestApprovalSettingsMustBeCompliant *MRApprovalSettingsControlConfig `yaml:"mergeRequestApprovalSettingsMustBeCompliant,omitempty"`
// MergeRequestSettingsMustBeCompliant control configuration (GitLab only).
// Checks the project's merge-request/merge settings (merge method, squash,
// merge trains, source-branch removal, etc.) against per-setting optional
// expectations for exact equality (ISSUE-506).
MergeRequestSettingsMustBeCompliant *MRSettingsControlConfig `yaml:"mergeRequestSettingsMustBeCompliant,omitempty"`
// ProjectMustHaveSecurityPolicySource control configuration (GitLab only).
// Requires the project to link the expected GitLab security policy project
// (ISSUE-601). Requires GitLab Ultimate.
ProjectMustHaveSecurityPolicySource *SecurityPolicyControlConfig `yaml:"projectMustHaveSecurityPolicySource,omitempty"`
// PipelineMustNotIncludeHardcodedJobs control configuration
PipelineMustNotIncludeHardcodedJobs *HardcodedJobsControlConfig `yaml:"pipelineMustNotIncludeHardcodedJobs,omitempty"`
// ExternalRefsMustNotCollide control configuration (GitLab + GitHub).
// Flags external CI references whose symbolic ref resolves upstream as
// BOTH a tag and a branch (ref-confusion, ISSUE-402): GitHub `uses:`
// action refs and GitLab `include:` project `ref:` / component
// `@version` refs. Driven by a per-ref tag+branch API probe.
// Config-free; toggle via `enabled`.
ExternalRefsMustNotCollide *EnabledOnlyControlConfig `yaml:"externalRefsMustNotCollide,omitempty"`
// IncludesMustBeUpToDate control configuration
IncludesMustBeUpToDate *IncludesUpToDateControlConfig `yaml:"includesMustBeUpToDate,omitempty"`
// IncludesMustNotUseForbiddenVersions control configuration
IncludesMustNotUseForbiddenVersions *IncludesForbiddenVersionsControlConfig `yaml:"includesMustNotUseForbiddenVersions,omitempty"`
// PipelineMustIncludeComponent control configuration
PipelineMustIncludeComponent *RequiredComponentsControlConfig `yaml:"pipelineMustIncludeComponent,omitempty"`
// PipelineMustIncludeTemplate control configuration
PipelineMustIncludeTemplate *RequiredTemplatesControlConfig `yaml:"pipelineMustIncludeTemplate,omitempty"`
// PipelineMustNotEnableDebugTrace control configuration
PipelineMustNotEnableDebugTrace *DebugTraceControlConfig `yaml:"pipelineMustNotEnableDebugTrace,omitempty"`
// PipelineMustNotUseUnsafeVariableExpansion control configuration
PipelineMustNotUseUnsafeVariableExpansion *VariableInjectionControlConfig `yaml:"pipelineMustNotUseUnsafeVariableExpansion,omitempty"`
// SecurityJobsMustNotBeWeakened control configuration
SecurityJobsMustNotBeWeakened *SecurityJobsWeakenedControlConfig `yaml:"securityJobsMustNotBeWeakened,omitempty"`
// PipelineMustNotExecuteUnverifiedScripts control configuration
PipelineMustNotExecuteUnverifiedScripts *UnverifiedScriptsControlConfig `yaml:"pipelineMustNotExecuteUnverifiedScripts,omitempty"`
// PipelineMustNotOverrideJobVariables control configuration
PipelineMustNotOverrideJobVariables *JobVariablesOverrideControlConfig `yaml:"pipelineMustNotOverrideJobVariables,omitempty"`
// PipelineMustNotUseDockerInDocker control configuration
PipelineMustNotUseDockerInDocker *DockerInDockerControlConfig `yaml:"pipelineMustNotUseDockerInDocker,omitempty"`
// ActionsMustBePinnedByCommitSha control configuration (GitHub Actions only)
ActionsMustBePinnedByCommitSha *ActionsPinnedByShaControlConfig `yaml:"actionsMustBePinnedByCommitSha,omitempty"`
// GithubActionMustComeFromAuthorizedSources control configuration
// (GitHub Actions only). Restricts which `uses:` action sources are
// allowed: GitHub-official actions, an org allowlist (exact or
// owner/* wildcard), and an optional minimum-stars trust floor.
GithubActionMustComeFromAuthorizedSources *ActionAuthorizedSourcesControlConfig `yaml:"githubActionMustComeFromAuthorizedSources,omitempty"`
// WorkflowMustNotInjectUserInputInScripts control configuration (GitHub Actions only).
// Config-free; toggle via `enabled`.
WorkflowMustNotInjectUserInputInScripts *EnabledOnlyControlConfig `yaml:"workflowMustNotInjectUserInputInScripts,omitempty"`
// WorkflowMustNotWriteUntrustedContentToGitHubEnv control configuration (GitHub Actions only).
// Config-free; toggle via `enabled`.
WorkflowMustNotWriteUntrustedContentToGitHubEnv *EnabledOnlyControlConfig `yaml:"workflowMustNotWriteUntrustedContentToGitHubEnv,omitempty"`
// WorkflowMustNotUseDangerousTriggers control configuration (GitHub Actions only).
// Config-free; toggle via `enabled`.
WorkflowMustNotUseDangerousTriggers *EnabledOnlyControlConfig `yaml:"workflowMustNotUseDangerousTriggers,omitempty"`
// PullRequestTargetMustNotCheckoutHead control configuration (GitHub
// Actions only). Flags a workflow triggered by `pull_request_target`
// that checks out the PR head ref, putting base-repo secrets and
// fork-controlled code in the same run (tj-actions / CVE-2025-30066).
// Config-free; toggle via `enabled`.
PullRequestTargetMustNotCheckoutHead *EnabledOnlyControlConfig `yaml:"pullRequestTargetMustNotCheckoutHead,omitempty"`
// WorkflowsMustDeclarePermissions control configuration (GitHub Actions only).
// Config-free; toggle via `enabled`.
WorkflowsMustDeclarePermissions *EnabledOnlyControlConfig `yaml:"workflowsMustDeclarePermissions,omitempty"`
// ReusableWorkflowsMustNotInheritSecrets control configuration (GitHub Actions only).
// Config-free; toggle via `enabled`.
ReusableWorkflowsMustNotInheritSecrets *EnabledOnlyControlConfig `yaml:"reusableWorkflowsMustNotInheritSecrets,omitempty"`
// WorkflowMustNotExportEntireSecretsContext control configuration (GitHub Actions only).
// Flags a job that serialises the whole `secrets` context via toJson(secrets)
// into a run script, env binding, or action `with:` input. Config-free; toggle
// via `enabled`.
WorkflowMustNotExportEntireSecretsContext *EnabledOnlyControlConfig `yaml:"workflowMustNotExportEntireSecretsContext,omitempty"`
// WorkflowMustNotGrantPermissionsWriteAll control configuration (GitHub
// Actions only). Flags workflows or jobs whose effective `permissions:`
// block is the literal `write-all` shortcut, which grants every scope
// (contents, packages, deployments, …) write access on GITHUB_TOKEN.
// Stricter scope-level audits (per-scope write grants) are out of scope
// here; they get their own rule later. Config-free; toggle via `enabled`.
WorkflowMustNotGrantPermissionsWriteAll *EnabledOnlyControlConfig `yaml:"workflowMustNotGrantPermissionsWriteAll,omitempty"`
// ActionsMustNotBeArchived control configuration (GitHub Actions only).
// Flags `uses: owner/repo@ref` references whose upstream repository is
// archived on GitHub. Driven by per-action API metadata enriched at
// collect time. Config-free; toggle via `enabled`.
ActionsMustNotBeArchived *EnabledOnlyControlConfig `yaml:"actionsMustNotBeArchived,omitempty"`
// ActionRefsMustExistUpstream control configuration (GitHub Actions
// only). Flags `uses: owner/repo@<sha>` references pinned to a 40-char
// commit SHA that the upstream repository confirms does not exist — a
// typo or an impostor-commit attack. Fires only on a definitive 404
// from a readable repo; a SHA that could not be verified stays silent.
// Driven by per-action API metadata enriched at collect time.
// Config-free; toggle via `enabled`.
ActionRefsMustExistUpstream *EnabledOnlyControlConfig `yaml:"actionRefsMustExistUpstream,omitempty"`
// ActionsMustNotCarryKnownCVEs control configuration (GitHub Actions
// only). Flags `uses: owner/repo@ref` references whose upstream
// repository carries at least one published advisory in GitHub's
// Advisory Database under the `actions` ecosystem. Driven by per-
// action API metadata enriched at collect time. Config-free; toggle
// via `enabled`.
ActionsMustNotCarryKnownCVEs *EnabledOnlyControlConfig `yaml:"actionsMustNotCarryKnownCVEs,omitempty"`
// ActionsMustNotExecuteMutableRemoteCode control configuration (GitHub
// Actions only). Flags a third-party action whose own source fetches
// and executes a script from a moving ref at runtime, so a SHA pin on
// the action does not make its execution immutable. Driven by the
// collector's per-action source analysis. Config-free; toggle via
// `enabled`.
ActionsMustNotExecuteMutableRemoteCode *EnabledOnlyControlConfig `yaml:"actionsMustNotExecuteMutableRemoteCode,omitempty"`
// ReleaseWorkflowsMustNotRestoreUntrustedCache control configuration (GitHub
// Actions only). Flags a release/publish job that restores a build cache
// whose key is not scoped to the release ref, so a PR-populated cache can be
// injected into the published output. Config-free; toggle via `enabled`.
ReleaseWorkflowsMustNotRestoreUntrustedCache *CachePoisoningControlConfig `yaml:"releaseWorkflowsMustNotRestoreUntrustedCache,omitempty"`
// WorkflowMustIncludeRequiredActions control configuration (GitHub
// Actions only). The GitHub counterpart of
// PipelineMustIncludeComponent / PipelineMustIncludeTemplate on
// the GitLab side: assert that workflows reference a configured
// set of required actions or reusable workflows. Matching is by
// `owner/repo[/path]` prefix and ref-agnostic, so
// `org/sast-scan` matches `uses: org/sast-scan@v2`,
// `uses: org/sast-scan@abc123`, and `uses: org/sast-scan/sub@v1`.
WorkflowMustIncludeRequiredActions *RequiredActionsControlConfig `yaml:"workflowMustIncludeRequiredActions,omitempty"`
}
ControlsConfig holds configuration for all controls
type DebugTraceControlConfig ¶ added in v0.1.51
type DebugTraceControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// ForbiddenVariables is a list of CI/CD variable names that must not be set to "true"
// Defaults: CI_DEBUG_TRACE, CI_DEBUG_SERVICES
ForbiddenVariables []string `yaml:"forbiddenVariables,omitempty"`
}
DebugTraceControlConfig configuration for the debug trace detection control
func (*DebugTraceControlConfig) IsEnabled ¶ added in v0.1.51
func (c *DebugTraceControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type DockerInDockerControlConfig ¶ added in v0.1.77
type DockerInDockerControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// DetectInsecureDaemon when true, also flags insecure daemon configuration
// (DOCKER_TLS_CERTDIR="" or DOCKER_HOST pointing to non-TLS port 2375)
// in jobs that use a DinD service.
DetectInsecureDaemon *bool `yaml:"detectInsecureDaemon,omitempty"`
}
DockerInDockerControlConfig configuration for the Docker-in-Docker detection control
func (*DockerInDockerControlConfig) IsDetectInsecureDaemonEnabled ¶ added in v0.1.77
func (c *DockerInDockerControlConfig) IsDetectInsecureDaemonEnabled() bool
IsDetectInsecureDaemonEnabled returns whether insecure daemon detection is enabled. Defaults to true when the field is nil.
func (*DockerInDockerControlConfig) IsEnabled ¶ added in v0.1.77
func (c *DockerInDockerControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type EnabledOnlyControlConfig ¶ added in v0.3.0
type EnabledOnlyControlConfig struct {
Enabled *bool `yaml:"enabled,omitempty"`
}
EnabledOnlyControlConfig is the shape used for controls that have no configurable behaviour beyond on/off. The Rego rule for these controls reads no `input.config.<name>` keys; toggling enabled to false simply drops their findings via FilterFindingsByEnabledControls.
func (*EnabledOnlyControlConfig) IsEnabled ¶ added in v0.3.0
func (c *EnabledOnlyControlConfig) IsEnabled() bool
IsEnabled reports whether the control is enabled. Returns false when the wrapper or the field is nil — same convention as every other IsEnabled() in this package.
type HardcodedJobsControlConfig ¶ added in v0.1.31
type HardcodedJobsControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
}
HardcodedJobsControlConfig configuration for the hardcoded jobs control
func (*HardcodedJobsControlConfig) IsEnabled ¶ added in v0.1.31
func (c *HardcodedJobsControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type ImageAuthorizedSourcesControlConfig ¶
type ImageAuthorizedSourcesControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// TrustedUrls is a list of trusted registry URLs/patterns (supports wildcards)
TrustedUrls []string `yaml:"trustedUrls,omitempty"`
// TrustDockerHubOfficialImages trusts official Docker Hub images (e.g., nginx, alpine)
TrustDockerHubOfficialImages *bool `yaml:"trustDockerHubOfficialImages,omitempty"`
// IncludePlumberDefaults, in overlay mode (extends: plumber:default),
// unions Plumber's curated default trusted list with TrustedUrls.
// Defaults to true. Set false to trust only the entries listed here.
// Ignored in legacy (no-extends) mode.
IncludePlumberDefaults *bool `yaml:"includePlumberDefaults,omitempty"`
}
ImageAuthorizedSourcesControlConfig configuration for the authorized image sources control
func (*ImageAuthorizedSourcesControlConfig) IsEnabled ¶
func (c *ImageAuthorizedSourcesControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
func (*ImageAuthorizedSourcesControlConfig) IsIncludePlumberDefaults ¶ added in v0.4.25
func (c *ImageAuthorizedSourcesControlConfig) IsIncludePlumberDefaults() bool
IsIncludePlumberDefaults reports whether the curated default trusted list is unioned in. Defaults to true when the config or field is nil.
type ImageForbiddenTagsControlConfig ¶
type ImageForbiddenTagsControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// Tags is a list of forbidden tags (e.g., latest, dev)
Tags []string `yaml:"tags,omitempty"`
// ContainerImagesMustBePinnedByDigest when true, ALL images must use immutable digest references.
// Takes precedence over the forbidden tags list — any image not pinned by digest is flagged.
ContainerImagesMustBePinnedByDigest *bool `yaml:"containerImagesMustBePinnedByDigest,omitempty"`
}
ImageForbiddenTagsControlConfig configuration for the forbidden image tags control
func (*ImageForbiddenTagsControlConfig) IsEnabled ¶
func (c *ImageForbiddenTagsControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
func (*ImageForbiddenTagsControlConfig) IsPinnedByDigestRequired ¶ added in v0.1.40
func (c *ImageForbiddenTagsControlConfig) IsPinnedByDigestRequired() bool
IsPinnedByDigestRequired returns whether all images must be pinned by digest
type IncludesForbiddenVersionsControlConfig ¶ added in v0.1.31
type IncludesForbiddenVersionsControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// ForbiddenVersions is a list of version patterns considered forbidden (e.g., latest, main, HEAD)
ForbiddenVersions []string `yaml:"forbiddenVersions,omitempty"`
// DefaultBranchIsForbiddenVersion when true, adds the project's default branch to forbidden versions
DefaultBranchIsForbiddenVersion *bool `yaml:"defaultBranchIsForbiddenVersion,omitempty"`
}
IncludesForbiddenVersionsControlConfig configuration for the forbidden versions control
func (*IncludesForbiddenVersionsControlConfig) IsEnabled ¶ added in v0.1.31
func (c *IncludesForbiddenVersionsControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type IncludesUpToDateControlConfig ¶ added in v0.1.31
type IncludesUpToDateControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
}
IncludesUpToDateControlConfig configuration for the includes up-to-date control
func (*IncludesUpToDateControlConfig) IsEnabled ¶ added in v0.1.31
func (c *IncludesUpToDateControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type JobVariablesOverrideControlConfig ¶ added in v0.1.76
type JobVariablesOverrideControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// Variables is a list of CI/CD variable names that must not be defined
// in the pipeline configuration file. They should only be set via
// GitLab CI/CD Settings > Variables.
Variables []string `yaml:"variables,omitempty"`
}
JobVariablesOverrideControlConfig configuration for the job variable override control
func (*JobVariablesOverrideControlConfig) IsEnabled ¶ added in v0.1.76
func (c *JobVariablesOverrideControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type MRApprovalRulesMinApprovalsControlConfig ¶ added in v0.4.42
type MRApprovalRulesMinApprovalsControlConfig struct {
// Enabled controls whether this check runs.
Enabled *bool `yaml:"enabled,omitempty"`
// MinimumRequiredApprovals is the fewest approvals a rule covering all
// protected branches must require; a covering rule below it is flagged.
// When unset (nil) the control asserts nothing (treated as 0).
//
// Platform migration: this key was named minimumRequiredApprovalAllProtectedBranches
// on the backend2 platform. It is deliberately shortened to
// minimumRequiredApprovals in the CLI (the "all protected branches" scope is
// already implied by the control). A platform-config importer must map the
// old key to this one.
MinimumRequiredApprovals *int `yaml:"minimumRequiredApprovals,omitempty"`
}
BranchProtectionControlConfig configuration for the branch protection control MRApprovalRulesMinApprovalsControlConfig configures the GitLab merge-request approval-rules minimum-approvals check (ISSUE-502). GitLab-only.
func (*MRApprovalRulesMinApprovalsControlConfig) IsEnabled ¶ added in v0.4.42
func (c *MRApprovalRulesMinApprovalsControlConfig) IsEnabled() bool
IsEnabled reports whether the control is enabled. Returns false when the wrapper or the field is nil — same convention as every other IsEnabled().
type MRApprovalSettingsControlConfig ¶ added in v0.4.43
type MRApprovalSettingsControlConfig struct {
// Enabled controls whether this check runs.
Enabled *bool `yaml:"enabled,omitempty"`
// PreventApprovalByAuthor, when true, expects that MR authors cannot
// approve their own merge requests.
PreventApprovalByAuthor *bool `yaml:"preventApprovalByAuthor,omitempty"`
// PreventApprovalsByCommitters, when true, expects that users who
// committed to an MR cannot approve it.
PreventApprovalsByCommitters *bool `yaml:"preventApprovalsByCommitters,omitempty"`
// PreventEditingApprovalRulesInMR, when true, expects that approval
// rules cannot be overridden per merge request.
PreventEditingApprovalRulesInMR *bool `yaml:"preventEditingApprovalRulesInMR,omitempty"`
// RequireReAuthToApprove, when true, expects that approving requires
// re-authentication.
RequireReAuthToApprove *bool `yaml:"requireReAuthToApprove,omitempty"`
// BehaviorWhenCommitIsAdded is the MINIMUM required strictness for what
// happens to existing approvals when a commit is added to an open MR:
// "keep_approvals" < "remove_approvals_by_code_owners" <
// "remove_all_approvals". A project below the configured rung is
// flagged; any other value fails config validation.
BehaviorWhenCommitIsAdded *string `yaml:"behaviorWhenCommitIsAdded,omitempty"`
}
MRApprovalSettingsControlConfig configures the GitLab merge-request approval-settings check (ISSUE-503). GitLab-only. Every expectation is optional: an unset field is not checked. The booleans check only when set true — an explicit false is the same as unset, matching the legacy platform's conf semantics (there is no "expect the unsafe setting" mode).
func (*MRApprovalSettingsControlConfig) IsEnabled ¶ added in v0.4.43
func (c *MRApprovalSettingsControlConfig) IsEnabled() bool
IsEnabled reports whether the control is enabled. Returns false when the wrapper or the field is nil — same convention as every other IsEnabled().
type MRSettingsControlConfig ¶ added in v0.4.43
type MRSettingsControlConfig struct {
// Enabled controls whether this check runs.
Enabled *bool `yaml:"enabled,omitempty"`
// MergeMethod is the expected merge method: "merge", "ff", or
// "rebase_merge". Any other value fails config validation.
MergeMethod *string `yaml:"mergeMethod,omitempty"`
// SquashOption is the expected squash policy: "never", "always",
// "default_on", or "default_off". Any other value fails config validation.
SquashOption *string `yaml:"squashOption,omitempty"`
// MergePipelinesEnabled is the expected merged-results-pipelines setting.
MergePipelinesEnabled *bool `yaml:"mergePipelinesEnabled,omitempty"`
// MergeTrainsEnabled is the expected merge-trains setting.
MergeTrainsEnabled *bool `yaml:"mergeTrainsEnabled,omitempty"`
// AllowMergeOnSkippedPipeline is the expected "allow merge when the
// pipeline is skipped" setting.
AllowMergeOnSkippedPipeline *bool `yaml:"allowMergeOnSkippedPipeline,omitempty"`
// ResolveOutdatedDiffDiscussions is the expected auto-resolve-outdated-
// discussions setting.
ResolveOutdatedDiffDiscussions *bool `yaml:"resolveOutdatedDiffDiscussions,omitempty"`
// PrintingMergeRequestLinkEnabled is the expected print-MR-link-on-push
// setting.
PrintingMergeRequestLinkEnabled *bool `yaml:"printingMergeRequestLinkEnabled,omitempty"`
// RemoveSourceBranchAfterMerge is the expected delete-source-branch-after-
// merge default.
RemoveSourceBranchAfterMerge *bool `yaml:"removeSourceBranchAfterMerge,omitempty"`
}
MRSettingsControlConfig configures the GitLab merge-request/merge-settings check (ISSUE-506). GitLab-only. Every expectation is optional: an unset field is not checked, and each set field is compared against the project's actual value for EXACT equality (the legacy platform compared all fields, but always with a fully populated policy — optional here keeps a hand-authored YAML from flagging on a field the operator never set).
func (*MRSettingsControlConfig) IsEnabled ¶ added in v0.4.43
func (c *MRSettingsControlConfig) IsEnabled() bool
IsEnabled reports whether the control is enabled. Returns false when the wrapper or the field is nil — same convention as every other IsEnabled().
type PlumberConfig ¶
type PlumberConfig struct {
// Version of the config file format.
// "2.0" = current per-provider schema. "1.0" = legacy flat schema.
// Missing version is tolerated and treated as legacy.
Version string `yaml:"version,omitempty"`
// Extends selects overlay mode. The only supported value is
// "plumber:default": the file is then a sparse overlay merged onto
// the embedded baseline. Absent (the default) keeps legacy full
// replace behavior. See configuration/resolve.go.
Extends string `yaml:"extends,omitempty"`
// GitLab provider section (v2 schema). Holds GitLab-specific auth,
// the enabledControls allowlist, and the per-control configuration map.
GitLab *ProviderConfig `yaml:"gitlab,omitempty"`
// GitHub provider section (v2 schema). Same shape as GitLab.
GitHub *ProviderConfig `yaml:"github,omitempty"`
// Controls configuration (legacy v1 schema, top-level).
// After a v2 load this is the zero value; after a v1 load convertV1ToV2
// moves these into GitLab.Controls and clears this field.
Controls ControlsConfig `yaml:"controls,omitempty"`
// Raw is the verbatim text of the config that produced this run, captured
// at load. The self-describing `plumberConfig` block in the JSON report
// parses it into a structured object (the verbatim text is never shipped).
// Not serialized into the config itself.
Raw string `yaml:"-"`
// Source is the path the config was loaded from, or "default" when no
// file was present and the embedded default was used. Not serialized.
Source string `yaml:"-"`
}
PlumberConfig represents the .plumber.yaml configuration file structure.
Schema versions:
- "2.0" — current per-provider schema (gitlab.controls, github.controls).
- "1.0" — legacy flat schema (top-level controls). Auto-converted in memory at load time with a deprecation warning. Run `plumber config migrate` to upgrade the file on disk.
The legacy v1 fields (Controls) remain on the struct so the loader can detect a v1 file, parse it, and convert it via convertV1ToV2. After a v2 load — or after conversion — Controls is the zero value and downstream code reads from GitLab.Controls / GitHub.Controls.
func LoadPlumberConfig ¶
func LoadPlumberConfig(configPath string) (*PlumberConfig, string, []string, error)
LoadPlumberConfig loads configuration from a file path. It reads the file once, validates for unknown keys, parses the YAML into the config struct, detects whether the file uses the legacy v1 schema (top-level `controls:`/`engine:`) or the current v2 schema (per-provider `gitlab.controls:` / `github.controls:`), and converts v1 in-memory to v2. Returns the parsed config, the resolved path, any warnings (unknown-key + deprecation), and an error if loading or validation failed.
func LoadPlumberConfigFromBytes ¶ added in v0.4.13
func LoadPlumberConfigFromBytes(data []byte, source string) (*PlumberConfig, string, []string, error)
LoadPlumberConfigFromBytes parses configuration from raw bytes, recording `source` as its origin — a file path when called via LoadPlumberConfig, or a label such as "built-in default" when a caller falls back to the embedded config. It runs the same key validation, schema migration (v1 → v2) and version normalisation as loading from a file, so a fallback config is held to exactly the same contract as a user-supplied one.
func (*PlumberConfig) ControlsFor ¶ added in v0.3.0
func (c *PlumberConfig) ControlsFor(provider string) *ControlsConfig
ControlsFor returns a non-nil pointer to the named provider's ControlsConfig. If the provider is absent, returns a pointer to a zero-value ControlsConfig so callers can dereference fields without nil-checking. The returned pointer is read-only — mutations are discarded if the provider was absent.
func (*PlumberConfig) GetBranchMustBeProtectedConfig ¶
func (c *PlumberConfig) GetBranchMustBeProtectedConfig() *BranchProtectionControlConfig
GetBranchMustBeProtectedConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetCicdVariablesMustBeMaskedConfig ¶ added in v0.4.41
func (c *PlumberConfig) GetCicdVariablesMustBeMaskedConfig() *EnabledOnlyControlConfig
func (*PlumberConfig) GetCicdVariablesMustBeProtectedConfig ¶ added in v0.4.41
func (c *PlumberConfig) GetCicdVariablesMustBeProtectedConfig() *EnabledOnlyControlConfig
func (*PlumberConfig) GetContainerImageMustComeFromAuthorizedSourcesConfig ¶
func (c *PlumberConfig) GetContainerImageMustComeFromAuthorizedSourcesConfig() *ImageAuthorizedSourcesControlConfig
GetContainerImageMustComeFromAuthorizedSourcesConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetContainerImageMustNotUseForbiddenTagsConfig ¶
func (c *PlumberConfig) GetContainerImageMustNotUseForbiddenTagsConfig() *ImageForbiddenTagsControlConfig
GetContainerImageMustNotUseForbiddenTagsConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetIncludesMustBeUpToDateConfig ¶ added in v0.1.31
func (c *PlumberConfig) GetIncludesMustBeUpToDateConfig() *IncludesUpToDateControlConfig
GetIncludesMustBeUpToDateConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetIncludesMustNotUseForbiddenVersionsConfig ¶ added in v0.1.31
func (c *PlumberConfig) GetIncludesMustNotUseForbiddenVersionsConfig() *IncludesForbiddenVersionsControlConfig
GetIncludesMustNotUseForbiddenVersionsConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetMergeRequestApprovalRulesMustCoverAllProtectedBranchesConfig ¶ added in v0.4.42
func (c *PlumberConfig) GetMergeRequestApprovalRulesMustCoverAllProtectedBranchesConfig() *EnabledOnlyControlConfig
func (*PlumberConfig) GetMergeRequestApprovalRulesMustRequireMinimumApprovalsConfig ¶ added in v0.4.42
func (c *PlumberConfig) GetMergeRequestApprovalRulesMustRequireMinimumApprovalsConfig() *MRApprovalRulesMinApprovalsControlConfig
func (*PlumberConfig) GetMergeRequestApprovalSettingsMustBeCompliantConfig ¶ added in v0.4.43
func (c *PlumberConfig) GetMergeRequestApprovalSettingsMustBeCompliantConfig() *MRApprovalSettingsControlConfig
func (*PlumberConfig) GetMergeRequestSettingsMustBeCompliantConfig ¶ added in v0.4.43
func (c *PlumberConfig) GetMergeRequestSettingsMustBeCompliantConfig() *MRSettingsControlConfig
func (*PlumberConfig) GetPipelineMustIncludeComponentConfig ¶ added in v0.1.31
func (c *PlumberConfig) GetPipelineMustIncludeComponentConfig() *RequiredComponentsControlConfig
GetPipelineMustIncludeComponentConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetPipelineMustIncludeTemplateConfig ¶ added in v0.1.31
func (c *PlumberConfig) GetPipelineMustIncludeTemplateConfig() *RequiredTemplatesControlConfig
GetPipelineMustIncludeTemplateConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetPipelineMustNotEnableDebugTraceConfig ¶ added in v0.1.51
func (c *PlumberConfig) GetPipelineMustNotEnableDebugTraceConfig() *DebugTraceControlConfig
GetPipelineMustNotEnableDebugTraceConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetPipelineMustNotExecuteUnverifiedScriptsConfig ¶ added in v0.1.69
func (c *PlumberConfig) GetPipelineMustNotExecuteUnverifiedScriptsConfig() *UnverifiedScriptsControlConfig
GetPipelineMustNotExecuteUnverifiedScriptsConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetPipelineMustNotIncludeHardcodedJobsConfig ¶ added in v0.1.31
func (c *PlumberConfig) GetPipelineMustNotIncludeHardcodedJobsConfig() *HardcodedJobsControlConfig
GetPipelineMustNotIncludeHardcodedJobsConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetPipelineMustNotOverrideJobVariablesConfig ¶ added in v0.1.76
func (c *PlumberConfig) GetPipelineMustNotOverrideJobVariablesConfig() *JobVariablesOverrideControlConfig
GetPipelineMustNotOverrideJobVariablesConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetPipelineMustNotUseDockerInDockerConfig ¶ added in v0.1.77
func (c *PlumberConfig) GetPipelineMustNotUseDockerInDockerConfig() *DockerInDockerControlConfig
GetPipelineMustNotUseDockerInDockerConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetPipelineMustNotUseUnsafeVariableExpansionConfig ¶ added in v0.1.52
func (c *PlumberConfig) GetPipelineMustNotUseUnsafeVariableExpansionConfig() *VariableInjectionControlConfig
GetPipelineMustNotUseUnsafeVariableExpansionConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) GetProjectMustHaveSecurityPolicySourceConfig ¶ added in v0.4.44
func (c *PlumberConfig) GetProjectMustHaveSecurityPolicySourceConfig() *SecurityPolicyControlConfig
GetProjectMustHaveSecurityPolicySourceConfig returns the GitLab security-policy-project linkage control configuration (ISSUE-601), or nil.
func (*PlumberConfig) GetSecurityJobsMustNotBeWeakenedConfig ¶ added in v0.1.64
func (c *PlumberConfig) GetSecurityJobsMustNotBeWeakenedConfig() *SecurityJobsWeakenedControlConfig
GetSecurityJobsMustNotBeWeakenedConfig returns the control configuration Returns nil if not configured
func (*PlumberConfig) ProviderConfig ¶ added in v0.3.0
func (c *PlumberConfig) ProviderConfig(name string) *ProviderConfig
ProviderConfig returns the named provider's config, or nil if absent. Accepted names: "gitlab", "github" (case-sensitive). Any other name returns nil. Safe to call on a nil receiver.
func (*PlumberConfig) Validate ¶ added in v0.1.82
func (c *PlumberConfig) Validate() error
Validate checks structural consistency (required component/template expressions, etc.).
type ProviderConfig ¶ added in v0.3.0
type ProviderConfig struct {
// Auth holds provider-specific authentication knobs. Optional.
// Today only GitHub uses this (RequireAuth). Reserved for future
// per-provider auth options on GitLab if needed.
Auth *AuthConfig `yaml:"auth,omitempty"`
// Controls holds per-control configuration. Same struct types as
// the legacy top-level ControlsConfig — only the YAML location and
// the values differ between providers.
Controls ControlsConfig `yaml:"controls,omitempty"`
}
ProviderConfig is the per-provider configuration block introduced in schema v2. One instance per provider section in .plumber.yaml.
Toggle semantics mirror the GitLab side: a control absent from `controls:` is treated as enabled at the filter level; a control present with `enabled: false` is dropped. The dev-side `bench` set in control/registry.go suppresses non-production controls regardless of YAML state — see that file for how to promote a benched control out of bench.
type RequiredActionsControlConfig ¶ added in v0.3.0
type RequiredActionsControlConfig struct {
Enabled *bool `yaml:"enabled,omitempty"`
Required string `yaml:"required,omitempty"`
RequiredGroups [][]string `yaml:"requiredGroups,omitempty"`
}
RequiredActionsControlConfig configures the GitHub workflowMustIncludeRequiredActions control. Mirrors RequiredComponentsControlConfig's DNF (Disjunctive Normal Form) shape so users running both providers have one mental model:
- Required is a boolean expression ("a AND b OR c"), parsed via ParseRequiredExpression into the same OR-of-ANDs groups.
- RequiredGroups is the same DNF written directly.
- The two fields are mutually exclusive at validate-time.
Each required entry is an owner/repo prefix (or owner/repo/path for sub-actions and reusable-workflow paths). Matching is ref-agnostic so users can bump pinned SHAs without rewriting the policy.
func (*RequiredActionsControlConfig) GetResolvedRequiredGroups ¶ added in v0.3.0
func (c *RequiredActionsControlConfig) GetResolvedRequiredGroups() ([][]string, error)
GetResolvedRequiredGroups returns the effective required groups by resolving either the 'required' expression or the 'requiredGroups' field. Errors when both are set or when the expression is invalid.
func (*RequiredActionsControlConfig) IsEnabled ¶ added in v0.3.0
func (c *RequiredActionsControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled. Returns false when the config block is absent or when `enabled:` is not set.
type RequiredComponentsControlConfig ¶ added in v0.1.31
type RequiredComponentsControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// Required is a human-readable boolean expression defining required components.
// Supports AND, OR operators and parentheses for grouping.
// AND has higher precedence than OR.
//
// Examples:
// "components/sast/sast AND components/secret-detection/secret-detection"
// "(components/sast/sast AND components/secret-detection/secret-detection) OR your-org/full-security/full-security"
Required string `yaml:"required,omitempty"`
// RequiredGroups uses DNF (Disjunctive Normal Form) format:
// Outer array = OR (at least one group must be satisfied)
// Inner array = AND (all components in group must be present)
// Example: [["comp-a", "comp-b"], ["comp-c"]] means:
// "must have (comp-a AND comp-b) OR (comp-c)"
//
// Cannot be used together with 'required'.
RequiredGroups [][]string `yaml:"requiredGroups,omitempty"`
}
RequiredComponentsControlConfig configuration for the required components control
func (*RequiredComponentsControlConfig) GetResolvedRequiredGroups ¶ added in v0.1.34
func (c *RequiredComponentsControlConfig) GetResolvedRequiredGroups() ([][]string, error)
GetResolvedRequiredGroups returns the effective required groups by resolving either the 'required' expression or the 'requiredGroups' field. Returns an error if both are set or if the expression is invalid.
func (*RequiredComponentsControlConfig) IsEnabled ¶ added in v0.1.31
func (c *RequiredComponentsControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type RequiredTemplatesControlConfig ¶ added in v0.1.31
type RequiredTemplatesControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// Required is a human-readable boolean expression defining required templates.
// Supports AND, OR operators and parentheses for grouping.
// AND has higher precedence than OR.
//
// Examples:
// "templates/go/go AND templates/trivy/trivy"
// "(templates/go/go AND templates/trivy/trivy) OR templates/full-go-pipeline"
Required string `yaml:"required,omitempty"`
// RequiredGroups uses DNF (Disjunctive Normal Form) format:
// Outer array = OR (at least one group must be satisfied)
// Inner array = AND (all templates in group must be present)
// Example: [["go", "helm"], ["go_helm_unified"]] means:
// "must have (go AND helm) OR (go_helm_unified)"
//
// Cannot be used together with 'required'.
RequiredGroups [][]string `yaml:"requiredGroups,omitempty"`
}
RequiredTemplatesControlConfig configuration for the required templates control
func (*RequiredTemplatesControlConfig) GetResolvedRequiredGroups ¶ added in v0.1.34
func (c *RequiredTemplatesControlConfig) GetResolvedRequiredGroups() ([][]string, error)
GetResolvedRequiredGroups returns the effective required groups by resolving either the 'required' expression or the 'requiredGroups' field. Returns an error if both are set or if the expression is invalid.
func (*RequiredTemplatesControlConfig) IsEnabled ¶ added in v0.1.31
func (c *RequiredTemplatesControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type SecurityJobsSubControlToggle ¶ added in v0.1.64
type SecurityJobsSubControlToggle struct {
Enabled *bool `yaml:"enabled,omitempty"`
}
SecurityJobsSubControlToggle is a simple enabled/disabled toggle for a sub-control
func (*SecurityJobsSubControlToggle) IsEnabled ¶ added in v0.1.64
func (t *SecurityJobsSubControlToggle) IsEnabled(defaultVal bool) bool
IsEnabled returns whether the sub-control toggle is enabled. Returns the provided default if the toggle or its Enabled field is nil.
type SecurityJobsWeakenedControlConfig ¶ added in v0.1.64
type SecurityJobsWeakenedControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// SecurityJobPatterns is a list of job name patterns considered "security jobs" (supports wildcards)
SecurityJobPatterns []string `yaml:"securityJobPatterns,omitempty"`
// Sub-control toggles (sit directly under the control, no wrapper)
AllowFailureMustBeFalse *SecurityJobsSubControlToggle `yaml:"allowFailureMustBeFalse,omitempty"`
RulesMustNotBeRedefined *SecurityJobsSubControlToggle `yaml:"rulesMustNotBeRedefined,omitempty"`
WhenMustNotBeManual *SecurityJobsSubControlToggle `yaml:"whenMustNotBeManual,omitempty"`
}
SecurityJobsWeakenedControlConfig configuration for the security jobs weakening control
func (*SecurityJobsWeakenedControlConfig) IsEnabled ¶ added in v0.1.64
func (c *SecurityJobsWeakenedControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type SecurityPolicyControlConfig ¶ added in v0.4.44
type SecurityPolicyControlConfig struct {
// Enabled controls whether this check runs.
Enabled *bool `yaml:"enabled,omitempty"`
// ExpectedProjectId is the numeric GitLab project ID the security policy
// project must match. Unset => require only that some policy project is
// linked.
ExpectedProjectId *int `yaml:"expectedProjectId,omitempty"`
// ExpectedProjectPath is the full path (namespace/project) the linked
// security policy project must match — a human-friendly alternative to the
// numeric ID, compared case-insensitively. Ignored when ExpectedProjectId is
// also set (the ID is authoritative). Unset (and no ID) => require only that
// some policy project is linked.
ExpectedProjectPath *string `yaml:"expectedProjectPath,omitempty"`
}
SecurityPolicyControlConfig configures the GitLab security-policy-project linkage check (ISSUE-601). GitLab-only, requires Ultimate. When ExpectedProjectId is set, the linked policy project must be exactly that project. When it is unset, any linked policy project passes and the control fails only when none is linked.
func (*SecurityPolicyControlConfig) IsEnabled ¶ added in v0.4.44
func (c *SecurityPolicyControlConfig) IsEnabled() bool
IsEnabled reports whether the control is enabled. Returns false when the wrapper or the field is nil — same convention as every other IsEnabled().
type UnverifiedScriptsControlConfig ¶ added in v0.1.69
type UnverifiedScriptsControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// TrustedUrls is a list of URL patterns that should not trigger findings.
// Supports wildcards (e.g., "https://internal-artifacts.example.com/*").
TrustedUrls []string `yaml:"trustedUrls,omitempty"`
}
UnverifiedScriptsControlConfig configuration for the unverified script execution control
func (*UnverifiedScriptsControlConfig) IsEnabled ¶ added in v0.1.69
func (c *UnverifiedScriptsControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured
type VariableInjectionControlConfig ¶ added in v0.1.52
type VariableInjectionControlConfig struct {
// Enabled controls whether this check runs
Enabled *bool `yaml:"enabled,omitempty"`
// DangerousVariables is a list of CI/CD variable names whose values come from user input
// and should not appear in script blocks where shell injection is possible
DangerousVariables []string `yaml:"dangerousVariables,omitempty"`
// AllowedPatterns is a list of regex patterns. Script lines matching any of these
// patterns will not be flagged even if they contain a dangerous variable.
AllowedPatterns []string `yaml:"allowedPatterns,omitempty"`
}
VariableInjectionControlConfig configuration for the unsafe variable expansion control
func (*VariableInjectionControlConfig) IsEnabled ¶ added in v0.1.52
func (c *VariableInjectionControlConfig) IsEnabled() bool
IsEnabled returns whether the control is enabled Returns false if not properly configured