docs: add Pipeline Policy Constraints with Tekton and Kyverno solution - #830
docs: add Pipeline Policy Constraints with Tekton and Kyverno solution#830l-qing wants to merge 1 commit into
Conversation
afe55c1 to
99586ca
Compare
Add a Solution-kind article at docs/en/solutions/Pipeline_Policy_Constraints_with_Tekton_and_Kyverno.md covering admission-time policy constraints for Tekton pipelines with Kyverno on ACP: template/Task identity locking, gate-parameter effective-value validation, source/target restrictions, result-driven cancellation, scoped exemptions (PolicyException), and rollout/upgrade operations. Verified against ACP 4.3 with Alauda DevOps Pipelines v4.14.x, Kyverno v1.15.9-v4.3.2, and Alauda Artifact Hub Shim v1.0.0; every code block was validated on a live cluster. ProductsVersion is anchored to 4.3.x; the id frontmatter field is left for the add_id.sh flow to assign. Note: the document deliberately ships a fake, format-valid Slack token as the fixture for the trivy secret-scanning demonstration; it must stay format-valid for trivy to detect it.
99586ca to
2eb6d9c
Compare
yuzichen12123
left a comment
There was a problem hiding this comment.
本次结合 DEVOPS-43870 及其关联文档单 DEVOPS-43674 的验收标准完成审查,共提交 4 条行级评论:2 个 Major、2 个 Minor。重点是修正文档对 mutate-existing 故障语义的安全承诺,并补齐可直接执行、可重复验证的 probe 与测试证据。指定验收环境当前持续返回 EOF,待问题修复且环境恢复后,应补做目标版本的故障注入与完整正/负回归。
|
|
||
| | What to budget | Mechanism facts | The budget / action you must set | | ||
| |---|---|---| | ||
| | **External calls on the admission path** | Two kinds of criteria wait for an external round trip inside admission: `context.imageRegistry` ([§4.5.2](#s4-5-2)) and `context.apiCall` (one each in [§4.2.1](#s4-2-1) / [§4.2.2](#s4-2-2) / [§4.6.1](#s4-6-1) — three in the whole document). **Both fail closed**: registry unreachable → request denied (measured at roughly 5 seconds; roughly 3 seconds when reachable, see limitation 4 in [§4.5.2](#s4-5-2)); apiCall cannot fetch its target → the rule errors out and the request is denied (the error message shape is in the [§4.2.1](#s4-2-1) warning) | Decide explicitly "which request paths may carry external calls"; narrow such rules' match down to **the Tasks that genuinely need them**; load-test p95 / p99 and the timeout ratio, and confirm it stays below the webhook timeout — **that ceiling applies to the whole request, not to each rule separately** (measured `timeoutSeconds=10` in this document's verification environment, see checklist item 6 in [§3.1](#s3-1); one 5-second registry round trip fits, two stacked on the same request may not). **Registry / API server jitter turns directly into pipeline creation failures** — have the matching alerts and playbooks ready | |
There was a problem hiding this comment.
Major|mutate-existing 的 apiCall 故障语义被误写为 fail-closed
这里把 §4.2.1、§4.2.2、§4.6.1 的三个 context.apiCall 一概描述成“查询失败时 rule error,原请求被拒绝”。这只适用于同步 validate 路径,不能套用到 mutate-existing。
Kyverno 1.15 上游实现中,mutate-existing 由 handleBackgroundApplies 异步处理,并且只为 RuleStatusPass 创建 UpdateRequest;context/precondition 得到 RuleStatusError 时不会进入 admission 的 BlockRequest。因此 §4.2.2/§4.6.1 查询父 PipelineRun 失败时,原 TaskRun CREATE 或 status UPDATE 仍可能被接受,但预期的 CancelledRunFinally 补丁不会产生。此时是 fail-open,流水线可能继续执行。
修复目标:
- 分开描述同步 validate(§4.2.1)与异步 mutate-existing(§4.2.2/§4.6.1)的错误语义,不再使用统一的 “Both fail closed”。
- 明确 mutate-existing 在
apiCall、规则求值或UpdateRequest创建失败时不会完成取消,并补充 UpdateRequest、background-controller event/error 的监控与告警要求。 - 说明需要零竞态硬保证时应使用同步 validate/admission-mutate,而不能把异步取消当作硬门禁。
- 在目标 Kyverno v1.15.9-v4.3.2 环境补一条受控故障用例:制造父对象查询失败,验证原请求、取消补丁和告警三者的实际结果,并据此更新文字。
There was a problem hiding this comment.
补充目标环境实测证据(2026-08-11,Tekton Pipelines v1.12.2,Kyverno v1.15.9-v4.3.2):
- 正常对照组:mutate-existing 规则的
context.apiCall查询当前真实 PipelineRun,并校验返回 UID;PipelineRun 正常完成,目标注解成功写入,证明规则、RBAC 和 background mutation 路径本身可用。 - 故障注入组:保持 match、subject、target、RBAC 和触发方式不变,仅将
apiCall指向同命名空间内一个确定不存在的 PipelineRun。结果是原 PipelineRun 的 status UPDATE 未被拒绝,最终状态为Succeeded;预期 mutation 注解未写入;查询时没有保留该策略对应的 UpdateRequest,admission/background controller 日志中也没有观察到包含该测试策略名的错误记录。 - 因此差异可以归因于
apiCall故障:在 mutate-existing 路径中,实际行为是“原请求继续、mutation 消失”,不是本行描述的 fail-closed。且本次未自然产生可操作告警,文档还需明确补充监控手段,不能只要求查看 background-controller event/error。
这也进一步确认修复目标 1–4 均为必须项,尤其应把“异步取消失败”作为显式验收用例。
|
|
||
| Later sections supply probes in one of two ways: some give complete manifests and commands directly ([§3.3](#s3-3), [§4.4.1](#s4-4-1), [§4.4.2](#s4-4-2), [§4.6.1](#s4-6-1)); the others give only an **expectation table** (listing which inputs should be allowed / denied / skipped) and leave the commands to this section — because these three kinds of commands are mechanical, and repeating them section by section would make the document longer, not clearer. | ||
|
|
||
| **Eight sections give only an expectation table and need you to turn it into commands yourself**: [§4.1.1](#s4-1-1), [§4.2.4](#s4-2-4), [§4.5.1](#s4-5-1), [§4.5.3](#s4-5-3), [§4.5.4](#s4-5-4), [§4.5.5](#s4-5-5), [§5.2](#s5-2), [§5.3](#s5-3). (The method behind this list is "the section has an expectation table but no `kubectl create` that submits a probe" — after the document changes, recount by that method instead of trusting the list. The `kubectl apply` commands already present in [§4.5.3](#s4-5-3), [§5.2](#s5-2), [§5.3](#s5-3) create **prerequisite objects** (ConfigMaps, namespaces), not the probes themselves.) In addition, [§4.1.4](#s4-1-4) and [§4.1.5](#s4-1-5) have no expectation table: they are Audit defense in depth on `*/status`, their criteria are stated in the body, and the expected shape is "which fail entry should appear in the report" — follow **type 2** below. |
There was a problem hiding this comment.
Major|缺少可直接执行的 probe 和可复核的 731 条断言产物
本节明确说明有 8 个章节只有 expectation table,需要读者自行选择 skeleton、编辑字段并生成 probe.yaml。受影响的章节包括 §4.1.1、§4.2.4、§4.5.1、§4.5.3、§4.5.4、§4.5.5、§5.2、§5.3。这与前文对 walkthrough operator 的 “Every step copy-pasteable” 承诺以及 Jira 的“所有示例 YAML 可直接执行并验证通过”验收标准不一致。
另外,PR 描述声称已完成 731 条 live assertions,但当前变更只包含 Markdown,没有提交或链接脱敏后的 harness、输入版本、执行日志/结果摘要以及“策略/探针 → 断言”映射。现有 GitHub build 只能证明站点可以构建,不能证明策略行为和清理流程已经回归。
修复目标:
- 为上述 8 个章节补齐完整的正/负 probe manifest,可集中成多文档 YAML,但必须能在替换环境参数后直接提交。
- 每个 probe 提供实际执行命令、机器可判定的预期结果和清理命令,避免依赖读者自行解释输出。
- 将脱敏后的测试 harness 纳入仓库,或提供稳定、可访问的结果产物;记录 ACP、Pipelines、Kyverno、Artifact Hub Shim 的精确版本。
- 建立每个完整策略及 probe 到断言结果的映射,使升级后可以重复回归。若本次只计划交付设计矩阵,则应删除 copy-paste/已全部验证的承诺,并同步调整验收范围。
|
|
||
| **The key criterion** — each of the three channels locks the complete identity, and a false union is a denial: | ||
|
|
||
| ```yaml |
There was a problem hiding this comment.
Minor|这些 yaml fence 是非完整片段,无法独立解析
这里及另外 9 处 “Key criterion” 代码块只截取了嵌套字段,缺少外围对象。逐块运行 yq eval 时共有 10/69 个 yaml fence 解析失败,起始行分别为 2140、2434、2637、2886、3577、4413、5337、5564、6052、7675。后续完整策略 YAML 可以解析,因此这不是策略本体错误,但当前语言标记容易让读者和自动化把它们当成可复制的 YAML 示例,也与“所有示例 YAML 可直接执行”的表述冲突。
修复目标:
- 如果只用于解释逻辑,将这 10 个 fence 改为
text,并在标题或块前明确标注non-executable YAML fragment。 - 如果希望保留
yaml,则补齐到可独立解析的最小对象。 - 修复后以“所有标为
yaml的 fence 均能逐块通过 YAML 解析”作为验收条件。
|
|
||
| Requiring merely that "a task named `scan` exists in the inline definition" is an **insufficient** security check — an attacker can drop in a hollow no-op scanner, hang a never-true `when` on it so it gets skipped, set the gate switch to `false`, or order release before it / parallel to it. | ||
|
|
||
| To open up inlining safely, you must validate the complete contract set of [§2.3](#s2-3) (scanner identity, effective values of the gate switches, must-run, DAG d |
There was a problem hiding this comment.
Minor|4.14 安装链接当前跳转到了 4.12 首页
当前 https://docs.alauda.io/alauda-devops-pipelines/4.14/install.html 返回的 HTML 使用 meta refresh 跳转到 /alauda-devops-pipelines/4.12/,并且丢失了 install.html 路径。读者按这里查找 4.14 的安装和 TektonConfig 说明时,实际看到的是错误版本、错误页面,无法核对本文声明的 4.14 前提。
修复目标:
- 替换为实际存在的 4.14 安装/
TektonConfig文档地址。 - 如果 4.14 文档尚未发布,明确说明临时引用的版本、与 4.14 的差异及后续替换条件,不能把 4.12 首页标成 4.14 安装页。
- 验收时检查最终页面内容与版本,而不只检查 HTTP 200;当前页面虽然返回 200,但正文会继续重定向。
| kubectl get cm -n "$TEKTON_NS" resolvers-feature-flags -o jsonpath='{.data}{"\n"}' | ||
| # Expect enable-cluster-resolver / enable-hub-resolver / enable-git-resolver to be | ||
| # "true" as required by the resolvers you actually use | ||
| echo "hub default-type: $(kubectl get cm -n "$TEKTON_NS" hubresolver-config -o jsonpath='{.data.default-type}')" |
There was a problem hiding this comment.
Major|Hub 检查会误报就绪,文档中的官方模板在验收环境实际无法解析
在提供的 /root/config/kb.yaml 环境实测:
enable-hub-resolver=true,本行读取的default-type=artifact,因此当前检查会判定 Hub 能力正常;- 按文档完整坐标创建
java-image-build-scan-deploy@0.3和python-image-build-scan-deploy@0.3的真实 PipelineRun,二者均终止为CouldntGetPipeline,resolver 请求返回 404,status.pipelineSpec未生成;显式type=artifact也不会改变这个 endpoint; - 同一集群内置 Artifact Hub Shim 对这两个 Pipeline 以及
sonarqube-scanner@0.7、trivy-scanner@0.6、skopeo-copy@0.1的精确坐标均返回 200,解析 manifest 后参数、结果和 DAG 合约也与 §3.2 矩阵一致。问题是当前 resolver 配置的 endpoint 没有实际提供这套内置 catalog,而现有检查完全发现不了。
这会使所有依赖真实 Hub profile 的示例在 walkthrough 开始很久以后才以解析失败结束,用户容易误判为策略问题,也不满足“示例可直接执行验证”的验收目标。
修复目标:
- 这里不能只检查 feature flag 和
default-type;增加对当前配置的 artifact-hub-api endpoint 的真实 smoke test,至少验证本文固定使用的五个catalog/name/version/kind坐标可解析。 - 提供可复制命令并机器判定:官方 Pipeline 应生成
status.pipelineSpec,Task 应生成已解析 spec;404、认证失败或 endpoint 不一致必须在进入 Cookbook 前明确失败。 - 明确“内置 Shim”与 resolver 实际配置 endpoint 的关系;若验收环境配置漂移,应先修复环境再宣称本文 live assertions 通过。
- 把该 smoke test 纳入可重复 harness,避免仅验证 Shim 自身“有包”,却漏掉 resolver 实际“取不到包”的链路断点。
What
Adds a Solution-kind article:
docs/en/solutions/Pipeline_Policy_Constraints_with_Tekton_and_Kyverno.mdIt covers admission-time policy constraints for Tekton pipelines with Kyverno on ACP: template/Task identity locking, gate-parameter effective-value validation, source/target restrictions, result-driven cancellation, scoped exemptions (PolicyException), and rollout/upgrade operations.
Version anchoring
Verified against ACP 4.3 with Alauda DevOps Pipelines v4.14.x, Kyverno v1.15.9-v4.3.2, and Alauda Artifact Hub Shim v1.0.0; the applicability matrix is declared in the document front section,
ProductsVersion: 4.3.xin the frontmatter.How this was verified
Rather than reviewed on paper, the material was executed against a live ACP 4.3 cluster:
CreateRunFailednaming the policy, the approved exemption makes the identical run succeed, the same config in a normal namespace still fails, and deleting the exemption restores the refusal.Known environment dependency worth calling out for reviewers: the Hub coordinates used in §4.2.4/§4.5.1 resolve through the cluster's in-cluster Artifact Hub Shim. On a cluster whose
hubresolver-configstill points at the publicartifacthub.io, those references cannot resolve; the endpoint is set throughTektonConfig.spec.pipeline.hub-resolver-config(the ConfigMap itself is operator-owned).Notes for reviewers
Software_Supply_Chain_Security_of_Alauda_Container_Platform_with_Tekton_and_Kyverno.mdis referenced as a same-directory relative link; it exists in the en tree.idfrontmatter field is left for the add_id.sh flow to assign.scanners=[secret]demonstration in §4.4 and must stay format-valid for trivy to detect it. Push protection was resolved via the used-in-tests allowance.