I’m not entirely opposed to TUF and can see the benefits to an incremental approach, but without end-to-end signing it looks like there is significant work for some modest initial benefits.
In its favor, I see a few benefits to Non-E2E TUF, first the ability to cryptographically validate packages have not been tampered with in transit from PyPI to disk. It prevents tampering by CDNs and mirrors and it looks like it can enable a recovery from a future compromise. As long as root.json
is bundled with the OS distribution of pip
, it looks like TUF removes the need for certificate pinning, otherwise I’m not sure how root.json
gets initialized. Finally, while TUF has some complexity, most of it looks like it can be hidden from developers and end-users.
On the other hand, as far as I can tell Non-E2E TUF does not help if PyPI has been compromised before the TUF deployment. It does not help if the person generating the timestamp
, snapshot
and bin
signing keys is compromised and it does not prevent PyPI from being legally compelled to modify packages, though it may help recover from some of these issues if they are discovered. It is unclear to me if Non-E2E TUF can prevent tampering with new uploads while an upload server is actively compromised.
Beyond TUF itself, in-toto was mentioned as part of the goal state and after reviewing the spec, I have a few concerns.
First, I can see the benefit of in-toto for audits and for scripts that are not compiled, but I’m having trouble seeing how it secures the build process from a compromise without some sort of byzantine CI. Further it is unclear how the root.layout
would specify a set of possible valid signing keys that could be used by multiple CI build servers. Edit: Although the example refers to the test step, it looks like this is handled with the threshold
field being set for builds.
While perhaps it works well for enterprises, the packaging trust delegation in root.layout flows backwards from common opensource practices where OS packagers trust developers, not the other way around. Would developers need to add the PyPI, Conda, Debian, RedHat, etc public signing keys into the package root.layout
? How would key updates for this be handled? or is packaging trust delegation just for running python ./setup.py bdist_wheel
on the CI server?
I’m unclear on the use of git tag -s
in the fetch-upstream example. Is it supposed to be git tag -v
?
Tooling can help, and maybe some of the files needed for in-toto can be generated automatically, but creating a root.layout
seems significant for non-enterprise developers wanting to upload packages to PyPI, much less debugging.
It seems reasonable that the root.json
can establish the initial set of trusted keys, it is unclear how TUF or in-toto would establish that a developers public key is associated with a package. Would PyPI provide this validation? How would developer key rotation be handled?
While I understand the enterprise use case for in-toto, if the person who writes, builds and uploads the package to PyPI is all the same person in most use cases, what is the benefit of in-toto over something like minisign?