3 ms·
> However, what they call trusted publishing is just a configuration where PyPI tells github that publishing from a particular workflow name on a particular rep
by woodruffw 3y ago
> However, what they call trusted publishing is just a configuration where PyPI tells github that publishing from a particular workflow name on a particular repository is ok, without further tokens. So PyPI "trusts" github actions and the maintainer is out of the loop.
That isn’t quite how trusted publishing works: it’s morally equivalent to trusting GitHub with your manually configured API token, except GitHub mints the token using its own publicly verifiable key material.
In other words: it’s no more trusting of GitHub than manually configuring a secret would be, but is significantly more misuse and compromise resistant (since the minted API token is auto-expiring and minimally scoped to whatever project the repo is linked to).
You’re right that this does not itself involve reproducibility or maintainer signoff. But signoff is something you can configure for yourself on GitHub releases (which PyPI cannot meaningfully enforce), and reproducibility is a distant ecosystem-sized goal at this point. Lashing trusting publishers to either would have meant making the perfect the enemy of the good.
(It’s also something we’re working on, by exposing cryptographic publish attestations tied to the trusted publisher. That is still being designed, but I hope to have more to share publicly soon.)
Source: I implemented PyPI’s trusted publishing.
- guappa 3y ago> but is significantly more misuse and compromise resistant I don't think it is at all. Without it, I have a supersecret token.txt file on my machine. With it, I have a supersecret .ssh/ directory, which grants access to do a git tag, which will publish without needing to know the pypi secrets at all. You just moved the secret into another file. Am I wrong? Can you explain how am I wrong if you think so?
- woodruffw 3y ago> With it, I have a supersecret .ssh/ directory, which grants access to do a git tag, which will publish without needing to know the pypi secrets at all. That isn't how trusted publishing works. It uses OpenID Connect, which both requires a privileged workflow (in the case of GitHub) and is itself self-expiring. There's a lot of information available in PyPI's documentation about how it works[1]. But the basic version is that short-lived tokens always reduce attacker exposure, since they prevent a temporary compromise from becoming a permanent one (i.e., via theft of a long-lived credential). Similarly, auto-scoped credentials always reduce credential misuse, since they prevent users from over-scoping their API tokens to get things to "just work." Both were observed issues on PyPI prior to trusted publishing, and were a huge part of both the original API token and 2FA rollouts. [1]: https://docs.pypi.org/trusted-publishers/ https://docs.pypi.org/trusted-publishers/
- guappa 3y agoOnce you configure all the CI and everything, following the documentation. Isn't the documentation giving the advice to make it publish automatically on a git tag? And isn't it true that to do a git tag you only need to steal the private ssh keys of the account, which are commonly stored in the ~/.ssh directory? If I am the attacker, and a project has trusted publishing configured, my target shifts from the token.txt file on the machine of a maintainer, to the .ssh directory on the very same machine. You can do all the complicated authentication schemes between github and pypi, but do I care to attack there when there's a much easier point to attack? I have set up trusted publishers for one of my projects. At least from the point of view of a user I am familiar with it. A git tag followed by a push did indeed trigger a new build+release workflow in my CI.
- woodruffw 3y agoThese are different layers: trusted publishing doesn't know how you store your git credentials, and PyPI isn't able to be prescriptive there. The recommendation that you publish from a tag is just normal release hygiene stuff; PyPI cannot make you use the other parts of your computer safely. The scenario you're talking about ("attacker has your SSH private key") is already a "game over" scenario, and is tantamount to the attacker assuming your identity. Trusted publishing is not aimed at that scenario; it's aimed at eliminating other scenarios (such as people using permanent user-scoped tokens everywhere, making it easier for an attacker to move laterally after compromising a single token). Or in other words: not every attacker is empowered to assume my identity by stealing my SSH key (which lives in a security module for me, not in `~/.ssh`). That's a very strong attacker model; there are other, weaker attacker models that are still worth defending against (such as someone who opportunistically compromises a single CI run, or takes advantage of a one-time accidental API token leak). Edit: and note: the documentation for trusted publishing encourages you to use a release environment on PyPI, which can be configured to require multi-user signoff. So you can use it to prevent a stolen SSH key from compromising your uploaded project. But again, that is the strongest possible adversary, and is not the most common one that users need protecting against.
- 3y ago
- kzrdude 3y agoSounds exciting with the coming features! About trust. I would say, the firmer the structure of configurations is, the more trust I'm giving over to Github vs handling it myself. Is Github actions a neutral VM executor that I can configure as I want to? Or does it have slot-ins for lots of different services? You are probably right that it is morally equivalent, but there is some material difference - Github now has a database of all their python-publishing repositories.