Commit 1ed9fb9399
1ed9fb9399b21da8e6cf45be8389792aac82d5bc
parent: 44e5fb3a83
Verified · cmc
cmc <hello@cleberg.net> · 2026-09-28 07:40 UTC
wiki: key expiry
Closes #277
Layout: unified · split
.gitbay/wiki/API.org
+1 −1
| @@ -16,7 +16,7 @@ enabled = true |
| 16 | 16 | Tokens are minted wherever the registry is reached: over SSH, on the |
| 17 | 17 | API, anywhere. =token create= makes a =read= token unless =--scope full= |
| 18 | 18 | is given; a read token runs only commands marked read-only. A full-scope |
| 19 | | token can mint another, but a token with a =--ttl= cannot run any |
| 19 | token can mint another, but a token or SSH key with a =--ttl= cannot run any |
| 20 | 20 | command that creates a credential — =token create=, =keys add=, |
| 21 | 21 | =repo deploy-key add=, =repo runner add=, =web login=, =admin invite=, |
| 22 | 22 | =admin user create=, =email verify=, =admin email verify= — since what |
.gitbay/wiki/Architecture/05-Identity-and-Access.org
+2 −2
| @@ -15,8 +15,8 @@ |
| 15 | 15 | |
| 16 | 16 | | Credential | Format and generation | Stored as | Scope | Expiry | Revocation | |
| 17 | 17 | |--------------------+-------------------------------------------------+----------------------------------+--------------------------------------------+-------------------------------+-------------------------------------| |
| 18 | | | SSH user key | user's public key | fingerprint and public blob | =full=, =git=, or =runner= | none | =keys remove= (own keys); closes its connections | |
| 19 | | | Deploy key | public key | same table, scope =deploy:<repo>:ro/rw= | one repository, read or read-write | none | =repo deploy-key remove= (repo admin); closes its connections | |
| 18 | | SSH user key | user's public key | fingerprint and public blob | =full=, =git=, or =runner= | optional =--ttl=, refused at auth | =keys remove= (own keys); closes its connections | |
| 19 | | Deploy key | public key | same table, scope =deploy:<repo>:ro/rw= | one repository, read or read-write | optional =--ttl=, refused at auth | =repo deploy-key remove= (repo admin); closes its connections | |
| 20 | 20 | | API token | =gb_= + 32 random bytes hex | SHA-256 hash | =read= (default) or =full=; with an expiry, no credential-minting command | optional =--ttl= | =token revoke [--created]= | |
| 21 | 21 | | Web session | 32 random bytes hex, cookie =gitbay_session= | SHA-256 hash | full account | 7 days, no sliding renewal | logout, =web sessions revoke= | |
| 22 | 22 | | Login link | 32 random bytes hex in a URL | SHA-256 hash, single use | creates a web session | 15 min (mail), 5 min (SSH) | consumed on use | |
.gitbay/wiki/Architecture/09-Controls.org
+1 −1
| @@ -24,7 +24,7 @@ chapter names of OWASP ASVS 4.0 where one fits. |
| 24 | 24 | | Account enumeration resistance at login | in place | uniform response (=internal/control/loginlink.go=) | |
| 25 | 25 | | Session cookie flags | in place | HttpOnly, SameSite=Lax, Secure with TLS (=internal/httpd/accounts.go=) | |
| 26 | 26 | | Session lifetime | partial | 7 days absolute, no idle timeout (#276) | |
| 27 | | | Credential expiry | partial | API tokens optional; SSH and deploy keys none (#277) | |
| 27 | | Credential expiry | in place | optional =--ttl= on API tokens, SSH and deploy keys; checked at auth and per exec | |
| 28 | 28 | | 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 | 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) | |
| 30 | 30 | |
.gitbay/wiki/Architecture/10-Known-Gaps.org
−1
| @@ -20,7 +20,6 @@ what the 2026-09-27 review found; remove a row when its issue closes. |
| 20 | 20 | | #274 | Backups | The local backup archive is not encrypted | medium | |
| 21 | 21 | | #275 | Audit | Refused writes are not audited; the audit table is writable by the daemon user | medium | |
| 22 | 22 | | #276 | Sessions | Web sessions last 7 days with no idle timeout | low | |
| 23 | | | #277 | Credentials | SSH and deploy keys never expire | low | |
| 24 | 23 | | #278 | Login links | =web login= over SSH skips the login-link rate limit | low | |
| 25 | 24 | | #279 | SSRF | Mirror URLs are checked when saved, not when git connects | medium | |
| 26 | 25 | | #280 | Mail | STARTTLS only when the relay offers it | medium | |
.gitbay/wiki/Parity.org
+1
| @@ -343,6 +343,7 @@ client has no use for one (krz/gitbay#57). |
| 343 | 343 | |-----------------------------+-----+-----+-----| |
| 344 | 344 | | SSH keys: list, add, remove | yes | yes | yes | |
| 345 | 345 | | SSH key label | yes | yes | yes | |
| 346 | | SSH key expiry and last use | yes | no | no | |
| 346 | 347 | | PGP keys: list, add, remove | yes | yes | yes | |
| 347 | 348 | | email add and verify | yes | yes | yes | |
| 348 | 349 | | email list, remove, primary | yes | yes | yes | |
.gitbay/wiki/Users.org
+7
| @@ -61,6 +61,7 @@ username is always =git= — the key alone determines who you are. |
| 61 | 61 | gitbay auth keys list |
| 62 | 62 | gitbay auth keys add --scope git < ~/.ssh/ci_key.pub # key on stdin |
| 63 | 63 | gitbay auth keys add --label laptop < ~/.ssh/id_ed25519.pub |
| 64 | gitbay auth keys add --scope git --ttl 90d < ~/.ssh/ci_key.pub |
| 64 | 65 | gitbay auth keys label SHA256:... "work laptop" |
| 65 | 66 | gitbay auth keys remove SHA256:... |
| 66 | 67 | #+end_src |
| @@ -69,6 +70,12 @@ A key's label is the comment on its =authorized_keys= line unless |
| 69 | 70 | =--label= gives one; =keys label= renames a key, and with no text |
| 70 | 71 | clears the name. Labels are one line of up to 64 bytes. |
| 71 | 72 | |
| 73 | =--ttl 90d= (or any Go duration, =720h=) makes a key stop |
| 74 | authenticating after that long; =repo deploy-key add= takes the same |
| 75 | flag. An expiring key cannot create credentials: tokens, keys, login |
| 76 | links. =keys list= shows when each key was last used and when it |
| 77 | expires, so a key nobody uses is easy to spot. |
| 78 | |
| 72 | 79 | Removing a key closes every connection it opened, including the CLI's |
| 73 | 80 | shared one; removing the key the current command runs on ends that |
| 74 | 81 | command's connection too. |
CHANGELOG.org
+5
| @@ -20,6 +20,11 @@ must add =--scope full=. Existing tokens keep their scope. |
| 20 | 20 | those too (#257). |
| 21 | 21 | - Removing an SSH key, a deploy key, or disabling an account closes the |
| 22 | 22 | connections the key opened, a push in flight included (#256). |
| 23 | - =keys add= and =repo deploy-key add= take =--ttl=; an expired key is |
| 24 | refused at authentication, and an open connection on it closes within |
| 25 | 15 seconds. An expiring key cannot create credentials, like an |
| 26 | expiring token. =keys list= and =repo deploy-key list= gain =USED= and |
| 27 | =EXPIRES= columns, after the label (#277). |
| 23 | 28 | |
| 24 | 29 | * v1.36.0 — 2026-09-23 |
| 25 | 30 | |