Skip to content

[#899][SEC] Split sync-upstream: read-only candidate vs privileged push - #1060

Merged
jinjunnn merged 1 commit into
alphafrom
ready-899-kanpo-impl
Aug 22, 2026
Merged

jinjunnn merged 1 commit into
alphafrom
ready-899-kanpo-impl

Conversation

@jinjunnn

Copy link
Copy Markdown
Owner

Summary

Split upstream sync so untrusted upstream code does not share a job with push credentials.

Fixes #899

Test plan

  • Local verification per Claude
  • Outer verify + merge (SEC / CI)

Made with Cursor

The daily upstream fork-sync ran as a single job that held a repo-push
credential (secrets.SYNC_TOKEN, persisted via actions/checkout without
persist-credentials: false) for its entire duration while running code
fetched from the untrusted anomalyco/opencode tree (bun install lifecycle
scripts, then booting the merged engine for the smoke test). A compromised
upstream commit could read that credential out of .git/config.

Split into two trust domains:

- sync-upstream.yml (candidate): permissions: contents: read, zero
  references to secrets.SYNC_TOKEN, persist-credentials: false on its
  checkout. Fetches upstream, merges dev into alpha, runs every existing
  guard/tripwire and the engine smoke test, and — only on success —
  packages the resulting dev/alpha commits into an immutable git-bundle
  artifact. It never pushes anything.

- sync-upstream-push.yml (push, new): permissions: contents: write,
  triggered by workflow_run only when the candidate reports success.
  Downloads the bundle, verifies it (exact commit-sha match against the
  candidate's manifest, non-force push), configures the push credential
  only for the final step, and pushes. It never executes any code from
  the merged tree, so the push token is never in the same process as
  code sourced from upstream.

Side effect (matches the issue's "push only after guard/smoke pass"
requirement): previously the merge step pushed to alpha *before* the
frontend anchor tripwire and the engine smoke test ran, so a smoke
failure only reported after the fact. Now a failed smoke test blocks
artifact production entirely, so nothing reaches the push workflow.

Verified locally: YAML parses, every `run:` block passes `bash -n`,
scripts/north-star-guard.sh and scripts/assert-no-nul-bytes.py pass,
scripts/check-doc-links.py passes on the edited docs, and
packages/ui-mac/src/main/frontend-patch-roundtrip.test.ts (which pins
the exact `rm -rf packages/app packages/ui` line in this file) still
passes 15/15. Also hand-verified the bundle create/fetch/push mechanics
end-to-end against a throwaway git repo before writing the workflow YAML.

Out of scope per the issue: does not touch alpha-ci.yml's upstream-guard
job or its change-type coverage, and does not change sync frequency or
upstream selection strategy.

Fixes #899

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015BNKogUjFuCri3Ri6BDGkZ
@jinjunnn
jinjunnn marked this pull request as ready for review August 22, 2026 04:45
@jinjunnn
jinjunnn merged commit d6a76b0 into alpha Aug 22, 2026
5 of 6 checks passed
@jinjunnn
jinjunnn deleted the ready-899-kanpo-impl branch August 22, 2026 04:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SEC][BUG][P1] 上游同步在同一 job 里既跑不可信上游代码又持有推送凭据

1 participant