---
url: /en/build/file-reference.md
---
## 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](./grammar.md#include)
* Environment variable reference: [imports](./grammar.md#pipeline-imports)
* Built-in task parameter reference: [optionsFrom](./grammar.md#job-optionsfrom)
* Plugin task parameter reference: [settingsFrom](./grammar.md#job-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:

```yaml title=".cnb.yml"
main:
  push:
    - env:
        CNB_CONFIG_URL: https://cnb.share.ralphlauren.cn/<your-repo-slug>/-/blob/main/xxx
        CNB_CONFIG_FILE: account.yml
      imports:
        # Assume env1.yml declares variable CNB_ENV_FILE_URL
        - https://cnb.share.ralphlauren.cn/<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:

```yaml title=".cnb.yml"
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
```

## Permission Checks

For configuration files in public or same-origin repositories, pipelines can reference them directly.

For private and non-origin repositories, you can declare four fields in the configuration file: `allow_slugs`, `allow_events`, `allow_branches`, and `allow_images` to control the access scope. All four fields are in `glob` pattern `strings` (multiple expressions separated by `,` or `|`) or `string arrays`.

For example:

```yaml
# String format, multiple expressions separated by ',' or `;`
allow_slugs: "group/project,some/another-project/feature-*"
# String array
allow_events:
  - push
  - tag_push
  - "tag_deploy.*"
# Only allow specified image.
allow_images: "cnbcool/ssh"
# Allow branches starting with main or feature/
allow_branches:
  - main
  - "feature/*"
```

It is recommended to declare multiple expressions using `string arrays` for better readability. If the configuration file is in a text format that does not support declaring arrays, you can use the string format.

If the above four fields are not declared, it will check if the triggerer of the pipeline is a `developer` or a role higher than that in the repository of the configuration file. If they are, access is granted; otherwise, access is denied.

Where:

* `allow_slugs` specifies which repositories' pipelines are allowed to read the current file.
* `allow_events` specifies under which events pipelines can read the current file. Configurable event names refer to [Trigger Events](./trigger-rule.md#trigger-event).
* `allow_branches` specifies under which branches pipelines can read the current file.
* `allow_images` specifies which image plugins are allowed to read the current file.

The permission check flow for whether a pipeline can load target files is shown below:

Overall flow:

```mermaid
flowchart LR
    subgraph allow checks
      slug-check --> branch-check --> image-check --> event-check
    end
    subgraph allow necessity checks
      allow_events-necessity-check --> allow_images-necessity-check
    end
    start([Start]) --> public-repo{Public repo?}
    public-repo --Yes--> Can-access
    public-repo --No--> same-source{Same-source?}
    same-source --Yes--> Can-access
    same-source --No--> allow-necessity-check[Allow necessity check]
    allow-necessity-check --> necessity-check-passed{Check passed?}
    necessity-check-passed -- Yes --> allow-declared{Allow declared?}
    necessity-check-passed -- No --> Cannot-access
    allow-declared -- No --> has-file-read-permission{File read permission?}
    allow-declared -- Yes --> allow-check[Allow check]
    has-file-read-permission --Yes--> Can-access
    has-file-read-permission --No--> Cannot-access
    allow-check --> allow-check-passed{Check passed?}
    allow-check-passed --Yes--> Can-access
    allow-check-passed --No--> Cannot-access
```

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: See [Role Permissions](../guide/role-permissions.md)

```mermaid
flowchart LR
  strat([Allow necessity check]) --> untrusted-event{Untrusted event?}
    untrusted-event --No--> image-task{Image task?}
    untrusted-event --Yes--> declare-allow_events{Declare allow_events?}
    declare-allow_events --Yes--> image-task{Image task?}
    declare-allow_events --No--> Not-pass
    image-task --No--> Pass
    image-task --Yes--> declare-allow_images{Declare allow_images?}
    declare-allow_images --No--> Not-pass
    declare-allow_images --Yes--> Pass
```

Explanation of Allow Requirement Checks:

1. In [untrusted events](./trigger-rule.md#untrusted-events), the pipeline configuration or the trigger is uncontrollable. For security reasons, the configuration file must include `allow_events` to be referenced by the pipeline triggered by an untrusted event.

2. Pipelines may use third-party plugins. For **security reasons**, the configuration file must declare `allow_images` to be referenced by plugin tasks.

```mermaid
flowchart LR
  strat([Slug check]) --> declare-allow_slugs{Declare allow_slugs?}
  declare-allow_slugs --Yes--> slug-matches-allow_slugs{Slug matches allow_slugs?}
  declare-allow_slugs --No--> Pass
  slug-matches-allow_slugs --Yes--> Pass
  slug-matches-allow_slugs --No--> Not-pass
```

```mermaid
flowchart LR
  strat([Branch check]) --> declare-allow_branches{Declare allow_branches?}
  declare-allow_branches --Yes--> branch-matches-allow_branches{Branch matches allow_branches?}
  declare-allow_branches --No--> Pass
  branch-matches-allow_branches --Yes--> Pass
  branch-matches-allow_branches --No--> Not-pass
```

Branch checked in `allow_branches` is same as [CNB\_BRANCH](./build-in-env.md#CNB_BRANCH).

```mermaid
flowchart LR
  strat([Event check]) --> declare-allow_events{Declare allow_events?}
  declare-allow_events --Yes--> event-matches-allow_events{Event matches allow_events?}
  declare-allow_events --No--> Pass
  event-matches-allow_events --Yes--> Pass
  event-matches-allow_events --No--> Not-pass
```

```mermaid
flowchart LR
  strat([Image check]) --> declare-allow_images{Declare allow_images?}
  declare-allow_images --Yes--> image-matches-allow_images{Image matches allow_images?}
  declare-allow_images --No--> Pass
  image-matches-allow_images --Yes--> Pass
  image-matches-allow_images --No--> Not-pass
```

Image check notes:

* Plugin task parameters can be set via `settingsFrom` or imported as env vars via `imports`. Both count as plugin task file references
* When the image name does not include a tag or includes the `:latest` tag, it will match `allow_images` using both the `image-name` and `image-name:latest`. A match with either one is considered valid.
* 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 Secret File Reference

```yaml
# Configuration file secret.yml in the keystore repository
allow_slugs: "p1/**"
allow_events: push
allow_branches: main
# DockerHub username and password
DOCKER_USER: docker-user
DOCKER_PWD: docker-pwd
```

```yaml title=".cnb.yml"
# Pipeline configuration file .cnb.yml
main:
  push:
    - services:
        - docker
      imports: https://cnb.share.ralphlauren.cn/<your-repo-slug>/-/blob/main/xxx/secret.yml
      stages:
        - name: docker login
          script: |
            # Log in to DockerHub
            docker login -u ${DOCKER_USER} -p "${DOCKER_PWD}"
            # docker build xxx
            # docker push xxx
```

The pipeline references the configuration file `secret.yml` from another keystore repository, but the pipeline triggerer does not have read access to this file.

The referenced file `secret.yml` declares `allow_slugs`, `allow_events`, and `allow_branches`.

If a repository under the `p1` organization triggers a `push` event on the `main` branch, the pipeline can reference this secret file and use the sensitive information within it.

This ensures that only the owner or administrator of the keystore repository can view or modify the sensitive content in `secret.yml`, while still allowing it to be referenced by pipelines that meet the specified conditions.

### Plugin Task Parameter Reference

```yaml
# Configuration file image-settings.yml in the keystore repository
allow_images: "registry.com/image1/**"
allow_slugs: "p1/**"
arg1: arg1
arg2: arg2
```

```yaml
# Pipeline configuration file .cnb.yml configuring a plugin task
name: image job
image: registry.com/image1/print:latest
settingsFrom:
  - https://cnb.share.ralphlauren.cn/<your-repo-slug>/-/blob/main/xxx/image-settings.yml
```

If the image is created by a third party, there may be a risk of information leakage. This can be mitigated by using `allow_images` to restrict the configuration file to only be used by plugin tasks with specific image names that are deemed safe.

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

`allow_slugs` specifies that the configuration file can only be referenced by pipelines of repositories under the `p1` organization, further controlling the scope of the configuration file's usage.
