Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Phase 7 slice 4: a published release cannot change under its link

948a6d7dcdacb72d6f90074ac0e5f9999314c4f4 · Keenan Nemetz · 17d ago · parent 85cc89fe

Phase 7 slice 4: a published release cannot change under its link

The last piece of the release story is the one that makes the download links
trustworthy: pre-receive now refuses to move or delete a tag that has artifacts
attached, and on the metadata branch refuses removing a pointer or re-pointing
one at different bytes. Comparing blob ids is enough — a pointer's id is its
text, so "unchanged" needs no parsing and cannot be fooled by reformatting.

Adding an artifact stays legal: an artifact is published when its pointer lands,
so an addition invalidates nothing.

The rules sit with the integrity checks rather than the review gate, because a
download that can change bytes is broken whoever pushed it. An admin may
override, with a line in data/audit.log, following the force-push precedent: a
mistyped tag is otherwise unrepairable, and an unaudited override leaves no trace
of the bytes that changed under somebody's link.

Four refusals are tested through a writer account (moved tag, deleted tag,
removed pointer, re-pointed pointer), plus the admin override and its audit line.

internal/hook/hook.go +18

@@ -189,6 +189,24 @@ func PreReceive(cfg Config) int {
189 189 }
190 190 }
191 191
192 // A published release is immutable: the tag that names it and the pointers
193 // that carry its bytes. This sits with the integrity checks rather than
194 // with the review gate, because a download that can change bytes is broken
195 // no matter who pushed it — but an admin may override, audited, since a
196 // mistyped tag is a real problem and the alternative is a repository
197 // nobody can repair.
198 if relProblems := releaseFindings(g, c); len(relProblems) > 0 {
199 if role.AtLeast(acl.Admin) {
200 for _, p := range relProblems {
201 auditLine(cfg.AuditPath, fmt.Sprintf("release rewrite %s by %s in %s: %s",
202 c.ref, actor, m.Name, p))
203 reject(cfg.Out, "admin override, audited: %s", p)
204 }
205 } else {
206 problems = append(problems, relProblems...)
207 }
208 }
209
192 210 if a.IsProtected(c.ref) {
193 211 // Admins keep the bypass they always had. Everyone else needs an
194 212 // approved request that names the exact commit they are landing.