File Reference

# Background

Pipeline configuration files can reference other files for pipeline configuration, environment variables, task parameters, etc.

Sensitive information may exist in the files, so it is necessary to perform permission checks on file references to avoid leakage of sensitive information.

# Reference Methods

There are four ways to reference configuration files in CNB:

Note:

To facilitate flexible configuration of pipeline task parameters, the file paths declared by imports, optionsFrom, and settingsFrom support the use of environment variables.

You can declare environment variables in the pipeline in advance and then reference them in the task, such as:

main:
  push:
    - env:
        CNB_CONFIG_URL: https://xxx.com/p1/xxx
        CNB_CONFIG_FILE: account.yml
      imports:
        # Assume env1.yml declares variable CNB_ENV_FILE_URL
        - https://xxx.com/p1/xxx/env1.yml
        # The file path after imports supports using the environment variables declared in the previous file
        - ${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}

At the same time, optionsFrom and settingsFrom support reading local files, even if there is no ./path/to/file in the repository, but you can write this file in the pipeline and load it when the pipeline is executed, such as:

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 a file generated by the pipeline but not in the repository
            - ./path/to/file-not-in-git
        - name: Plugin task
          image: some-image
          settingsFrom:
            # Reference a file that exists in the repository
            - ./path/to/file-in-git

# File Types

In CNB, the configuration files that can be referenced are divided into three types:

# YAML Files

The file extension is .yml or .yaml, such as:

account.yml

SOME_ACCOUNT: some-account
SOME_PASSWORD: some-password

# JSON Files

The file extension is .json, such as:

account.json

{
  "SOME_ACCOUNT": "some-account",
  "SOME_PASSWORD": "some-password"
}

# Text Files

Files that are not of the above two types will be parsed as text files, such as:

account.txt

SOME_ACCOUNT=some-account
SOME_PASSWORD=some-password

# Permission Check

Configuration files can declare three fields: allow_images, allow_events, allow_slugs to control the accessible range. All three fields are glob pattern strings or arrays of strings.

The flowchart of CNB's permission check on whether the pipeline can load the target file is as follows:

Explanation of the above flowchart:

  • Same Repo: The pipeline and the target file belong to the same repository.
  • Pull Request Event: In PR, especially when a fork repository submits a PR, the source branch code has not been reviewed by the administrator and is not trustworthy. For security reasons, the configuration file must have allow_events configured to be referenced by the pull_request pipeline.
  • Plugin Task:
    • Parameters can be set through settingsFrom or imported through imports and then set via environment variables. Both methods are considered as plugin tasks referencing files.
    • When the image name does not carry a tag, it will match allow_images with both image name and image name:latest. If either matches, it is considered a pass.
    • Note: When a job has both the image and script properties set, it is considered a script task. The image property is used as the execution environment. In this scenario, the image is treated as an empty string and cannot match **.

# Examples

# Pipeline Template Reference

# Referenced configuration file template.yml
allow_slugs:
  - "p1/**"
main:
  push:
    - stages:
        - name: echo
          script: echo 1
# Pipeline configuration file .cnb.yml
include:
  - https://xxx.com/p1/xxx/-/blob/main/template.yml

The pipeline configuration file references another configuration file template.yml in a private repository. The pipeline trigger does not have pull permission for it, but the referenced file declares allow_slugs specifying p1/**. If the pipeline repository is under the organization p1, the slug check passes, otherwise it does not.

This prevents the pipeline template file from being maliciously modified while still being referenced by the pipeline of the repository under a specific organization.

# Plugin Task Parameter Reference

# Referenced configuration file
allow_images:
  - "registry.com/image1/**"
allow_slugs:
  - "p1/**"
arg1: arg1
arg2: arg2
# Configuration file Plugin task
name: image job
image: registry.com/image1/print:latest
settingsFrom:
  - xxx.com/xxx/image-settings.yml

image: registry.com/image1/print:latest matches registry.com/image1/**, so the image check passes.

allow_slugs specifies p1/**. If the pipeline repository is under the organization p1, the slug check passes, otherwise it does not.

This restricts the configuration file to be used only in the plugin tasks of the pipeline in the repository under a specific organization with a specific image name, preventing the leakage of sensitive information.

# Limit Events

A common scenario is to deploy a project when clicking the deploy button on the repository tag list page or publish to npm, docker hub in tag_push events.

To protect sensitive information, you can configure sensitive information such as password, token in files of other private repositories.

To prevent developers from arbitrarily deploying projects or publishing to npm, docker hub in push events, you can declare the allow_events field in the configuration file, allowing it to be referenced only in tag_deploy.*, tag_push events.

allow_events:
  - tag_push
  - tag_deploy.*

SOME_ACCOUNT: some-account
SOME_PASSWORD: some-password