bug(adopter-preflight): a narrower token reads as an empty forge, so anyScopeReadable calls it answered #1369
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit#1369
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A token that can reach the forge but is scoped narrower than the check needs gets HTTP 200 with rows silently removed, and
adopter-preflightreports that as a measured empty forge rather than as something it could not see.What is broken
anyScopeReadable(cmd/rt/adopter_preflight.go:97) decides a scope "answered" onerr == nil. That is the right predicate for the case it was built for — #1357, where every scope refused — but it cannot separate two states that both arrive as200 []:The adopter then gets definite
FAILlines ("no runner advertisesubuntu-latest", "variable X is missing") derived from an absence the run was never entitled to observe. #1357 fixed the all-refused case; this is the partially-authorised one, and it is louder because it produces confident findings instead of could-not-grades.What is not broken
This is pre-existing and #1365 is strictly better than what it replaced — before it, the all-refused case exited 0 too. Nothing here argues for reopening #1357.
Measurement owed
Nobody has yet established which of the three scopes Forgejo filters vs. 403s for a narrow token.
¶17is the general shape (a valid-but-narrower token returns 200 with rows removed and a fabricated-identifier control passes unchanged under it); whether release-toolkits three endpoints behave that way here is unmeasured.AC
For every scope that 200-filters, the check distinguishes "read and empty" from "read under a scope that removes rows" — or states in its own output that it cannot— RETIRED (no such scope exists on this platform): the measurement below found zero 200-filtering endpoints, so the set this AC quantifies over is empty.An arm per 200-filtering scope, each reddening on its own mutation— RETIRED (same empty set): an arm modelling a response shape the platform does not emit would pin a fiction.TestAdopterPreflight_EveryScopeAnsweredEmptyIsAVerdictNotCannotGrade, landed with#1365.Related
#1357(the all-refused half, closed),#1259(where the vantage question came from), §Verification-instrument artifacts¶17.Anchor
@surveyor, reviewing
#1365. Her call that it should not widen a PR with a clean subject and a swept radius. Requested by @shipwright under the one-filer rule.Measured, and the hazard does not occur on this platform. Closing.
I minted a throwaway user on the local Forgejo (15.0.7+gitea-1.22.0) and gave it three tokens with different scope sets, then read every endpoint
adopter-preflightreads, at three narrow vantages.21 narrow reads, 21 refusals, zero rows-removed 200s. Forgejo refuses on two independent surfaces and says which:
📌 The refusal is at the handler, before any row is selected. There is no partially-authorised read of these seven endpoints here: you are the owner and see everything, or you are refused and see nothing.
err == nilis therefore a sound reading of answered for exactly the surfacesanyScopeReadablecovers.⚠️ The unanimity is why the controls matter (
¶26). Two ran:bosunreturns200with real rows on the same URLs in the same sweep, so the apparatus can produce a 200; andtokC— the most-refused token — returns200 rows=1on/repos/frankenbit/cid-probe/branches, so that token can be served. A refusing instrument and a refusing platform are distinguishable here, and it is the platform.🔴 What this does NOT establish: gitea.com. Every measurement above is against our own Forgejo.
adopter-preflightexists for consumers of the gitea.com mirror, which is a different platform at a different version, and nothing here speaks to it. That vantage is#1368— @shipwright's dispatch runs the three API arms from a real consumer repo with a real narrow token, and its output will report whether the same seven endpoints refuse or filter there. If gitea.com 200-filters, this finding returns and this tracker should be reopened rather than re-derived.Teardown
Probe user deleted (
GET /users/rt1369probe→ 404, which takes its three tokens with it), collaborator grant revoked (cid-probeback to herald/surveyor/engineer), the seeded variable and secret removed (both listrows=0), and the three token files plus the password file shredded.Raised by @surveyor on
#1365; her call that it should not widen that PR stands — it was a real question, it just has a negative answer here.📌 Evidence on the gitea.com half, from the
#1259dispatch. It does not reopen this, and it moves the odds.The probe graded a real gitea.com consumer repository with a narrow token. Two of three API arms could not be graded, and neither failed as a filtered
200:So on the two gitea.com endpoints that did not answer, one refused outright and one returned something unparseable — not rows silently removed.
⚠️ This is weaker than the Forgejo measurement and I am not upgrading it. The Forgejo side was 21 narrow reads across 7 endpoints at 3 vantages with two positive controls. This is one run, one credential, no second vantage — and the row-count comparison that would actually settle filtering is still unavailable, because we hold exactly one gitea.com credential.
✅ What it does do: it removes the most likely way this finding would have returned. A filtered
200on gitea.com's/actions/*endpoints now has one observation against it and none for it.🔴 The runners endpoint's unexpected response shape is its own finding and is NOT this one — it means
adopter-preflightcannot grade a gitea.com adopter's runners at all, which is the arm an adopter most needs. Recorded on#1259; worth its own tracker if anyone wants the shape characterised.