Policy debate: third-party actions with write-capable tokens — own scripts, fork-and-custody, allowlist, or nothing? #171
Replies: 4 comments
|
Triage frame, so the debate does not wait on the wrong actor. Record verified. I re-read incubator#54: ruling 1 (19:16Z, direct — prefer the battle-tested action) was superseded by ruling 2 (19:27Z, direct — supply-chain posture outranks the complexity concern; own the registry logic, only GitHub-authored actions hold the write token). The body's framing matches the record. Incubator is settled regardless of this thread: ruling 2 is in force there. What is open here is only whether it generalizes, and in what form. Who decides. Fleet doctrine and the org allowed actions setting are org policy — the decision is danmt's (TRIAGE.md outcome 3), and the operator asked for the debate to be had first, not skipped. Process: consumers answer Q1–Q4 here; when the thread converges I assemble the canonical ruling ask on this thread (options, recommendation, blocked/continues) for danmt, and mint the resulting work after the ruling. Two mechanics facts for Q3 (where a policy would live):
Nothing is gated meanwhile. incubator#56 stays blocked by #54 only, and binds to #54's merged shape under ruling 2. If a consumer's Q1 answer turns up a write-scoped third-party action in use today, that is a discussion in that repo, not a hold here. Q1–Q4 are yours: @codex-bot-andresmgsl @grok-bot-andresmgsl @kimi-bot-andresmgsl. |
|
I honestly think we should at least be extremely careful with our dependencies. We can use an action from a large team, still there's a supply chain attack surface but considerably less than one that looks like a scam from the get-go. I don't think we should implement everything but I'd say I rather write code and introduce a security breach |
|
Ruling ask. @danmt's comment narrows this enough to decide — the consumer bots never answered Q1, so their inventories become minted work instead of a precondition. What the comment settles. The blanket rule does not generalize as written: an action "from a large team" is acceptable (smaller supply-chain surface "than one that looks like a scam from the get-go"), we shouldn't "implement everything" ourselves, and the residual lean is toward own code even at the cost of our own bugs. That is a trust-profile rule with an own-code preference — not incubator's GitHub-authored-only blanket, and not "no doctrine." Options: A — trust-profile rule (matches the comment). Concrete text, so a confirm here is the ruling:
Lives in REVIEWER.md + BUILDER.md in the vendored B — generalize incubator's ruling 2 fleet-wide (only C — no fleet doctrine; per-repo calls continue. Leaves the next repo to re-run this debate. Recommendation: A. It encodes your stated judgment as a rule reviewers can apply without re-litigating per PR. On confirm I mint: one ceremony issue (doctrine text into the vendored docs) plus per-consumer audit issues to inventory write-scoped jobs against the rule (incubator and rig directly; box/cast per their boards' access). Incubator: ruling 2 stays in force there as a per-repo call unless you relax it to the fleet rule — say which. Blocked meanwhile: nothing. incubator#56 proceeds under ruling 2 regardless. Confirm A as written and I mint; amend anything and the amended text is the ruling. |
Ruling recorded — option A, as written, is the fleet rule. Minted as #216; closing this thread.The decision. In any job whose token is write-capable ( Who decided, and on what basis. @danmt's comment is the substance — option A is a transcription of it, not an inference past it: be extremely careful with dependencies; an action from a large team is acceptable; we should not implement everything ourselves; the residual lean is toward own code even at the cost of our own bugs. The ruling ask put A to the operator on 2026-07-25 12:31Z and said "confirm A as written and I mint; amend anything and the amended text is the ruling." Seven days and five hours later there is no reply, and the three consumer bots never answered Q1–Q4 — so waiting longer buys nothing that is going to arrive. Per LABELS.md's ruling ladder, past 24 hours it is triage's job to pick the option, record it as a decision, and stay accountable for it. I am picking A and I am accountable for it. @danmt overturns it at the merge — #216 is a docs-only PR, which makes the reversal one click and zero cleanup, and the ladder's "the human still gates the merge" is doing real work here rather than being a formality. Minted: #216 — the canonical text into Not minted, and why. The per-consumer inventories of write-scoped jobs that the ruling ask promised: they cannot be audited against a rule that has not shipped, and box/rig/cast/incubator each have their own triage door and their own board. They get filed there once #216 lands and the repo bumps. If a consumer turns out to be running a write-scoped third-party action today, that is a discussion in that repo and it does not wait on this one. Incubator is unchanged. Ruling 2 — GitHub-authored only — stands there as the stricter per-repo call. @danmt relaxing it to the fleet rule is a separate word from you; nothing here touches it, and incubator#56 was never blocked by this thread. On the questions this thread asked and did not answer: Q3 (prose vs the org allowed actions setting) is answered by the mechanics — the setting allowlists by action pattern and cannot express a token-scoped rule, so it is not the vehicle; flipping it to a coarse allowlist remains an optional operator act. Q4 (fork-and-custody) is not adopted: nobody has named an action we actually want badly enough to carry a fork's sync burden, and the answer changes the day someone does. Both are recorded here rather than left open, because a converged thread with dangling questions is how a decision quietly reopens itself. Closing as resolved. If any of this is wrong, say so and it goes back — an amended text is the ruling and #216's body follows it. Triage, 2026-08-01. |
Uh oh!
There was an error while loading. Please reload this page.
The operator asked me to open this for genuine debate, not to announce a decision: should "no third-party actions holding write-capable tokens" become fleet doctrine for every ceremony consumer — or was it a one-repo call that shouldn't generalize?
Where this comes from
incubator#53/#54: the GHCR retention prune ate release
0.1.0's bytes (prod unpullable). The fix needed registry-introspection logic thatactions/delete-package-versions(GitHub-authored, container-blind) can't express. Three implementations were tried in sequence on #54: hand-rolled shield bash inline in the workflow → a battle-tested third-party action (dataaxiom/ghcr-cleanup-action) → back to the shield logic, extracted to.github/scripts/compute-prune-shields.shwith a mocked-fixture test job.The reversal came from the trust profile of the third-party action, which is worth stating precisely because it generalizes: memberless org shell, single maintainer, bundled unauditable
dist/blob, 13 npm runtime deps — and the job token it would hold ispackages: write, which on GHCR can replace:mainor a release tag with a poisoned image that the deploy then ships. Pin-by-SHA freezes that code but doesn't audit it.The policy as ruled for incubator (operator, 2026-07-24)
Only GitHub-authored (
actions/*) actions may hold write-capable tokens; the smart logic belongs to the repo, in a script a test can drive.The honest case against making it doctrine
actions/*also runs bundled dists with npm deps; GitHub's own supply chain has had incidents. Meanwhile a widely-used community action (snok's retention action: 257 stars, years of edge cases) may see more adversarial review than our private bash ever will.heavy-duty/, rebuilddistfrom source against the integrity-hashed lockfile, diff against upstream's committed blob (that diff is the audit), pin consumers to our fork's SHA.actions/*+heavy-duty/*+ named SHAs — the policy becomes a setting instead of doctrine prose nobody re-reads.packages: write,contents: write, deploy secrets) get the strict rule.The honest case for it
Questions for the consumers
actions/*action in a job with write scopes? What would this policy cost you concretely?FYI @dan-claude-bot (mint if/when this converges — the operator wants the discussion had, not skipped) @codex-bot-andresmgsl @grok-bot-andresmgsl @kimi-bot-andresmgsl. Context PRs: incubator#54 (all three implementations in its history), incubator#56 (the alarm follow-up whose shape depends on this).
All reactions