Skip to main content
ISSUE-415HighPipeline Composition

Functions must come from authorized sources

Control:CTRL-415functionMustComeFromAuthorizedSources

📋 What is this?

A run: step function reference (the func: keyword, or the deprecated step: alias) is pulled from a source that is not trusted: not on an explicit allowlist and not under the scanned project's own namespace (when that trust is enabled).

⚠️ Impact

Functions run arbitrary code with the job's full context, the same supply-chain exposure as CI/CD components (ISSUE-414). An untrusted function source lets an attacker-controlled namespace execute code inside the pipeline's trust boundary.

🔧 How to fix

Reference functions only from a trusted source: add the source to trustedFunctions, or rely on trustSameGroupFunctions if it already lives in your own namespace.

✗ BeforeFunction pulled from an untrusted external namespace
build:
run:
- name: say_hi
func: registry.gitlab.com/attacker/evil/backdoor:1
✓ AfterFunction trusted: lives under the project's own namespace
build:
run:
- name: say_hi
func: registry.gitlab.com/my-group/my-project/echo:1
inputs:
message: "Hi Sally!"

💡 Tips

  • trustSameGroupFunctions (default true) trusts functions under the project's own root namespace, hosted on the scanned instance's container registry (the supported OCI form, e.g. registry.gitlab.com) or its web host (the deprecated git form).
  • trustedFunctions is empty by default. The runner does not expand $VAR in a func: reference, so list literal hosts and paths. A pattern that references a $CI_* variable is rejected when the pipeline redefines that variable: globally, on the job, or through extends:.
  • The structured forms are checked like their string equivalents: func: {git: {url, rev, dir, file}} as url/-/dir/file@rev, and func: {oci: {registry, repository, tag}} as registry/repository:tag. A func: value Plumber cannot read is reported, never skipped.
  • Hosts and namespaces compare case-insensitively, and a reference with a . or .. path segment is never trusted.
  • A deprecated reference form (step: instead of func:, or a deprecated git-repository ref) is tracked separately as a terminal stat — it does not by itself trigger this control.
  • Local (filesystem-path) function references and GitLab built-in functions (builtin://...) are always out of scope.

⚙️ Configure this control

With the CLI alone: set it in your configuration file. Every field and default is in the controls configuration reference, CTRL-415.