Rio
adr/0125-repository-signing-keys-list.mdRaw Markdown · GitHub ↗

ADR-0125: Every repository signing key rio trusts is listed, and can be forgotten

  • Status: Accepted; amended by ADR-0126
  • Date: 2026-09-19
  • Deciders: jka
  • Decision: D118 (amendment of 2026-09-19)

Context

ADR-0124 trusts a repository's signing key on first use and writes it to repository-keys.conf beside the sources list. That file is hand-editable on purpose, and deleting a section is how a user takes a trust decision back — but it was the only way to see what rio had trusted at all, and the only way to undo it. A management dialog was weighed there and deferred, to keep an already large change reviewable. The maintainer asked for it as soon as that change had merged: nothing about it was unresolved.

ADR-0111 had already settled the shape for the same job on certificates — a list, a Forget, and the file underneath staying the definition.

Decision

A "Repository signing keys…" window under Preferences ▸ Extensions, in the shape ADR-0111 gave accepted certificates: a hint, a list, a status line, Forget selected and Close. It sits under Extensions and not under Network, where ADR-0120 moved the certificates, because a certificate exception governs every https connection the core makes and a signing key is consulted by nothing but the Extensions window. The trust store is the GUI's, which is ADR-0124's argument for where the policy lives; the window belongs with it.

A row per recorded trust decision, carrying the scheme-less source it is filed under, the key's fingerprint, and the date it was trusted. The fingerprint is the core's to compute, since ADR-0124 put the public-key work in ssh-keygen on the host that fetches. Where that host has no usable tool the row falls back to the key type and a truncated base64 of the key itself, because a row still has to identify which key it is about, and a key printed in full is not something a person compares.

The seeded key is a row of its own, marked as built in. rio trusts its own key for its own repository through a fallback, so a first scan of that repository stores nothing, and a window listing only the file would be empty on a fresh install while rio does trust a key — the one thing the window exists to show. The row appears only while that repository is still in the sources list, since a key for a source the user removed speaks for nothing. It cannot be forgotten: selecting it says there is nothing stored to forget, and names Repositories… as what actually stops rio using that repository. The reason is given on selection rather than when the button is pressed, because a control that does nothing is worse than one that says beforehand why.

Forgetting is not distrust, and the window says so. After a key is forgotten the next scan trusts whatever that repository publishes then, exactly as the first scan did and exactly as deleting the section by hand always did. The window therefore introduces no trust state of its own: it is the hand edit ADR-0124 already invited, done for the user, and every verdict still comes from the same file.

Alternatives considered

Listing the keys under Preferences ▸ Network, beside the accepted certificates, so that everything about verified connections is in one place. Rejected: the two look alike and govern different scopes. An exception is the core's and applies to the agent as well; a signing key is the GUI's and applies to extension repositories only.

Leaving the built-in key out, on the ground that there is nothing stored for it and the window lists the store. Rejected: it makes the honest case — a fresh install that trusts exactly one key — look like a window with nothing in it, and teaches a user that an empty list means nothing is trusted.

Giving Forget a meaning on the built-in row: removing the repository, or recording a refusal that survives the next scan. Rejected on both counts. Removing a repository is what Repositories… does, and a recorded refusal would be revocation, which ADR-0124 deliberately does not have; the conf file has no way to express it, and the window must not be able to reach a state a hand edit cannot.

Consequences

  • What ADR-0124 records silently is now visible, and a trust decision can be taken back without finding a file. The file remains the definition; the window is a second way to reach it.
  • Forgetting a key puts that repository back on first use, with first use's one weakness: an attacker present on the next scan is not detected. That is the same trade ADR-0124 accepted, re-entered deliberately rather than by accident.
  • A GUI attached to a core whose host has no ssh-keygen can hold keys it cannot fingerprint, because the store is the GUI's and the tool is the core's. Such a host cannot use a signed repository anyway, so the rows are informational there.
  • ADR-0124's open item is closed. There is still no revocation, no expiry and no way to distrust a key other than removing its repository.