Does python's pip provide cryptographic authentication and integrity validation?

The short answer is: pip always uses TLS, which is actually fairly useful here. It means that as long as no-one's managed to compromise PyPI itself or steal the site certificate, then you can be certain that the packages you download are the ones that the PyPI admins think are correct. And it's hard to do better than that: after all, the PyPI admins are the only ones who know which users are allowed to upload which packages, so you kind of have to trust them.

As match mentions, there also used to be a way to upload PGP signatures for packages. However, that's been removed, since it was basically just security theater – complicated and makes it feel like you're being secure, but doesn't actually improve security. One of PyPI's main admins has an old post about this: https://caremad.io/posts/2013/07/packaging-signing-not-holy-grail/

What would be better is to use a framework like TUF that can provide guarantees like: "the person who uploaded this was trusted by the PyPI admins at the time of upload, and if PyPI is compromised afterwards then the attacker can't go back and change anything that happened before the compromise". TUF is roughly similar to the package signing used by linux distributions, but a bit more powerful. The PyPI maintainers got a grant to implement this and work is in progress now: https://wiki.python.org/psf/PackagingWG#Warehouse:_Facebook_gift

One challenge is that to bootstrap a cryptographic system like this, you need a key signing ceremony, which was going to take place in-person at PyCon this year... but, well. Please be patient :-)

In the mean time, you can get a similar effect locally by putting package hashes into your requirements.txt: this guarantees that if an attacker somehow sneaks in a fake package after you ran this command, it will be rejected. Or some dependency management tools like pipenv or poetry will do this for you automatically.


Sort of...

Firstly, Pypi includes a hash of the file being downloaded, so that any modifications/errors between server and client will be spotted.

Secondly, pip has support for a hash-checking mode where you can specify the required hash for the requested package in requirements.txt in the form:

Foo==1.2.3 --hash=sha256:xxxxxxx

pip will then verify that the downloaded package hashes to this value, and errors if it doesn't. https://pip.pypa.io/en/stable/reference/pip_install/#hash-checking-mode

Thirdly, Pypi has a mechanism where a signature can be uploaded along with a package. twine has support for this.

You can then download the signature alongside the package and verify it. The signature file is found at the same url, but with .asc appended - e.g. https://pypi.python.org/packages/py2.py3/p/pip/pip-7.1.2-py2.py3-none-any.whl and it's signature in https://pypi.python.org/packages/py2.py3/p/pip/pip-7.1.2-py2.py3-none-any.whl.asc

You can manually do the verification by downloading both files and running e.g.

gpg --verify mypackage.whl.asc mypackage.whl

However at present there isn't a mechanism built into the pip tools to do this step automatically on your behalf - though there has been discussion of this as a much-needed feature on several occasions recently among developers.