Skip to content

How do we ship root TUF metadata for a repository? #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
phenaproxima opened this issue Mar 8, 2021 · 4 comments
Closed

How do we ship root TUF metadata for a repository? #7

phenaproxima opened this issue Mar 8, 2021 · 4 comments

Comments

@phenaproxima
Copy link
Collaborator

phenaproxima commented Mar 8, 2021

From the TUF spec:

5.0. Load the trusted root metadata file. We assume that a good, trusted copy of this file was shipped with the package manager or software updater using an out-of-band process.

Since this plugin assumes that Composer-facing package metadata is protected by TUF, the question now comes up: how do we plan to ship this root metadata for a given repository?

I think the original idea was to ship it with Drupal core. The problem, though, is that the plugin doesn't know the path to Drupal core. Normally, of course, we would use Composer's installer system to figure that out. But installers operate on fully loaded packages (i.e., instances of PackageInterface), which are yielded by a RepositoryInterface implementation, such as the one this plugin provides. But the plugin cannot load any packages until it has updated the TUF metadata. Which it can't do until it has some root metadata to start with. This vicious circle means that we cannot load the starting root metadata from a dynamically-computed package path.

How will we solve this? I don't know, but this is a brainstorming/discussion issue to figure it out.

Two possible ideas that have been floated so far:

  1. We could use a "centralized registry" pattern. For example, each TUF-aware repository could have a pre-assigned, publicly known UUID, and the plugin could include the starting root metadata for that repository shipped with it. Then, in your project's composer.json, you could opt a specific repository into TUF with something like this (you'd be able to find out the repository's TUF ID in advance):
"repositories": {
  "drupal": {
    "url": "https://packages.drupal.org/8",
    "type": "composer",
    "tuf": "REPOSITORY_TUF_ID_HERE"
  }
}

A major downside here is that, any time a public Composer repository wants to be able to opt into working with TUF, they'd need to submit a pull request to this plugin to add their root metadata to it. And what would private repositories do?
2. The plugin could provide a command which would help you configure the absolute path to some root metadata. For example:

$ composer run tuf:repository:add composer https://packages.drupal.org/8 /path/to/root/metadata.json

A possible downside here is that you'd have to get the root metadata somehow, so either you'd already need to have Drupal core installed, or you'd grab the root metadata from somewhere on the Internet first. Also, the path could vary across environments.

More thoughts and ideas would be very, very welcome! Bring on the big brain brigade.

@davidstrauss
Copy link

The problem, though, is that the plugin doesn't know the path to Drupal core.

I feel like the trusted root data should be part of what we distribute either with the plugin or composed Drupal tarball. Even in the latter case, it's less a Drupal thing and more of a Composer thing.

A possible downside here is that you'd have to get the root metadata somehow, so either you'd already need to have Drupal core installed, or you'd grab the root metadata from somewhere on the Internet first. Also, the path could vary across environments.

It needs to get distributed with however they acquire Drupal or the TUF Composer plugin itself.

I'd like to propose a third option: put the initial root keys directly into the composer.json as part of the repository configuration. Updates to the keys would need to be elsewhere, but it would cleanly solve the bootstrapping. If it's too unwieldy to include the keys directly, we could include a hash and root.json version. The client can then pull its initial root data from the server (and validate with the hash) and then update from there. The hash approach might also reduce confusion around the data being for bootstrapping only (rather than the current trusted roots).

@davidstrauss
Copy link

It would also be neat (but certainly not required) to have a command/option in the TUF plugin to freshen composer.json data for trusted roots to pin to the latest data. It's often nice to freshen a pinning like that as a sort of threshold that prevents even more rollback scenarios.

@phenaproxima
Copy link
Collaborator Author

phenaproxima commented Apr 15, 2021

If it's too unwieldy to include the keys directly, we could include a hash and root.json version. The client can then pull its initial root data from the server (and validate with the hash) and then update from there.

I implemented this in #18, mostly as an academic exercise. What do you think? From a simplicity and security standpoint, I'd prefer to embed the stuff directly into composer.json. But depending on how much stuff we'd need to embed, that is almost certainly going to be unwieldy, and it just transfers the burden of trickiness to the people who want to use this.

@phenaproxima
Copy link
Collaborator Author

Fixed in #23.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants