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/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

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

Drop the refs/vole rule, which has nothing left to guard

592710c296c678e21bc1dc89341ad71606316500 · Keenan Nemetz · 17d ago · parent ec5c519c

Drop the refs/vole rule, which has nothing left to guard

The namespace held the ACL and needed a rule of its own: a client who could write
refs/vole/acl could have granted itself admin. The rules live in data/users.db now,
so the namespace is empty and the special case only made refusals inconsistent —
an owner pushing refs/vole/x got "server-owned", which is no longer true.

Only branches and tags are writable, and that rule already refuses everything else,
refs/vole/* included. The test now pins that: refs/notes/commits and refs/vole/acl
are refused with the same message.

internal/hook/hook.go +4−7

@@ -141,13 +141,10 @@ func PreReceive(cfg Config) int {
141 141 }
142 142 var problems []string
143 143 for _, c := range changes {
144 // Metadata refs belong to the server. Letting a client write refs/vole/*
145 // would let them grant themselves access by pushing a new acl.json.
146 if strings.HasPrefix(c.ref, "refs/vole/") {
147 problems = append(problems, fmt.Sprintf(
148 "%s is server-owned and cannot be pushed to", c.ref))
149 continue
150 }
144 // Only branches and tags are writable. The namespace beside them used to hold
145 // the ACL; nothing lives there now (see the access package), so it needs no rule
146 // of its own — the rule below already covers every ref that is not a branch or a
147 // tag.
151 148 if !strings.HasPrefix(c.ref, "refs/heads/") && !strings.HasPrefix(c.ref, "refs/tags/") {
152 149 problems = append(problems, fmt.Sprintf(
153 150 "%s: only refs/heads/* and refs/tags/* may be pushed", c.ref))