Repository navigation
Description
At the moment we only identify repositories by their user-facing names, which will become problematic once we want to start dealing with composability (repository links #73) and providing information about repositories to other parties (such as for systemd-report purposes) because repository names are fundamentally a local-only concept with no real way of validating them.
For links it would be much better to only instantiate one client and only do a single refresh per repository, as well as potentially making it easier to handle problems like auth, and for systemd-report consumers it will be incredibly useful to be able to categorise repositories using globally unique identifiers.
The only really obvious choice is to use a cryptographic hash of 1.root.json, because:
- It is transport-agnostic.
- Conceptually it defines the initial repository identity. (We already implicitly treat the signing key set as an identity in Quarry, especially on the publishing side.)
- It doesn't require any extensions to TUF.
- It is not something a malicious repository can manipulate directly without a pre-image attack (other ideas like generating a UUID and putting it in the
1.root.jsonsuffer from malicious repositories being able to publish the same identifier).
Once we do the <meta> stuff for self-describing repositories we will likely want to be able to include the identity hash in the <meta> tag.
However, there are some issues with this proposal:
- We need to now store
1.root.jsonon the client (and transmit it in cases like cross-repo links) so that it can independently derive the identifier. But that is not enough -- a malicious repository could provide anN.root.jsonthat is not actually signed with a valid chain from1.root.jsonto impersonate a repository. So we also need to emulateroot.jsonupgrades up to the currentN.root.jsonon first fetch when figuring out the repository identity to make sure that the signature chain is really valid. Forroot_trust = { type = "bundled", ... }we probably should change the structure so that we keep all historicalroot.jsons to avoid post-key-compromise attacks. - The ideas for using prefix-based matching for AuthN/AuthZ providers (as mentioned in tufclient: authenticate repo requests as this machine #82 (comment)) is kind of dead in the water. I guess we would need to instead restrict it based on which domains we are contacting...?
- We probably should hash the canonicalised JSON rather than just using the original bytes so that we don't end up with fragile setups.
- There is now an incentive for an attacker to compromise the initial
1.root.jsonkeys even after rotation, since a fully broken1.root.jsonmight allow you to impersonate that repository... Maybe this is a serious enough issue to warrant a different design?
Activity
pothos commentedon Nov 9, 2026
Requiring that different repos use different root keys means disallowing as policy instead of convention. Isn't this too strict and could lead to subtle issues?
I wonder if a UUID would help or if a fixed free form name that's not mentioning the domain would be good enough?