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.

Store repository secrets encrypted, with a CLI and a settings form

0c40a1d3b48eb0ade37334f62ee526c371ecb61c · Keenan Nemetz · 7d ago · parent 122cbe4f

Store repository secrets encrypted, with a CLI and a settings form

A repository has values that cannot live in its code: a deploy key, a
registry token, a staging password. They are now stored in data/secrets.db,
sealed with AES-256-GCM under data/secrets.key, and read through one store
that records every read and every change. The key is a separate file, and
secrets_key can move it, so a backup of the data directory can be a backup of
ciphertext rather than of plaintext.

`vole secret list|set|get|rm` asks the instance over the key the caller
already pushes with, since the store is server-side. set reads the value from
stdin or a file and never from the argument list; get writes the value and
nothing else. The maintainer role is the capability: the accounts that approve
work and allow CI own the credentials those jobs will use.

The repository's Settings tab gains the same list — names, versions, who
changed one, when a value was last read — with set, replace and delete. It
never renders a value, and a maintainer who is not an admin now reaches that
page for this section alone.

Values are limited to what one environment variable can carry: 128 KiB for
NAME=value, valid UTF-8 and no NUL. A longer value could never reach a step,
and the refusal says so.

Slice 1 of #154.

server/web/page.go +5−1

@@ -34,6 +34,10 @@ type Page struct {
34 34 // CanAdmin reports whether the viewer may administer the repository named in
35 35 // the request path. The repository header uses it to show Settings.
36 36 CanAdmin bool
37 // CanMaintain reports whether the viewer holds the maintainer capability. The
38 // header shows Settings for a maintainer because that page holds the
39 // repository's secrets, and a maintainer is who owns them.
40 CanMaintain bool
37 41 // CloneURL and SSHURL are the two transports the repository header offers to
38 42 // copy. They are empty when the path does not name a repository.
39 43 CloneURL string
@@ -130,7 +134,7 @@ func (w *Web) userRef(name string) userRef {
130 134 // Templates call it as
131 135 // {{template "repohead" (nav .Page "issues")}}.
132 136 func (w *Web) repoNav(p Page, tab string) repoNavData {
133 n := repoNavData{Name: p.RepoName, Tab: tab, Private: true, CanAdmin: p.CanAdmin,
137 n := repoNavData{Name: p.RepoName, Tab: tab, Private: true, CanAdmin: p.CanMaintain || p.CanAdmin,
134 138 CloneURL: p.CloneURL, SSHURL: p.SSHURL, Site: p.Site}
135 139 if p.RepoName == "" {
136 140 return n