Skip to content

feat(oauth): Use keyring to store oauth token#1228

Open
burmudar wants to merge 14 commits intowb/add-oauth-refresh-tokenfrom
wb/oauth-keyring
Open

feat(oauth): Use keyring to store oauth token#1228
burmudar wants to merge 14 commits intowb/add-oauth-refresh-tokenfrom
wb/oauth-keyring

Conversation

@burmudar
Copy link
Contributor

@burmudar burmudar commented Dec 8, 2025

This adds a keyring which is used to store OAuth credentials. The OAuth credentials are retrieved from the keyring whenever there is no SRC_ACCESS_TOKEN defined.

When we use an OAuth token, we also add a OAuth transport which will automatically refresh the access token using the refresh token when it is near to expiring.

Credentials are stored in the keyring with under the service "Sourcegraph CLI" and with key "src:oauth:". The reason for the endpoint being in the key name is that some clients might access multiple sourcegraph instances like dev and prod, and we can't reuse the same credentials for the different servers.

Test plan

  • Authorize by running src login --oauth https://sourcegraph.sourcegraph.com
  • run export SRC_ENDPOINT=https://sourcegraph.sourcegraph.com; echo 'query { currentUser { username } }' | go run ./cmd/src api
  • Revoke access of Sourcegraph CLI application and rerun previous command
The OAuth token is invalid. Please check that the Sourcegraph CLI client is still authorized.

To re-authorize, run: src login

Learn more at https://github.com/sourcegraph/src-cli#readme

error: 401 Unauthorized

Invalid OAuth token.
exit status 1

Platforms tested

  • Mac
  • Windows
  • Linux

@burmudar
Copy link
Contributor Author

burmudar commented Dec 8, 2025

@burmudar burmudar force-pushed the wb/add-oauth-refresh-token branch from 2f24f44 to 7f2c665 Compare January 23, 2026 09:03
@burmudar burmudar force-pushed the wb/add-oauth-refresh-token branch from 7f2c665 to 87b5732 Compare January 23, 2026 09:10
- rename keyring to store
- make keyring struct src-cli and set label on secret
- create token struct from TokenResponse
- Token converts expiresIn to a timestamp
- Store the token with the endpoint suffix
- OAuth transport and use when available in api client
- Add secret store that supports different backends
- We use a registry map for a few secrets and the registry gets
  persisted as one secret to the keyring. We don't waant to create a
  keyring secret for every different secret
- Store is opened once to load the registry.
- use secretStorage to store oauth tokens
- use token.ClientID during refresh
- best effort store refresh token
handle oauth discovery failure and set client id on token

- use SRC CLI client id as default and handle discovery failures
- add clientID flag and set it on the token

improve error message and panic in apiClient if no usable token

- warn if we fail to store the token on login
- panic if apiClient has no accessToken or OAuth token to use
@burmudar burmudar force-pushed the wb/add-oauth-refresh-token branch from 87b5732 to abd0850 Compare February 26, 2026 12:33
@burmudar burmudar self-assigned this Feb 26, 2026
@burmudar burmudar requested review from a team, eseliger and keegancsmith February 26, 2026 13:58
@burmudar burmudar marked this pull request as ready for review February 26, 2026 14:08
printProblem("No access token is configured.")
case endpointConflict:
printProblem(fmt.Sprintf("The configured endpoint is %s, not %s.", cfg.Endpoint, endpointArg))
if err := oauth.StoreToken(ctx, token); err != nil {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opted to not store anything when failing to store in the keyring. This means if we fail storing the user would have to login everytime - not exactly ideal.

We could write the details to disk and warn the user? And everytime we load it we warn them again?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants