---
url: /zh/security/config-file.md
description: code_scan_config.yml 配置文件详解，包括文件位置、顶层结构、include 拆分合并规则和 validate 自检。
---
本章介绍配置文件的整体结构、文件位置，以及如何用 `include` 拆分管理。

## 文件位置

| 文件 | 位置 | 必需 |
|---|---|---|
| `code_scan_config.yml` | `<repo-root>/.cnb/security/code_scan_config.yml` | 否 |
| `.scanignore` | 仓库内任意路径（在配置中显式声明） | 否 |
| `include` 子文件 | 仓库内任意路径 | 否 |

未提供 `code_scan_config.yml` 时，平台使用内置默认配置，扫描照常进行。

## 顶层结构

```yaml title=".cnb/security/code_scan_config.yml"
# 0~N 个子文件，按顺序合并
include:
  - <relative path>
  - path: <relative path> # 对象形式，可容忍缺失
    ignoreError: true

# 各能力块（任意子集；未声明的能力沿用平台默认）
secrets:
  # ...
software-composition-analysis:
  # ...
```

每个能力块的形状一致：

```yaml
<capability>:
  scan: # 扫描范围
    ignoreFrom: <path>
    paths:
      - <gitignore pattern>
  rules: # 告警处理规则（Beta）
    - name: <id>
      when:
        # ...
      then:
        # ...
```

> **重要提示**：顶层常用的键是 `include` / `secrets` / `software-composition-analysis`；无法识别的键会被当作错误，请以 `validate` 的校验结果为准。

## include：把配置拆开维护

### 路径解析

**所有 include 路径相对仓库根目录解析**——无论它出现在 `code_scan_config.yml` 还是某个被 include 的子文件中：

```yaml title=".cnb/security/code_scan_config.yml"
include:
  - .cnb/security/checks/secrets.yml
```

```yaml title=".cnb/security/checks/secrets.yml"
include:
  - .cnb/security/checks/secrets-extra.yml # ✅ 仍以仓库根为基准
```

### 容忍可选的子文件

字符串形式下，子文件缺失会报错。若希望"文件存在则加载，不存在则跳过"，使用对象形式并设置 `ignoreError: true`：

```yaml title=".cnb/security/code_scan_config.yml"
include:
  - { path: .cnb/security/checks/local-overrides.yml, ignoreError: true }
```

> **提示**：`ignoreError` 只忽略文件不存在的情况；解析错误、循环引用、路径越界等仍会报错。

### 合并规则

`code_scan_config.yml` 与所有被 include 的子文件最终会合并成一份配置。不同能力之间互不干扰；同一能力下的字段按以下规则合并：

| 字段类型 | 合并行为 |
|---|---|
| 标量（`ignoreFrom`） | 后出现的覆盖前面的 |
| 数组（`paths`、`rules`） | 追加合并，顺序为低→高优先级 |

**优先级（低 → 高）**：

```text
include[0] < include[1] < ... < include[N-1] < 本地 code_scan_config.yml
```

* **本地值覆盖 include**：标量字段若本地与 include 都写了，本地值生效。
* **include 内部的顺序**：较早 include 的优先级更低，后写的覆盖先写的。

> **注意数组的覆盖行为**：数组字段不存在"覆盖"，所有来源的元素按低→高顺序**追加**。这对 gitignore 的取反规则很重要——本地写的 `!pattern` 必须排在 include 值之后才能生效。

#### 示例

```yaml title=".cnb/security/code_scan_config.yml"
# 本地配置，最高优先级
include:
  - .cnb/security/checks/secrets.yml
secrets:
  scan:
    ignoreFrom: .scanignore-local # 本地标量
    paths: ["!keep-local.go"] # 本地数组
```

```yaml title=".cnb/security/checks/secrets.yml"
secrets:
  scan:
    ignoreFrom: .scanignore-included
    paths: ["vendor/**"]
```

合并结果：

```yaml
secrets:
  scan:
    ignoreFrom: .scanignore-local # 本地赢
    paths: ["vendor/**", "!keep-local.go"] # 追加，本地在后
```

### 安全限制

* include 路径必须**相对**且不能逃逸出仓库根目录（不允许 `../..`）。
* 不允许绝对路径、不允许 URL、不支持跨仓库引用。
* 不允许符号链接——即便目标在仓库内也会报错。
* 单次解析最多 **50** 个文件（含递归）。
* 不允许循环 include（`A → B → A` 报错）。

## 用 validate 插件自检

`validate` 用来在提交前确认配置是否正确。退出码 `0` 表示配置合法，非 `0` 表示存在问题（日志中会列出每条问题及其行号）。

### 在 CNB 流水线里调用（推荐）

在仓库的 `.cnb.yml` 里加一个插件任务，PR 阶段就能拦住坏配置：

```yaml title=".cnb.yml"
main:
  pull_request:
    - stages:
        - name: validate code scan config
          image: cnbcool/code-security-config
          args:
            - validate
```

* `args` 会追加到插件镜像的入口命令之后，等价于执行 `code-security-config validate`。
* 默认读取 `.cnb/security/code_scan_config.yml`。
* 配置放在其它位置时，用 `args: [validate, --config, <仓库内相对路径>]` 指定。
* 校验失败时该任务以非 0 退出码结束，流水线随之失败，日志里能看到每条问题及行号。

### 在本地调用

```bash
code-security-config validate                              # 读取 .cnb/security/code_scan_config.yml
code-security-config validate --config path/to/code_scan_config.yml
```

## 下一步

[语法手册](./syntax-reference.md) —— 字段级完整参考。
