Commit 5593f9c1d6

5593f9c1d6842ab10c228f7818320e13a00dff95

parent: d0cfea951a

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-05 04:09 UTC

Parity: browser login by emailed link

Layout: unified · split

Parity.org +15 −4
@@ -16,8 +16,10 @@ stranded a capability where only it can reach.
16A capability lands over SSH first. If it belongs to the 16A capability lands over SSH first. If it belongs to the
17triage/review/respond loop, it lands on the web in the same merge 17triage/review/respond loop, it lands on the web in the same merge
18request. Anything whose input is a credential — secrets, mirror 18request. Anything whose input is a credential — secrets, mirror
19tokens, API tokens, session minting — stays SSH-only by design: the 19tokens, API tokens — stays SSH-only by design: the web dispatcher
20web dispatcher refuses =SSHOnly= commands outright. 20refuses =SSHOnly= commands outright. Session minting is not one of
21them: what a browser submits to ask for a login link is a username or
22an address, and the credential it gets back travels by mail.
21 23
22Rows are one page or one action each. Grouped rows hide gaps, twice 24Rows are one page or one action each. Grouped rows hide gaps, twice
23now: "browse, log, blame, search" read as covered while blame had no 25now: "browse, log, blame, search" read as covered while blame had no
@@ -228,6 +230,7 @@ client has no use for one (krz/gitbay#57).
228| API token mint | yes | no | no | 230| API token mint | yes | no | no |
229| account export bundle | yes | no | no | 231| account export bundle | yes | no | no |
230| profile set | yes | no | no | 232| profile set | yes | no | no |
233| request a login link | n/a | yes | no |
231 234
232Notifications land in an inbox row per recipient whether or not the 235Notifications land in an inbox row per recipient whether or not the
233instance sends mail, and mail is the second half when SMTP is 236instance sends mail, and mail is the second half when SMTP is
@@ -237,6 +240,15 @@ web rail carry the unread count. =repo watch= adds you to a
237repository's notifications and =repo unwatch= mutes it, and a mute wins 240repository's notifications and =repo unwatch= mutes it, and a mute wins
238over owning the repository or having written the thread. 241over owning the repository or having written the thread.
239 242
243A login link is requested from the login page by username or verified
244address, and arrives by mail: it works once and expires in fifteen
245minutes. The row is =n/a= for the CLI because a terminal with a
246registered key runs =web login=, which mints a link directly and needs
247no mail. It exists because an account with no SSH key had no way into
248the web at all (krz/gitbay#155). The page offers the form only when the
249instance has SMTP configured; there is no separate switch. The response
250never says whether the account exists.
251
240=profile set= carries description, website, about and links. It is not 252=profile set= carries description, website, about and links. It is not
241=SSHOnly= — nothing about a bio is a credential, and the JSON API runs 253=SSHOnly= — nothing about a bio is a credential, and the JSON API runs
242it — but no surface has ever offered a form, so the =no= above is 254it — but no surface has ever offered a form, so the =no= above is
@@ -264,8 +276,7 @@ with the same cursors; iOS pages with them too.
264* SSH only, by design 276* SSH only, by design
265 277
266Build secrets, mirror configuration and tokens, custom domain claims, 278Build secrets, mirror configuration and tokens, custom domain claims,
267API token minting, web session minting, deploy keys, account and 279API token minting, deploy keys, account and instance administration. Deleting or transferring a repository is also
268instance administration. Deleting or transferring a repository is also
269CLI-only: both want a typed confirmation, not a button. 280CLI-only: both want a typed confirmation, not a button.
270 281
271These are the only rows where a =no= is intended. Everywhere else a 282These are the only rows where a =no= is intended. Everywhere else a