Commit e2a32d5f8d

e2a32d5f8d59e4213571c602bd9009b6c8fa86ed

parent: 0787c7c07e

Verified · cmc ci/build: success ci/test: success

cmc <hello@cleberg.net> · 2026-09-28 08:10 UTC

wiki: delegation bound covers tokens and keys, not web sessions

Ref #257

Layout: unified · split

.gitbay/wiki/Architecture/09-Controls.org +1 −1
@@ -26,7 +26,7 @@ chapter names of OWASP ASVS 4.0 where one fits.
2626| Session lifetime | partial | 7 days absolute, no idle timeout (#276) |
2727| Credential expiry | partial | API tokens optional; SSH and deploy keys none (#277) |
2828| Revocation takes effect immediately | in place | removing a key or disabling an account closes its connections; every exec re-reads its key (=internal/sshd/sshd.go=) |
29| Delegation bounded by the delegating credential | in place | expiring tokens refused on =MintsCredential= commands; credentials record their creating token (=internal/control/control.go=) |
29| Delegation bounded by the delegating credential | partial | expiring tokens refused on =MintsCredential= commands; credentials record their creating token (=internal/control/control.go=); a web session can still mint credentials that outlive it (#297) |
3030
3131** Access control (V4)
3232
.gitbay/wiki/Architecture/10-Known-Gaps.org +1 −1
@@ -26,7 +26,7 @@ what the 2026-09-27 review found; remove a row when its issue closes.
2626| #280 | Mail | STARTTLS only when the relay offers it | medium |
2727| #281 | TLS | No explicit minimum TLS version | low |
2828| #282 | Hook socket | Anything that can open =hook.sock= can act as any user | medium |
29
29| #297 | Credentials | A browser session can mint tokens and keys that outlive it | low |
3030
3131* Questions an auditor will ask that have no answer yet
3232
.gitbay/wiki/Threat-Model.org +4 −3
@@ -52,9 +52,10 @@ matrix and the open gaps are in the [[file:Architecture/00-Overview.org][Archite
5252 OpenSSH and fronted unchanged by the JSON API and the web. No command
5353 belongs to one surface (#234): what a caller may do is the account's
5454 rights narrowed by its credential's scope, decided in one place, so a
55 bearer token is worth exactly its scope and no more, and a credential
56 with an expiry cannot create one that outlives it. Git transport
57 never runs over the API.
55 bearer token is worth exactly its scope and no more, and a token or
56 SSH key with an expiry cannot create a credential that outlives it.
57 Browser sessions are not covered yet (#297). Git transport never runs
58 over the API.
5859- *Anonymous surfaces* — HTTPS clone of public repos, =git://= where
5960 enabled, the read-only web UI — carry no credentials and expose only
6061 public data. HTTP push is refused via a pkt-line =ERR=, never a 401.
CHANGELOG.org +3 −1
@@ -6,6 +6,8 @@ anything beyond "replace the binary and restart" is needed.
66
77* Unreleased
88
9Credentials: revocation and delegation (#256, #257).
10
911*Upgrade note.* =token create= makes a =read= token unless given
1012=--scope full=. A script that mints a token and then writes with it
1113must add =--scope full=. Existing tokens keep their scope.
@@ -15,7 +17,7 @@ must add =--scope full=. Existing tokens keep their scope.
1517 invites, accounts and verified addresses (#257).
1618- Tokens and SSH keys record the token they were created through.
1719 =token revoke <name>= lists what it created; =--created= revokes
18 those too.
20 those too (#257).
1921- Removing an SSH key, a deploy key, or disabling an account closes the
2022 connections the key opened, a push in flight included (#256).
2123