File References
About 1184 wordsAbout 4 min
Background
Pipeline configuration files can reference other files for pipeline configuration, environment variables, task parameters, etc.
Since files may contain sensitive information, permission checks are needed for file references to prevent information leakage.
Reference Methods
CNB supports four types of configuration file references:
- Pipeline template reference: include
- Environment variable reference: imports
- Built-in task parameter reference: optionsFrom
- Plugin task parameter reference: settingsFrom
Note:
For flexible pipeline task parameter configuration, file paths declared in imports
, optionsFrom
and settingsFrom
support environment variables.
You can declare environment variables in the pipeline first, then reference them in tasks, like:
main:
push:
- env:
CNB_CONFIG_URL: cnb.cool/<your-repo-slug>/-/blob/main/xxx
CNB_CONFIG_FILE: account.yml
imports:
# Assume env1.yml declares variable CNB_ENV_FILE_URL
- cnb.cool/<your-repo-slug>/-/blob/main/xxx/env1.yml
# File paths after imports can use variables declared in previous files
- ${CNB_ENV_FILE_URL}/env2.yml
stages:
- name: echo
script: echo 1
- name: Built-in task
type: some-type
optionsFrom:
- ${CNB_CONFIG_URL}/${CNB_CONFIG_FILE}
- name: Plugin task
image: some-image
settingsFrom:
- ${CNB_CONFIG_URL}/${CNB_CONFIG_FILE}
Additionally, optionsFrom
and settingsFrom
support reading local files. Even if ./path/to/file
doesn't exist in the repository, you can write it in the pipeline for loading during execution, like:
main:
push:
- env:
CNB_CONFIG_URL: https://xxx.com/p1/xxx
CNB_CONFIG_FILE: account.yml
stages:
- name: echo
script: echo some-content > ./path/to/file-not-in-git
- name: Built-in task
type: some-type
optionsFrom:
# Reference file generated by pipeline but not in git
- ./path/to/file-not-in-git
- name: Plugin task
image: some-image
settingsFrom:
# Reference file existing in git
- ./path/to/file-in-git
File Types
In CNB, three types of configuration files are supported for reference:
YAML Files
Files with .yml
or .yaml
extension, like:
account.yml
SOME_ACCOUNT: some-account
SOME_PASSWORD: some-password
JSON Files
Files with .json
extension, like:
account.json
{
"SOME_ACCOUNT": "some-account",
"SOME_PASSWORD": "some-password"
}
Text Files
Files not of the above two types are parsed as text files, like:
account.txt
SOME_ACCOUNT=some-account
SOME_PASSWORD=some-password
Permission Checks
Configuration files from public or same-source repositories can be referenced directly by pipelines.
For configuration files from private and different-source repositories, four fields can be declared to control access scope: allow_images
, allow_events
, allow_slugs
, allow_branches
. Each field can be a glob pattern string or string array.
If these fields are not declared, the system will check if the pipeline trigger has read permission for the repository containing the configuration file.
The permission check flow for whether a pipeline can load target files is shown below:
Overall flow:
Flow explanation:
- Same source: Pipeline and target file belong to same repository
- Allow check: Declared allow fields checked sequentially, all must pass
- File read permission: Pipeline trigger has read permission for referenced file's repository, see Role Permissions
Allow necessity check explanation:
- "Pull request" events include
pull_request
andpull_request.update
events - In PRs, especially from forked repos, source branch code is untrusted without admin review. For security, config files must have
allow_events
for pull_request pipelines - Pipelines can use third-party plugins. For security, config files must declare
allow_images
for plugin tasks
Branch checked in allow_branches
is same as CNB_BRANCH.
Image check notes:
- Plugin task parameters can be set via
settingsFrom
or imported as env vars viaimports
. Both count as plugin task file references - When image name has no tag, both
name
andname:latest
are matched againstallow_images
. Match either passes - Non-plugin task image is empty string, can't match any glob pattern. Config files with
allow_images
can't be referenced by non-plugin tasks - Note: Jobs with both image and script are script tasks using image as execution environment
- Syntactically pipelines can declare image as build environment but not as plugin task. Config files with
allow_images
can't be referenced at pipeline level
Examples
Pipeline Template Reference
# Referenced config file template.yml
allow_slugs:
- "p1/**"
main:
push:
- stages:
- name: echo
script: echo 1
# Pipeline config file .cnb.yml
include:
- cnb.cool/<your-repo-slug>/-/blob/main/xxx/template.yml
Pipeline config references template.yml
from another private repo. Pipeline trigger lacks pull permission, but referenced file declares allow_slugs: "p1/**"
. Pipeline repo under org p1
passes slug check, otherwise fails.
This prevents malicious template modification while allowing reference by specific org repos.
Plugin Task Parameter Reference
# Referenced config file
allow_images:
- "registry.com/image1/**"
allow_slugs:
- "p1/**"
arg1: arg1
arg2: arg2
# Config file plugin task
name: image job
image: registry.com/image1/print:latest
settingsFrom:
- cnb.cool/<your-repo-slug>/-/blob/main/xxx/image-settings.yml
image: registry.com/image1/print:latest
matches registry.com/image1/**
, image check passes.
allow_slugs
specifies p1/**
, pipeline repo under org p1
passes slug check, otherwise fails.
This restricts config file use to specific image plugin tasks in specific org repos, preventing sensitive info leaks.
Restricting Events, Branches
A common scenario is publishing to npm/docker hub on main branch push
or tag_push
events.
To protect sensitive info, passwords/tokens can be configured in other private repo files.
To prevent developers from publishing on other branch push
events or printing sensitive info in forked repo pull_request
events,
Declare allow_events
, allow_branches
fields to restrict usage:
allow_events:
- tag_push
- tag_deploy.*
SOME_ACCOUNT: some-account
SOME_PASSWORD: some-password
Or:
allow_events:
- push
allow_branches:
- main
SOME_ACCOUNT: some-account
SOME_PASSWORD: some-password