Commit 273e9b95f8
Verified · cmc
Layout: unified · split
.gitbay/wiki/Architecture/05-Identity-and-Access.org +12 −1
| @@ -18,7 +18,7 @@ | |||
| 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 | | 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 | | 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 | | 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]= | | 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 | | Web session | 32 random bytes hex, cookie =gitbay_session= | SHA-256 hash | full account | 12 h idle, 7 days absolute | logout, =web sessions revoke= | | 21 | | Web session | 32 random bytes hex, cookie =gitbay_session= | SHA-256 hash | full account; credential-minting and access-granting commands only within 15 minutes of sign-in | 12 h idle, 7 days absolute | logout, =web sessions revoke= | |
| 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 | | 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 | |
| 23 | | Email verification | 32 random bytes hex | SHA-256 hash, single use | verifies one address for one account | 24 h | consumed on use | | 23 | | Email verification | 32 random bytes hex | SHA-256 hash, single use | verifies one address for one account | 24 h | consumed on use | |
| 24 | | Invite | random code | SHA-256 hash, single use | one registration for one email | as issued | consumed on use | | 24 | | Invite | random code | SHA-256 hash, single use | one registration for one email | as issued | consumed on use | |
| @@ -118,6 +118,17 @@ button and the displayed status (=internal/control/mr.go=): | |||
| 118 | - Destructive web actions (key, email and PGP removal, release, snippet, | 118 | - Destructive web actions (key, email and PGP removal, release, snippet, |
| 119 | team and label deletion, user disable and demote) require the target's | 119 | team and label deletion, user disable and demote) require the target's |
| 120 | name typed into the form (=internal/httpd/confirm.go=). | 120 | name typed into the form (=internal/httpd/confirm.go=). |
| 121 | - Commands that create a credential (SSH, deploy and runner keys, API | ||
| 122 | tokens, email verification, login links, PGP keys, device tokens) or | ||
| 123 | grant access (repository and organization roles, teams, transfers, | ||
| 124 | admin promote and enable, webhooks, secrets, mirrors) are refused | ||
| 125 | from a browser session that signed in more than 15 minutes ago | ||
| 126 | (=control.ReauthWindow=, =Command.NeedsRecentSignIn=). The sign-in | ||
| 127 | time is =web_sessions.created_at=, which idle renewal does not move; | ||
| 128 | a request with no sign-in time is refused. SSH, API tokens and host | ||
| 129 | commands are unaffected. The refusal is audited; the form shows it | ||
| 130 | with a sign-in link, and the login returns to the page through the | ||
| 131 | server-set =gitbay_next= cookie (=internal/httpd/flash.go=). | ||
| 121 | 132 | ||
| 122 | * Rate limits | 133 | * Rate limits |
| 123 | 134 | ||
.gitbay/wiki/Architecture/09-Controls.org +1 −1
| @@ -26,7 +26,7 @@ chapter names of OWASP ASVS 4.0 where one fits. | |||
| 26 | | Session lifetime | in place | 12 hours idle, 7 days absolute (=internal/store/sessions.go=) | | 26 | | Session lifetime | in place | 12 hours idle, 7 days absolute (=internal/store/sessions.go=) | |
| 27 | | Credential expiry | in place | optional =--ttl= on API tokens, SSH and deploy keys; checked at auth and per exec | | 27 | | Credential expiry | in place | optional =--ttl= on API tokens, SSH and deploy keys; checked at auth and per exec | |
| 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=); LFS transfer tokens are refused with their key (=internal/httpd/lfs.go=) | | 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=); LFS transfer tokens are refused with their key (=internal/httpd/lfs.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) | | 29 | | Delegation bounded by the delegating credential | in place | expiring tokens refused on =MintsCredential= commands; credentials record their creating token; a browser session runs credential-minting and access-granting commands only within 15 minutes of signing in, and the refusal is audited (=internal/control/control.go=) | |
| 30 | 30 | ||
| 31 | ** Access control (V4) | 31 | ** Access control (V4) |
| 32 | 32 | ||
.gitbay/wiki/Architecture/10-Known-Gaps.org −2
| @@ -13,8 +13,6 @@ what the 2026-09-27 review found; remove a row when its issue closes. | |||
| 13 | | #259 | Recovery | No restore has been exercised; the drill is written (Admin wiki) and not yet run | high | | 13 | | #259 | Recovery | No restore has been exercised; the drill is written (Admin wiki) and not yet run | high | |
| 14 | | #260 | CI network | Builds share the runner's source address; no egress policy | medium | | 14 | | #260 | CI network | Builds share the runner's source address; no egress policy | medium | |
| 15 | | #261 | Various | Migration foreign-key check after commit; three web writes bypass dispatch; documentation drift | medium | | 15 | | #261 | Various | Migration foreign-key check after commit; three web writes bypass dispatch; documentation drift | medium | |
| 16 | | #297 | Credentials | A browser session can mint tokens and keys that outlive it | low | | ||
| 17 | | #301 | SSRF | =repo import-issues --api-base= fetches without an address check or pin | medium | | ||
| 18 | 16 | ||
| 19 | * Not filed | 17 | * Not filed |
| 20 | 18 | ||
.gitbay/wiki/Threat-Model.org +3 −2
| @@ -61,8 +61,9 @@ matrix and the open gaps are in the [[file:Architecture/00-Overview.org][Archite | |||
| 61 | rights narrowed by its credential's scope, decided in one place, so a | 61 | rights narrowed by its credential's scope, decided in one place, so a |
| 62 | bearer token is worth exactly its scope and no more, and a token or | 62 | bearer token is worth exactly its scope and no more, and a token or |
| 63 | SSH key with an expiry cannot create a credential that outlives it. | 63 | SSH key with an expiry cannot create a credential that outlives it. |
| 64 | Browser sessions are not covered yet (#297). Git transport never runs | 64 | A browser session can create one, or grant access, only within 15 |
| 65 | over the API. | 65 | minutes of signing in (=control.ReauthWindow=, #297). Git transport |
| 66 | never runs over the API. | ||
| 66 | - *Anonymous surfaces* — HTTPS clone of public repos, =git://= where | 67 | - *Anonymous surfaces* — HTTPS clone of public repos, =git://= where |
| 67 | enabled, the read-only web UI — carry no credentials and expose only | 68 | enabled, the read-only web UI — carry no credentials and expose only |
| 68 | public data. HTTP push is refused via a pkt-line =ERR=, never a 401. | 69 | public data. HTTP push is refused via a pkt-line =ERR=, never a 401. |
.gitbay/wiki/Users.org +6
| @@ -701,6 +701,12 @@ creation, expiry and last use, and =gitbay web sessions revoke <id>= | |||
| 701 | or =--all= ends them from the terminal, which is where a lost laptop is | 701 | or =--all= ends them from the terminal, which is where a lost laptop is |
| 702 | handled. | 702 | handled. |
| 703 | 703 | ||
| 704 | Actions that create a credential or grant access (adding a key, token | ||
| 705 | or email, org and repository roles, transfers) ask you to sign in again | ||
| 706 | when your web sign-in is older than 15 minutes. The form shows a "Sign | ||
| 707 | in again" link and the login returns to the page. Idle renewal does not | ||
| 708 | extend this window. | ||
| 709 | |||
| 704 | =web theme set light= or =dark= fixes the web UI's colour scheme for | 710 | =web theme set light= or =dark= fixes the web UI's colour scheme for |
| 705 | your account; =system=, the default, follows the browser's own | 711 | your account; =system=, the default, follows the browser's own |
| 706 | preference. =web theme show= prints it. The account page has the same | 712 | preference. =web theme show= prints it. The account page has the same |
CHANGELOG.org +6
| @@ -27,6 +27,12 @@ too; rewrite it before upgrading. | |||
| 27 | access — keys, PGP keys, tokens, org membership, and the admin | 27 | access — keys, PGP keys, tokens, org membership, and the admin |
| 28 | promote/enable actions — and the form it tried shows a sign-in link | 28 | promote/enable actions — and the form it tried shows a sign-in link |
| 29 | that returns there (#297). | 29 | that returns there (#297). |
| 30 | - A browser session creates credentials and grants access — keys, PGP | ||
| 31 | keys, tokens, verified addresses, org and repository roles, transfers, | ||
| 32 | webhooks, secrets, mirrors, and the admin promote/enable actions — | ||
| 33 | only within 15 minutes of signing in. An older session gets the form | ||
| 34 | back with a "Sign in again" link, and the login returns to it. SSH and | ||
| 35 | API tokens are unaffected (#297). | ||
| 30 | - The builds page's status badge section gives an org-mode snippet | 36 | - The builds page's status badge section gives an org-mode snippet |
| 31 | beside the Markdown one, for a README.org (#299). | 37 | beside the Markdown one, for a README.org (#299). |
| 32 | - API tokens on the settings page: create with a scope and optional | 38 | - API tokens on the settings page: create with a scope and optional |