-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Description
Description
Originally, the GitHub CLI only supported writing the token during obtained auth login, insecurely to a file. In fact it was only February 2023 that gh began using keyrings for secure storage. When this was added, it was opt-in via --secure-storage because the team didn't want to break existing workflows. Later, this was made the default and the previous insecure behaviour was opt in via --insecure-storage. In order to avoid breaking anyone who didn't have a system keyring set up correctly, gh would fallback to the insecure storage if the keyring was unavailable.
We've had so many issues of people complaining about gh falling back to insecure storage, not being particularly transparent about doing that, and gh giving no indication of why the secure storage didn't work (because the error is swallowed) that I think we should do something about it:
- gh auth saves plain text token, even though I have keyring #8954
- Clarify "an authentication token will be stored internally" -- where is the token stored? #5961
It would be nice to have telemetry on:
- How many / what percentage of people currently rely on the fallback behaviour of
auth login.
However, in the absence of this, my gut feeling is that it may still be a breaking change worth making, with a clear path to fixing users who are broken (--insecure-storage and possibly a config option), particularly in the interactive case.
What Options are on the Table?
Non-Interactivity
I don't think it's acceptable to break scripts out there that are calling gh auth login --with-token on environments that don't have a keyring available. However, we can consider some mitigations and nudges:
- We could add a
--no-insecure-fallbackoption for users who really, really don't want this to happen - We could add a
no_insecure_fallbackconfig option forgh configthat makes it persistent - We could add a warning on stderr, just in case someone looks at their script output and realises that something unexpected is happening
Interactivity
With the interactive flows we have a bit more flexibility around changing behaviour. I think there are three paths we could take here, each with a different tradeoff of safety vs convenience.
--no-insecure-fallback/no_insecure_fallback idea from above
As above, we could allow users to opt-in to turning this off. The downside of course is that this is opt-in, which even with the warning, still ends up with your token potentially being written to disk.
Re-prompt
On a failure to use the keyring we could offer a prompt along the lines of:
Failed to save the token securely due to <err>
Would you like to continue with insecure storage (y/N) ?
This is informative and allows for immediate recovery, which is nice since the user has probably gone through a whole oauth dance already.
Error
On a failure to use the keyring we could error out with the reason.
This might be immediately annoying to a user, but it's a pretty big nudge that they need to start using --insecure-storage from now on, which should be high friction.
My Recommendation
I think I would probably favour all the non-interactive options, and the last of the interactive options (erroring). I don't love that it's not "secure by default" across the board but I really can't see any way in which we can accept breaking the non-interactive usage, which could be large.
Both the re-prompt and error options would also help provide clarity to why keyring operations are failing, since the error is currently suppressed.