-
Notifications
You must be signed in to change notification settings - Fork 932
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
Update distributing guide to prefer twine's keyring support, and discourage use of pypirc #297
Comments
I think this might actually be doable now. |
@glyph what would it take for twine to be able to put a password in the keyring? |
@takluyver may know, as I believe flit already does this (at least on Linux). |
Yup, flit uses keyring on all platforms, so long as it's available (it's a soft dependency). My strategy is to first try various means to get a stored or provided password. If none is found, we prompt the user, and then if The main UI weakness I'm aware of is that flit provides no mechanism to change the stored password; if you type it wrong, or change it later, you have to go through whatever mechanism the platform provides to change or remove it. I hope that twine is storing the passwords in a similar way so that both tools can use one stored password. |
@ncoghlan after discussing with Sumana on IRC about the security implications of |
I think something like |
+1 from me for moving towards platform credential storage support. We have
that freedom now that we're not dependent on the standard library for
upload management.
|
Here's a blog post I did on how to prevent .pypirc from being leaked for reference: http://mbacchi.github.io/2017/12/22/3-ways-prevent-secret-leaks-github.html FYI @brainwane |
Thank you, @mbacchi! very helpful. |
I'm on Debian 9.3 (stretch, e.g., stable) and today I successfully made a username/password/website credential available for I followed, basically, the instructions for Ubuntu 16.04 plus @jaraco's explanation in pypa/twine#208 (comment) , and everything worked out. Starting in a Python 3 virtualenv, and eliding a lot of output and a test
My opinion: we should put a variant of this into the uploading tutorial and the guide to using Test PyPI, with adjustments for the user's OS. |
I want to reiterate a comment I made here:
To be more explicit, the following lines (run anywhere, not just from within twine) would give @brainwane back the password in plaintext: >>> import keyring
>>> keyring.get_password('https://test.pypi.org/legacy/', 'brainwane') I don't really see the value in putting this in the guide unless it's at least marginally more secure that keeping a password in EDIT: Perhaps this is all understood, and it could be argued that using the keyring over |
It doesn't protect against untrusted code running in your user account, but storing the password in the keyring is an improvement in other ways:
There's arguably also a psychological reason: putting PyPI passwords in a plaintext config file signals that they're not that important. Using a specific mechanism for storing secrets would suggest that PyPA thinks how you store your password matters. We definitely shouldn't see using keyring as the end of the road on this. Glyph has done some work on getting the credentials from a password manager, for instance. And hopefully Warehouse will add features like tokens to upload a specific project. But if we can recommend keyring rather than storing passwords in |
All great points @takluyver. Consider me convinced, and thanks for laying out an explanation. |
We'll be publicizing pypi.org widely probably within the next two weeks, and I would very much welcome help on this, so the packaging guide (which we link to consistently within https://pypi.org/help/ and elsewhere on the site) mentions I've just put out a new release of twine and would be happy to put out a point release that includes command-line help with |
I'm working towards getting Twine 1.10.1 out in the next few days and would strongly welcome doc improvements related to |
Twine 1.11.0 is now out and includes guidance in the @jonparrott and I have, in our experience, run into hiccups in getting |
Hey all, I'm a bit new to python packaging and have a general question about this particular bit of the docs, no idea about the best way to ask but this issue seems to be the most relevant place The docs mention that one should install twine and run I was thinking I'd pop over here and make a PR to add the setup-upload info to the docs and found this thread, so I hope it doesn't hurt to ask |
@jaktonik Depending on exactly which Python environment you're using, the native distutils upload may happen over HTTP, exposing your PyPI password as cleartext. There's also some newer metadata fields which distutils on its own won't extract and publish correctly, but twine makes sure are handled. We should add that info as a footnote on https://packaging.python.org/guides/tool-recommendations/, perhaps by linking out to https://twine.readthedocs.io/en/latest/#why-should-i-use-this |
Hello wonderful people! 👋 I feel like the section in the python packaging guide about storing your password in plaintext in pypirc should be removed immediately. It's a separate issue of if twine keyring support is ready for everyone, or if alternative instructions are ready. https://packaging.python.org/guides/using-testpypi/?highlight=username#setting-up-testpypi-in-pypirc The note about setting permissions 'properly' is also not good advice. Instead it should just say The important part is removing the recommendation on storing passwords like this as soon as possible. |
Here's where the python docs talk about storing the password in pypirc: https://docs.python.org/3/distutils/packageindex.html#the-pypirc-file |
Hi @illume, feel free to see a pull request! |
Thanks @theacodes :) |
The Python docs now no longer mention I'm having trouble figuring out when, but someone removed the |
I think the relevant file is |
Checking in on the desired outcome of this issue. I've been passively tracking issues related to twine and credentials (most recently pypa/packaging-problems#313). My sense is that the documentation around Here is a list of possible next steps, which I hope prompts folks with opinions to chime in. :)
The entry point for help using API tokens seems to be https://pypi.org/help/#apitoken (source), or the token management page (source). Both suggest storing the token in
Compare that to https://packaging.python.org/guides/using-testpypi/#setting-up-testpypi-in-pypirc:
Reading over this issue, it seems the preferred solution is to use keyring. However, keyring doesn't seem to be documented in this repo or in warehouse. It's introduced at https://twine.readthedocs.io/en/latest/#keyring-support. I haven't seen any mention of how to use keyring with API tokens (though I suspect it'd be to use Furthermore, there doesn't seem to be centralized documentation of |
Related: #628 and pypa/twine#496 re: project-scoped API tokens. The suggestion seems to be to configure "proxy" repositories for each project, with distinct tokens. I haven't investigated if/how those are supported by twine when using keyring. Maybe @jaraco has a quick answer? |
I did some investigation, and it's not obvious how to use multiple project API tokens with twine and keyring: pypa/twine#565. |
The twine/keyring integration assumes one password per user and index. What keyring needs to support multiple credentials is some way to distinguish the tokens by project name. Perhaps instead of relying on Per-project credentials wasn't considered in the original design, so a new design is called for. |
For flit, I was planning to stuff the project name associated with a token into the 'username' for keyring, e.g. I know the secret storage protocol offered by Gnome allows for arbitrary key-value metadata associated with a secret, which can be used to look it up. In principle, this would be a neat way of storing a token scope, but it would only work for keyring if there are similar mechanisms on all supported platforms. |
+1 to having a common scheme shared by all tools. Just please don't require the 'project' to be specified. For a person managing a single project or two, that's fine, but where many projects share a token, you want keyring to store that credential exactly once. Perhaps |
I might go for something like I guess the precise details depend on whether this is something you expect users to see or enter manually, or more of an implementation detail. I'm hoping there will one day be an API to create a token (pypi/warehouse#6396 ), so if there isn't already a suitable token in keyring, the user can be prompted for their password (& 2FA), and it obtains and stores a new project-scoped token (rather than storing the password). |
I think it's a mistake to assume a token is uniquely associated with either a user or a project. A user can create a token for any purpose. For example, consider the tokens configured on my account: I've created two tokens with the "all projects" scope, and another which I created for a specific project, but I could imagine in the future PyPI might even offer a scope for an organization or other subset of projects. What I think is needed here is a separate designator that the user could use for any purpose to select a key other than the default. Perhaps the designator could be Also important, I'm not sure |
It's cool to see this discussion evolve. Thanks for diving in. Here are some thoughts from a relative newcomer to the packaging ecosystem. I tend to agree with @jaraco's take. To me, it seems like the key for distinguishing a token is its "Name", rather than its "Scope". Furthermore, this already works in twine for "All projects" tokens:
With that in mind, I like the optional
keeping in mind that the suffix doesn't need to equal the "Name" on PyPI; it's just a local identifier for distinguishing it to keyring. There's a related discussion starting at pypa/twine#496 (comment) re: how to use project-scoped tokens in |
I understand that tokens are more complicated than my idea encompasses. But I'm thinking about how tools are practically going to use them: it needs to be reliable and efficient to find the token to use to upload a given project. Keyring doesn't have any API to search for several credentials at once, and I assume it's not easy to add that given its cross-platform, extensible nature. So we have to do a small number of specific lookups - in my thinking, we'd check for a per-project token, and if it's not found, fall back to trying a per-user token. It makes sense to allow putting the tokens in |
Hoping to keep the discussion going, and possibly for clarification, here's the CLI workflow that I'm imagining, keeping in mind that this could be streamlined with Account token (works today):
Project token (proposed in pypa/twine#565):
Another idea from pypa/twine#565, combined with one from @di in pypa/twine#496 (comment), would be for Twine to use the repository name, instead of the URL, for the keyring lookup: Account token:
Project token:
However, that's a more substantial change to Twine. |
@takluyver's suggested approach seems reasonable to me: if the given username is exactly If the given username is something else, even if it starts with |
With this approach, I'm having trouble visualizing the commands that a package maintainer would use to set an account and/or project token in keyring, and then use one of those tokens to upload their package with twine. Could somebody provide an example? |
This can't be done until this upstream issue is resolved: pypa/twine#216
Original context: #271 (comment)
The text was updated successfully, but these errors were encountered: