简明目的
先在“没有写权限”的环境里拉取并检查上游代码,审核通过后才由另一个短时授权步骤推送,避免恶意上游代码偷走仓库权限。
验收改写(owner 2026-09-17 裁决)
Outcome(专业定义)
upstream sync 被拆为两个信任域:只读 candidate workflow 检出/恢复/构建/检查并产出不可变 diff evidence;独立 privileged push workflow 只消费已批准 candidate digest,使用短生命周期 GitHub App token,在所有 guard/smoke 通过后推送。Alpha-owned path guard 覆盖 added/modified/deleted/renamed 全部变化并对恶意 fixture fail closed。
Complexity
L — CI 供应链、仓库写权限和不可信代码执行属于高风险安全面。
Context
当前 workflow 可能在持久 push credential 存在时执行未审查上游代码,并在 smoke 前推送;guard 还可能漏掉 added files。仅设置 persist-credentials: false 不足以隔离 job-level secret/permissions。
Scope
- 只读 candidate job 使用最小
contents: read,无 push secret、无持久凭据。
- 禁止/约束 install hooks 与不可信构建副作用,产出可审核 diff/metadata/digest。
- 人工/策略批准后由独立 workflow 获取短时 GitHub App token。
- push 前重新验证 candidate digest、ownership guard、恢复结果和 required smoke。
- guard 覆盖 Alpha-owned/upstream-owned paths 的 A/M/D/R 与文件类型边界。
- 用恶意 upstream fixture 证明 secret、workflow 与 guard 隔离。
Non-goals
- 不自动批准或自动 push 任意 upstream candidate。
- 不在 candidate job 暴露 PAT、长期 App key、environment secret 或 write permission。
- 不保留旧单 job push-before-smoke 流程作为兼容路径。
- 不以文本 diff 人工目测替代机器 guard/digest identity。
Acceptance criteria
AC1. 未审查上游代码只在无仓库写 secret/permission 且 checkout 不持久凭据的 candidate job 中执行。
AC2. candidate 输出包含 base/head、完整 diff、文件状态、检查结果与不可变 digest,可供独立审核。
AC3. 推送是独立工作流,只在候选工作流成功后运行,不执行上游代码;推送凭据只在推送步骤配置,推送的提交哈希必须等于候选产物清单。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC4. ownership guard、restore、生成检查与 required smoke 全部在 push 前通过;失败不会更新目标 branch。
AC5. 上游路径下的修改、删除、改名由 north-star 守卫拦截;新增文件按 ADR-035/038 放行。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC6. 恶意 workflow/package/install fixture 不能读取 push credential、修改批准 artifact 或绕过 guard。 —— 2026-09-17 删除(owner 裁决):演练要先造演练装置,而「上游代码偷推送权限」已由两段工作流结构性隔离。
AC7. 审批、candidate digest、token subject、检查与 push 结果可审计,但日志不含 token/secret。
Evidence map
| AC |
Evidence surface |
| AC1 |
candidate workflow permission/credential audit |
| AC2 |
immutable candidate artifact/digest tests |
| AC3 |
.github/workflows/sync-upstream-push.yml(workflow_run + conclusion == 'success'、解包哈希核对清单、推送凭据只在推送步骤配置)(2026-09-17 同步) |
| AC4 |
push-order workflow test + required-smoke negative fixture |
| AC5 |
scripts/north-star-guard.sh(--no-renames --diff-filter=DMR)+ packages/ui-mac/src/main/north-star-guard.test.ts(新增文件不点名)(2026-09-17 同步) |
| AC6 |
建议 VERIFY:malicious upstream workflow/install-hook matrix —— 2026-09-17 删除 |
| AC7 |
redacted supply-chain audit record |
Acceptance owner
@jinjunnn(owner 2026-09-17 裁决按证据验收)(2026-09-17 订正,原为「待指定」)
设计要点
- 两阶段必须是独立 job/workflow 信任域,不只是同一 shell script 的两个步骤。
- privileged workflow 不重新执行 candidate 中的不可信 install/build 脚本。
- approval 绑定 exact digest/commit;重新生成候选会使旧批准失效。
- checkout、artifact download 与 push 都做 provenance 校验。
潜在问题与风险
- job-level write permission 即使 checkout 不持久凭据仍可能被不可信代码滥用。
- push-before-smoke 会把失败候选写入目标 branch。
- 只检查 modified/deleted 会允许新增文件覆盖 Alpha-owned 行为。
- privileged 阶段重新构建会引入 TOCTOU,推送的内容可能不是审核对象。
过时性与兼容性结论
需求有效且未完成。旧单 workflow、长期 credential、push-before-smoke 与不完整 guard 不做兼容,直接替换。保留批准/digest 绑定、失败重试、最小权限与审计正确性。
关联与职责边界
Delivery plan / 建议子票
Dependencies
- 需要可用的 GitHub App 最小权限配置与审核人/策略 owner。
- 未指定 acceptance owner 前不得进入 Ready。
简明目的
先在“没有写权限”的环境里拉取并检查上游代码,审核通过后才由另一个短时授权步骤推送,避免恶意上游代码偷走仓库权限。
验收改写(owner 2026-09-17 裁决)
Outcome(专业定义)
upstream sync 被拆为两个信任域:只读 candidate workflow 检出/恢复/构建/检查并产出不可变 diff evidence;独立 privileged push workflow 只消费已批准 candidate digest,使用短生命周期 GitHub App token,在所有 guard/smoke 通过后推送。Alpha-owned path guard 覆盖 added/modified/deleted/renamed 全部变化并对恶意 fixture fail closed。
Complexity
L — CI 供应链、仓库写权限和不可信代码执行属于高风险安全面。
Context
当前 workflow 可能在持久 push credential 存在时执行未审查上游代码,并在 smoke 前推送;guard 还可能漏掉 added files。仅设置
persist-credentials: false不足以隔离 job-level secret/permissions。Scope
contents: read,无 push secret、无持久凭据。Non-goals
Acceptance criteria
AC1. 未审查上游代码只在无仓库写 secret/permission 且 checkout 不持久凭据的 candidate job 中执行。
AC2. candidate 输出包含 base/head、完整 diff、文件状态、检查结果与不可变 digest,可供独立审核。
AC3. 推送是独立工作流,只在候选工作流成功后运行,不执行上游代码;推送凭据只在推送步骤配置,推送的提交哈希必须等于候选产物清单。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC4. ownership guard、restore、生成检查与 required smoke 全部在 push 前通过;失败不会更新目标 branch。
AC5. 上游路径下的修改、删除、改名由 north-star 守卫拦截;新增文件按 ADR-035/038 放行。 (2026-09-17 按 owner 裁决改写,原文见编辑历史)
AC6.
恶意 workflow/package/install fixture 不能读取 push credential、修改批准 artifact 或绕过 guard。—— 2026-09-17 删除(owner 裁决):演练要先造演练装置,而「上游代码偷推送权限」已由两段工作流结构性隔离。AC7. 审批、candidate digest、token subject、检查与 push 结果可审计,但日志不含 token/secret。
Evidence map
.github/workflows/sync-upstream-push.yml(workflow_run+conclusion == 'success'、解包哈希核对清单、推送凭据只在推送步骤配置)(2026-09-17 同步)scripts/north-star-guard.sh(--no-renames --diff-filter=DMR)+packages/ui-mac/src/main/north-star-guard.test.ts(新增文件不点名)(2026-09-17 同步)建议 VERIFY:malicious upstream workflow/install-hook matrix—— 2026-09-17 删除Acceptance owner
@jinjunnn(owner 2026-09-17 裁决按证据验收)(2026-09-17 订正,原为「待指定」)
设计要点
潜在问题与风险
过时性与兼容性结论
需求有效且未完成。旧单 workflow、长期 credential、push-before-smoke 与不完整 guard 不做兼容,直接替换。保留批准/digest 绑定、失败重试、最小权限与审计正确性。
关联与职责边界
Delivery plan / 建议子票
Dependencies