PyPI security work: multifactor auth progress & help needed

A blog post about API tokens, with screenshots, is up at & mirrored to the PSF blog & tweeted. Please spread the word!

Heads-up for people trying the beta of uploading with API tokens:

  • The Travis problem in #6287 means we’ll probably be changing the token prefix and the username you use for uploads. We may also end up changing other stuff. It’s a beta!
  • Here’s where I’m tracking what we need to fix before I declare the beta done.

Summary: In the last two weeks, we’ve deployed a beta of the API upload key feature, and made more progress on accessibility and multifactor auth.

2FA: So, first off, thanks for helping spread the word about 2FA. The percentage of logins to PyPI that use 2-factor auth:

  • May overall: 2.25%
  • June overall: 3.08%
  • July overall: 4.54%
  • August so far: 11.61%

We aren’t out of the WebAuthn support beta yet because we’re still fixing stuff, like UI, instruction text, and email verification guidance, and the beta badge.

API tokens: We launched the beta of scoped upload API tokens and started getting the word out to get testing, and started fixing things like the syntax of the username and token prefix used to upload, and using normalized project names. On regular PyPI, 106 users have created a total of 123 tokens since launch. 55 tokens are scoped to a single project, while 68 are scoped with the same upload privileges as the creating user (permissions for all of the user’s projects). That’s very helpful as we shake the bugs out – thank you!

Audit log: We made initial decisions on our audit log architectural design and @woodruffw has a work-in-progress pull request that we’re reviewing now (doesn’t yet have UI/UX, or complete tests for results of event recording calls). I believe we’re on track to deploy a beta of this feature this month.

Accessibility: And we kept making accessibility improvements: removing directional copy, fixing a11y in project management tables, defining type on buttons, updating markup on the classifiers page, fixing a11y on the error/404 page, and so on. Pretty soon I’ll be coordinating with @nlhkabu to get some user testers, especially people who use screenreaders, to find the next round of issues.

Scope: We’re trying to keep things scoped pretty tight, so we confirmed that some nice-to-have features are out of scope for this grant.

Thanks: thanks to @alex_Gaynor, sayanarijit, serhii73, @hugovk, @pganssle, Dustin, Ernest, Donald, @webknjaz, graingert, and minho42 who contributed code or reviews recently, and thanks to @nedbat, jheld, Carreau, ZaxR, @ronaldoussoren, glyph, johnsyweb, & bryevdv for opening bugs!

How you can help:

  • Please keep an eye on your email if you have been testing API tokens. As we change token format, if you have a token that we’re invalidating, we’ll notify you.
  • If you or someone you know has accessibility needs for websites (vision, motor control, or otherwise), and might have 30 minutes for Nicole to walk through a user test with them, please introduce them to Nicole.

More in two weeks! Ongoing notes on the wiki.

1 Like

:white_check_mark: Orgs that automate uploads using continuous integration

Retested after

username: @token => __token__
password/token: pypi:<base64 token body> => pypi-<base64 token body>

  • Created a new API token on Test PyPI
  • Updated .travis.yml to use user: __token__ (no quotes this time)
  • Created the password with travis encrypt pypi-A... (again no quotes this time) and put in .travis.yml as password: secure: "S..."
  • Pushed a commit, and it deployed successfully to Test PyPI

:white_check_mark: Orgs that automate uploads using continuous integration

And still working (on Test PyPI) after the old @token/pypi: cases have been removed from Warehouse (

You can now see logs of sensitive events for your user account, and for projects you own, on PyPI and Test PyPI! It’s a new beta feature so please test it and tell us about bugs.

Blog post with more details, things to test. Known issue: we don’t yet log failed authentication attempts.

1 Like