Add documentation for multiple accounts
This commit is contained in:
parent
0763c1d4a7
commit
21d94165bb
1 changed files with 237 additions and 0 deletions
237
docs/multiple-accounts.md
Normal file
237
docs/multiple-accounts.md
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
# Multiple Accounts with the CLI - v2.40.0
|
||||
|
||||
Since its creation, `gh` has enforced a mapping of one account per host. Functionally, this meant that when targeting a
|
||||
single host (e.g. github.com) each `gh auth login` would replace the token being used for API requests, and for git
|
||||
operations when `gh` was configured as a git credential manager. Removing this limitation has been a [long requested
|
||||
feature](https://github.com/cli/cli/issues/326), with many community members offering workarounds for a variety of use cases.
|
||||
A particular shoutout to @gabe565 and his long term community support for https://github.com/gabe565/gh-profile in this space.
|
||||
|
||||
With the release of `v2.40.0`, `gh` has begun supporting multiple accounts for some use cases on github.com and
|
||||
in GitHub Enterprise. We recognise that there are a number of missing quality of life features, and we've opted
|
||||
not to address the use case of automatic account switching based on some context (e.g. `pwd`, `git remote`, etc) though
|
||||
we hope many of those using these custom solutions will now find it easier to obtain and update tokens (via the standard
|
||||
OAuth flow rather than as a PAT), and to store them securely in the system keyring managed by `gh`.
|
||||
|
||||
We are by no means excluding these things from ever being native to `gh` but we wanted to ship this MVP and get more
|
||||
feedback so that we can iterate on it with the community.
|
||||
|
||||
## What is in scope for this release?
|
||||
|
||||
The support for multiple accounts in this release is focused around `auth login` becoming additive in behaviour,
|
||||
allowing for multiple accounts to be easily switched between using the new `auth switch` command. Switching the "active"
|
||||
user for a host will swap the token used by `gh` for API requests, and for git operations when `gh` was configured as a
|
||||
git credential manager. We have extended the `auth logout` command to switch the active user where possible if the
|
||||
current active user has been logged out. Finally we have extended `auth token`, `auth switch`, and `auth logout` with a
|
||||
`--user` flag. This new flag in combination with `--hostname` can be used to disambiguate accounts when running
|
||||
non-interactively.
|
||||
|
||||
Here's an example usage. First, we can see that I have a single acocunt `wilmartin_microsoft` logged in, and
|
||||
`auth status` reports that this is the active account:
|
||||
|
||||
```
|
||||
➜ gh auth status
|
||||
github.com
|
||||
✓ Logged in to github.com account wilmartin_microsoft (keyring)
|
||||
- Active account: true
|
||||
- Git operations protocol: https
|
||||
- Token: gho_************************************
|
||||
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
|
||||
```
|
||||
|
||||
Running `auth login` and proceeding through the browser based OAuth flow as `williammartin`, we can see that
|
||||
`auth status` now reports two accounts under `github.com`, and our new account is now marked as active.
|
||||
|
||||
```
|
||||
➜ gh auth login
|
||||
? What account do you want to log into? GitHub.com
|
||||
? What is your preferred protocol for Git operations on this host? HTTPS
|
||||
? How would you like to authenticate GitHub CLI? Login with a web browser
|
||||
|
||||
! First copy your one-time code: A1F4-3B3C
|
||||
Press Enter to open github.com in your browser...
|
||||
✓ Authentication complete.
|
||||
- gh config set -h github.com git_protocol https
|
||||
✓ Configured git protocol
|
||||
✓ Logged in as williammartin
|
||||
|
||||
➜ gh auth status
|
||||
github.com
|
||||
✓ Logged in to github.com account williammartin (keyring)
|
||||
- Active account: true
|
||||
- Git operations protocol: https
|
||||
- Token: gho_************************************
|
||||
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
|
||||
|
||||
✓ Logged in to github.com account wilmartin_microsoft (keyring)
|
||||
- Active account: false
|
||||
- Git operations protocol: https
|
||||
- Token: gho_************************************
|
||||
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
|
||||
```
|
||||
|
||||
Fetching our username from the API shows that our active token correctly corresponds to `williammartin`:
|
||||
|
||||
```
|
||||
➜ gh api /user | jq .login
|
||||
"williammartin"
|
||||
```
|
||||
|
||||
Now we can easily switch users using `gh auth switch`, and hitting the API shows that the active token has been
|
||||
changed:
|
||||
|
||||
```
|
||||
➜ gh auth switch
|
||||
✓ Switched active account for github.com to wilmartin_microsoft
|
||||
|
||||
➜ gh api /user | jq .login
|
||||
"wilmartin_microsoft"
|
||||
```
|
||||
|
||||
We can use `gh auth token --user` to get a specific token for a user (which should be handy for automated switching
|
||||
solutions):
|
||||
|
||||
```
|
||||
➜ GH_TOKEN=$(gh auth token --user williammartin) gh api /user | jq .login
|
||||
"williammartin"
|
||||
```
|
||||
|
||||
Finally, running `gh auth logout` presents a prompt when there are multiple choices for logout, and switches account
|
||||
if there are any remaining logged into the host:
|
||||
|
||||
```
|
||||
➜ gh auth logout
|
||||
? What account do you want to log out of? wilmartin_microsoft (github.com)
|
||||
✓ Logged out of github.com account wilmartin_microsoft
|
||||
✓ Switched active account for github.com to williammartin
|
||||
```
|
||||
|
||||
## What is out of scope for this release?
|
||||
|
||||
As mentioned above, we know that this only addreses some of the requests around supporting multiple accounts. While
|
||||
these are not out of scope forever, for this release some of the big things we have intentionally not included are:
|
||||
* Automatic account switching based on some context (e.g. `pwd`, `git remote`, etc)
|
||||
* Automatic configuration of git config such as `user.name` and `user.email` when switching
|
||||
* User level configuration e.g. `williammartin` uses `vim` but `wilmartin_microsoft` uses `emacs`
|
||||
|
||||
## What are some sharp edges in this release?
|
||||
|
||||
As in any MVP there are going to be some sharp edges that need to be smoothed out over time. Here are a list of known
|
||||
sharp edges in this release.
|
||||
|
||||
### Data Migration
|
||||
|
||||
The trickiest piece of this work was that the `hosts.yml` file only supported a mapping of one-to-one in the host to
|
||||
account relationship. Having persistent data on disk that required a schema change presented a compatability challenge
|
||||
both backwards for those who use [`go-gh`](https://github.com/cli/go-gh/) outside of `gh`, and forward for `gh` itself
|
||||
where we try to ensure that it's possible to use older versions in case we accidentally make a breaking change for users.
|
||||
|
||||
As such, from this release, running any command will attempt to migrate this data into a new format, and will
|
||||
additionally add a `version` field into the `config.yml` to aid in our future maintainability. While we have tried
|
||||
to maintain forward compatability (except in one edge case outlined below), and in the worst case you should be able
|
||||
to remove these files and start from scratch, if you are concerned about the data in these files, we advise you to take
|
||||
a backup.
|
||||
|
||||
#### Forward Compatability Exclusion
|
||||
|
||||
There is one case using `--insecure-storage` that we don't maintain complete forward and backward compatability. This
|
||||
occurs if you `auth login --insecure-storage`, upgrade to this release (which performs the data migration), run
|
||||
`auth login --insecure-storage` again on an older release, then at some time later use `auth switch` to make this
|
||||
account active. The symptom here would be usage of an older token (which may for example have different scopes).
|
||||
|
||||
This occurs because we will only perform the data migration once, moving the original insecure token to a place where
|
||||
it would later be used by `auth switch`.
|
||||
|
||||
#### Immutable Config Users
|
||||
|
||||
Some of our users lean on tools to manage their application configuration in an immutable manner for example using
|
||||
https://github.com/nix-community/home-manager. These users will hit an error when we attempt to persist the new
|
||||
`version` field to the `config.yml`. They will need to ensure that the `home-manager` configuration scripts are updated
|
||||
to add `version: 1`.
|
||||
|
||||
___
|
||||
|
||||
Meta: Draft text for home-manager issue:
|
||||
|
||||
## Description
|
||||
|
||||
In `gh` v2.40.0, we are going to be releasing initial support for [multiple accounts](https://github.com/cli/cli/issues/326)
|
||||
on a single host. As part of this process there is a migration of on-disk data and we will be adding a `version` field
|
||||
with value `1` to the `config.yml` file.
|
||||
|
||||
I'm not too familiar with `nix` or how people use it, so I'm not sure if the following is even an expected workflow. If
|
||||
it is expected that you can update the version of `gh` in place without regenerating the `config.yml` file from
|
||||
`home-manager` scripts it is likely that users will run into an error when `gh` tries to write the `config.yml` file.
|
||||
|
||||
Although it's our position that `gh` manages its own configuration file, we also try not to break users that choose to
|
||||
configure their systems this way. Unfortunately, in this case we value the future maintainability of having this
|
||||
`version` to support future migrations should we need them.
|
||||
|
||||
As such, this is just an informative issue for people to find that this new field will be required to perform any operations
|
||||
with v2.40.0. Since I'm not totally sure on the workflows used in this project, here are some possible workarounds:
|
||||
1. Temporarily allow writing to `config.yml` one time so that this `version` can be written
|
||||
1. After seeing a failure, install updated `home-manager` scripts with `version: 1` declared in the config
|
||||
1. Update the `home-manager` scripts with `version: 1` declared in the config and then blow everything away and start with v2.40.0 from scratch
|
||||
|
||||
To me it feels like option `3` is the easiest, since home manager enforces config to already be defined, the only consequence
|
||||
will be requiring `gh auth login` to be run for any accounts that were removed when blowing it all away.
|
||||
|
||||
We apologise for the inconvenience.
|
||||
___
|
||||
|
||||
### Auth Refresh
|
||||
|
||||
Although this has always been possible, the multi account flow increases the likelihood of doing something surprising
|
||||
with `auth refresh`. This command allows for a token to be updated with additional or fewer scopes. For example,
|
||||
in the following example we add the `read:project` scope to the scopes for our currently active user `williammartin`,
|
||||
and proceed through the OAuth browser flow as `williammartin`:
|
||||
|
||||
```
|
||||
➜ gh auth refresh -s read:project
|
||||
? What account do you want to refresh auth for? github.com
|
||||
|
||||
! First copy your one-time code: E79E-5FA2
|
||||
Press Enter to open github.com in your browser...
|
||||
✓ Authentication complete.
|
||||
|
||||
➜ gh auth status
|
||||
github.com
|
||||
✓ Logged in to github.com account williammartin (keyring)
|
||||
- Active account: true
|
||||
- Git operations protocol: https
|
||||
- Token: gho_************************************
|
||||
- Token scopes: 'gist', 'read:org', 'read:project', 'repo', 'workflow'
|
||||
|
||||
✓ Logged in to github.com account wilmartin_microsoft (keyring)
|
||||
|
||||
✓ Logged in to github.com account wilmartin_microsoft (keyring)
|
||||
- Active account: false
|
||||
- Git operations protocol: https
|
||||
- Token: gho_************************************
|
||||
- Token scopes: 'gist', 'read:org', 'repo', 'workflow'
|
||||
```
|
||||
|
||||
However, what happens if I try to remove the `workflow` scope from my active user `williammartin` but proceed through
|
||||
the OAuth browser flow as `wilmartin_microsoft`?
|
||||
|
||||
```
|
||||
➜ gh auth refresh -r workflow
|
||||
|
||||
! First copy your one-time code: EEA3-091C
|
||||
Press Enter to open github.com in your browser...
|
||||
error refreshing credentials for williammartin, received credentials for wilmartin_microsoft, did you use the correct account in the browser?
|
||||
```
|
||||
|
||||
When adding or removing scopes for a user, the CLI gets the scopes for the current token and then requests a new token with the requested amended scopes. Unfortunately, when we go through the account switcher flow as a different user, we end up getting a token for the wrong user with surprising scopes. We don't believe that starting and ending a `refresh` as different users is
|
||||
a user case we wish to support and has the potential for misuse. As such, we have begun erroring in this case.
|
||||
|
||||
Note that a token has still been minted on the platform but `gh` will refuse to store it. We are investigating
|
||||
alternative approaches with the platform team to prevent this occurring earlier in the flow.
|
||||
|
||||
### Account Switcher on GitHub Enterprise
|
||||
|
||||
When using `auth login` with github.com, if a user has multiple accounts in the browser, they should be presented
|
||||
with an interstitial page that allows for proceeding as any of their users. However, for Device Control Flow OAuth
|
||||
flows, this feature has not yet made it into GHES.
|
||||
|
||||
For the moment, if you have multiple accounts on GHES that you wish to log in as, you will need to ensure that you
|
||||
are authenticated as the correct user in the browser before running `auth login`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue