Skip to content

Support for short-lived oauth tokens #5924

Description

@adam-azarchs

Describe the feature or problem you’d like to solve

At the moment the OAuth2 flow is generating long-lived tokens. It would be nice to have the ability to use short-lived credentials + refresh tokens.

Proposed solution

Short-lived oauth tokens with refresh tokens are more secure than long-lived tokens because if your token gets exfiltrated then it'll expire quickly, and if the attacker uses the refresh token then you should at least be able to detect that quickly. I'm sure long-lived tokens are fine for many situations, but for organizations which are more paranoid, or where the risk of exposure is higher (e.g. situations where developers are logging in to github from a shared machine) it would be helpful to have the option to enable that higher level of security.

Additional context

See also similar feature request for GCM: git-ecosystem/git-credential-manager#789

Unfortunately, because gh's integration with git seems to be simply putting the token in ~/.git-credentials, unlike GCM (which is installed as a credential helper), in cases where git is used directly, the user would need to manually gh auth refresh when the tokens expired. However, doing so with a refresh token should at least allow that to proceed without redoing the browser flow. When using git fetch, gh push, etc, the only impact would be a minor speed bump every 8 hours when it needed to refresh the token.

Activity

  1. added
    authrelated to tokens, authentication state, or oauth
    and removed on Jul 13, 2022
  2. samcoe commented on Jul 13, 2022

    @samcoe
    Contributor

    @adam-azarchs Thanks for the feature request. This is something we would like to support in the future. I think there are some platform blockers, that are being worked on, still keeping this from being possible.

    cc #3855

  3. mislav commented on Nov 21, 2022

    @mislav
    Contributor

    Hi @adam-azarchs, this was suggested to us before via various channels, but I don't see how expiring tokens improve CLI security in any way.

    In a server-to-server model, expiring tokens do improve security (this is what they were designed for). For example, if I'm a 3rd-party CI service that integrates with GitHub, I will want to do some GitHub API operations on behalf of you as a user of my service. You might authorize my service to connect to your GitHub account and my service will receive an expiring access token + refresh token. I can use the short-lived access token to make API requests, and if that token gets compromised (e.g. “leaks” somewhere outside of the service), the potential damage is reduced by the nature of it being an expiring token.

    GitHub CLI runs on your machine and is not a service. It is only able to store personal data in a single place: on your computer. Therefore if we had an expiring access token + refresh token to store somewhere, we'd have to store them in the same place. If the attacker gets access to the access token stored by the CLI, they can also read the refresh token, thus completely bypassing the security of the expiring token.

    Note that I'm not a security expert, therefore I might be missing something. How do you think expiring tokens could improve security of client applications?

    See also: #449

  4. adam-azarchs commented on Nov 21, 2022

    @adam-azarchs
    Author

    There are many situations where one needs git credentials on a server, e.g. CI machines, git ops workflows, etc. Also, personal machines get compromised with alarming frequency.

  5. adam-azarchs commented on Nov 21, 2022

    @adam-azarchs
    Author

    As for the security implications of recording tokens when an attacker also has access to the refresh tokens, that's pretty straightforward: yes, they'll be able to refresh the token, but if they do, then you won't, because the refresh token is single use. So, you'll at least be able to detect that the token was compromised.

  6. adam-azarchs commented on Nov 21, 2022

    @adam-azarchs
    Author

    I'm a bit curious about why you're making such a distinction between a personal computer and a server - certainly in many modern contexts they're quite different, but many organizations are still using more traditional architectures where the difference between a server and a personal workstation is insignificant, e.g. if the user's home directory is mounted from a network share.

    In a bit more detail, some scenarios of interest for this:

    1. A developer machine gets temporarily compromised, e.g. they leave their workstation unlocked when going to the bathroom and someone comes by with a USB key and clones their home directory.
    2. A rouge IT employee accesses the off-site backups of a developer's workstation, which may include their authentication tokens.
    3. A departing employee copies the home directory of the service account that runs the CI infrastructure.

    In those scenarios, a short-lived key would significantly mitigate the damage, because either

    1. (best case) By the time the attacker tries to use those stolen credentials, the refresh token has already been consumed.
    2. The attacker uses the refresh token, which invalidates the legitimate user's refresh token, alerting them to the fact that something happened, so they can take appropriate steps to figure out what might have been done with it.

    In the worst case, of course, the attacker is able to use the auth token before it expires, and doesn't need the refresh token, so the theft of the credentials is never detected. Without refresh tokens, you're always stuck in this case.

  7. mislav commented on Nov 21, 2022

    @mislav
    Contributor

    Thanks for detailing these scenarios; that's helpful to frame the conversation.

    2. The attacker uses the refresh token, which invalidates the legitimate user's refresh token, alerting them to the fact that something happened

    That's an angle I haven't considered.

    I'm a bit curious about why you're making such a distinction between a personal computer and a server

    It's true that the distinction is not always necessary, but I have noticed that parts of the OAuth specification are more applicable to services (where the software code and storage is generally inaccessible to the consumer of the service) and less (or even not) applicable to client apps where the code that is being run is distributed to users. For example, refreshing an expiring OAuth token requires the use of both OAuth application ID and “secret” value, but if a client app is doing OAuth, then it needs to embed both the app ID and app secret in the app itself where the “secret” can be trivially reverse-engineered and extracted, making it a secret no longer.

  8. adam-azarchs commented on Nov 21, 2022

    @adam-azarchs
    Author

    if a client app is doing OAuth, then it needs to embed both the app ID and app secret in the app itself where the “secret” can be trivially reverse-engineered and extracted, making it a secret no longer.

    Of course that issue isn't unique to refresh tokens - it's an issue for long-lived tokens as well. The github CLI needs to embed a "secret" regardless. But that doesn't directly compromise the security of a user's credentials - at worst, it allows an attacker to bypass organizational restrictions on what apps are allowed to attempt authentication.

  9. jtheuer commented on Dec 1, 2022

    @jtheuer

    As an org admin I'd like to have a solution where developer machines only store credentials valid for e.g. 12h max in order to minimize the risk of exfiltration.

    A possible solution from a user perspective could be copied from the AWS SSO flow aws sso login. A developer needs to call it once per day. It opens a browser with the single-sign-in login flow. At the end the CLI polls for the short lived credentials (oauth2 device code flow). For GitHub this would be your login (most people are already logged in) plus the optional SSO login if enforced.

    Hope this description helps.

  10. adam-azarchs commented on Dec 1, 2022

    @adam-azarchs
    Author

    The idea with a refresh token is you can have the primary token with a very short expiration (e.g. 1 hour) without the inconvenience of needing to constantly re-enter your credentials, so long as you use the tool before the refresh token also expires (which is usually a much longer period time). The refresh token is a one-time token and gets refreshed at the same time as the primary token. If you do want to force the user to re-enter their credentials constantly, you'd need to disable refresh tokens, but at that point you might as well be using expiring PATs rather than dealing with the complexity of oauth.

  11. sethamclean commented on Dec 2, 2022

    @sethamclean

    The AWS SSO workflow is a perfect example where you don't re-enter your credentials. You're stored SSO token in your browser is used as a "refresh token". It isn't inconvenient at all from a user perspective, you run the login command, your browser pops open and you click "allow". The token expires at some interval < 24 hours. Vault's OIDC auth works similarly IIRC.

  12. 13 remaining items

  13. suzuki-shunsuke commented on Sep 15, 2025

    @suzuki-shunsuke

    Maybe this tool is useful.
    https://github.com/suzuki-shunsuke/ghtkn

    ghtkn is a CLI to create short-lived (8 hours) GitHub App User Access Token for secure local development.

  14. svperfecta commented on May 13, 2026

    @svperfecta

    This should be prioritized. With agents running around on workstations the more likely issue here is an agent publishing a token.

  15. corby commented on May 15, 2026

    @corby

    This has become a critical requirement since there have been multiple supply chain attacks in the last few weeks with stolen or leaked long lived tokens.
    This is a serious security oversight on Microosfts' part and not addressing this will lead to more supply chain attacks.
    +1

  16. jtheuer commented on May 20, 2026

    @jtheuer

    I think it is fair to say that this will never be implemented. Checking out alternative git services now.

  17. gilescope commented on May 26, 2026

    @gilescope

    Given NX Console was successfully hacked due to this ( https://nx.dev/blog/nx-console-v18-95-0-postmortem ), isn't it worth bumping the priority on this before inaction turns into a public relations disaster?

  18. snewell92 commented on May 26, 2026

    @snewell92

    Given my exposure (ie how many yarn/pnpm installs I and my clankers run run 😅 ), I'm considering building something similar to ghtkn (as linked above) or wrapping gh cli somehow or redirecting from cli to MCP. (or ofc just using ghtkn, should work too if GH app works for my use cases).

    Given investment in copilot; I'd appreciate even assigning a token budget for copilot to whittle away at this. As I understand it from above, there may still be blocked and that can be the first milestone, then the second is an opt in update to the gh cli, and then improving security for the entire world 👏

    cc @williammartin @BagToad unsure if either can make a decision and let us know in terms of priority - my above is just a suggestion not an expectation, and I truly appreciate using the gh cli over MCP or API, given supply chain attacks the more vectors we close off or limit the better. Let me know if I or any other interested party in the thread can help.

  19. karlhorky commented on May 26, 2026

    @karlhorky

    @williammartin @BagToad @babakks @mislav @samcoe would it be possible to get an updated official response from GitHub, now that supply chain security breaches are accelerating since a few years?

    Even the recent compromise of GitHub itself shows that developer devices are becoming a bigger target:

    Prior Art

    npm set access token limit to 2 hours in Dec 2025 (for the npm cli, when you run npm login):

  20. svperfecta commented on May 26, 2026

    @svperfecta
  21. chkp-ilyaro commented on Jun 8, 2026

    @chkp-ilyaro

    Hi @williammartin @BagToad @babakks @mislav @samcoe

    We use GH EMU enterprise, and we can't really use another solutions 100% like https://github.com/suzuki-shunsuke/ghtkn, as we can't block users from using gh auth login
    As it is, the GH Cloud internally managed OAUTH App, like many others

    So we do not see any alternative to addressing this issue
    Can you please update us on whether there are any plans to address the issue and, if so, when?

  22. g1a-pantheon commented on Jun 11, 2026

    @g1a-pantheon

    GitHub authentication tokens are high-value targets for bad actors. Recently, there have been a series of supply-chain software attacks whose main purpose has been the exfiltration of tokens. Credential rotation for long-lived tokens is laborious, and enterprises really expect to be able to require short-lived tokens.

    As an enterprise customer, we have already submitted feature requests for short-lived oauth tokens, and the ability to block all types of long-lived authentication tokens in an enterprise org, not just classic and fine-grained PATs. We would appreciate it if the cli/cli development team could also re-emphasize with the server-side teams the importance of these features, so that the work here to provide short-term oauth tokens could be unblocked.

  23. davidlovas commented on Jul 1, 2026

    @davidlovas

    Rather than everyone standing up their own GitHub App to try and achieve this, GitHub should support short-lived user tokens natively. Either an API that mints time-bounded user tokens that gh can call, or have the existing gh app issue them directly.

    The pattern I keep wanting is aws sso login (or npm login, as mentioned above): authenticate in the browser, get a token good for some TTL, and re-authenticate when it expires. Identity stays the user, nothing permanent sits on disk, and the TTL is something you can set (and an org can cap or enforce).

    And this isn't only for edge cases. Even on a primary dev machine I'd take short-lived tokens: aws sso login shows re-authenticating is almost no hassle, for a large security gain. There's little reason a permanent token should be the default anywhere.

    Where a permanent gh token is a liability:

    • shared or on-prem boxes like bastions or bare-metal build hosts, where the box should only ever hold a token that expires and can't renew itself, so a compromise leaks hours of access rather than a permanent credential
    • machine provisioning, contractor access, anything temporary by nature
    • blast-radius reduction: if a token leaks (supply-chain compromises, etc.), it's dead in hours instead of living forever

    This belongs in the platform and in gh, not in a pile of third-party Apps each reimplementing the same workaround.

    And it doesn't matter how you build the workaround, whether that's a separate tool, a wrapper, or something baked straight into a gh-compatible CLI. You're still stuck behind the same GitHub App with a fixed 8h floor and no way to enforce it.

  24. aqaurius6666 commented on Sep 24, 2026

    @aqaurius6666

    Upstream github oauth now supports refresh token for OAuth apps. So I wonder whether this feature in milestone of gh CLI? And where can i track that status?

    https://github.blog/changelog/2026-08-14-multiple-redirect-uris-and-token-refresh-for-oauth-apps/

  25. BagToad commented on Sep 24, 2026

    @BagToad
    Member

    @aqaurius6666 we're working on it; you can track it here:

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    authrelated to tokens, authentication state, or oauthblockedenhancementa request to improve CLIgh-authrelating to the gh auth commandpitchpitched internally for prioritisation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions