Repository navigation
Support for short-lived oauth tokens #5924
Description
Activity
- addedauthrelated to tokens, authentication state, or oauthrelated to tokens, authentication state, or oauthand removedneeds-triageneeds to be reviewedneeds to be reviewed
on Jul 13, 2022 @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
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
Reacted by Daniel Ingle, Nikhil Gaddam, Mike Juarez, Grégory Romé, bauerbrett1, MangelSpec, Sean Newell and Ilya RokhkinThere 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.
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.
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:
- 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.
- A rouge IT employee accesses the off-site backups of a developer's workstation, which may include their authentication tokens.
- 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
- (best case) By the time the attacker tries to use those stolen credentials, the refresh token has already been consumed.
- 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.
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.
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.
Reacted by Mislav Marohnić, Oliver Mannion and Ilya RokhkinAs 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.
Reacted by sethamclean, Rob Jackson, johnmarzella-immutable, Merlyn @ Netlify, Christian Heggland, Stephen Liu, Bo Lingen, Mike Juarez, Noah Allen, Ilya Rokhkin and 3 moreThe 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.
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.
Reacted by Christian Heggland, Ted B and Grégory Rump13 remaining items
Maybe this tool is useful.
https://github.com/suzuki-shunsuke/ghtknghtkn is a CLI to create short-lived (8 hours) GitHub App User Access Token for secure local development.
Reacted by Masahiro Saito, Sean Newell, Shinji Yamada and Ilya Rokhkin- addedpitchpitched internally for prioritisationpitched internally for prioritisation
on Mar 10, 2026 This should be prioritized. With agents running around on workstations the more likely issue here is an agent publishing a token.
Reacted by Tetsuro Aoki, Bernd, Corby Wilson, Nick Segalle, bauerbrett1, Tim Diekmann, Scott Hurd, Roman, Oleksii Leonov, Iron-E and 2 moreThis 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.
+1Reacted by Tetsuro Aoki, Oliver Mannion, José Moyano Gutiérrez, Nick Segalle, bauerbrett1, Tim Diekmann, Tito, Scott Hurd, MangelSpec, Ted B and 10 moreI think it is fair to say that this will never be implemented. Checking out alternative git services now.
Reacted by Ted B, Roman and Justin SmithGiven 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?
Reacted by Roman, Karl Horky, Sean Newell, Dylan Myers, Danilo Fuchs, Ilya Rokhkin, John Brothers, Oleksii Leonov, Iron-E and Justin SmithGiven 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.
@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
npmcli, when you runnpm login):Reacted by Sean Newell, Dylan Myers, Scot Schuchert-Wells, Mishaa, Ted B, Sébastien Lorber, Shinji Yamada, Ilya Rokhkin, John Brothers, Rob Lambell and 2 more- Critical to this is not just shorter token duration (and being able to set duration as an enterprise customer) but also correctly utilizing a refresh token. GitHub should be forcing reauthentication if the refresh token is used in an unexpected manner. That's the entire point of the specification. Also, as an enterprise It is also critical that we can expire tokens in a more fine grain fashion than the options that exist today.Reacted by Iron-E and David Lovas
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 othersSo 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?Reacted by Okkey and SukkaGitHub 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.
Reacted by Iron-E, John Brothers, Wout Van Boxem and SukkaRather 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
ghcan call, or have the existingghapp issue them directly.The pattern I keep wanting is
aws sso login(ornpm 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 loginshows 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
ghtoken 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.Reacted by Michael Nahkies, Pulasthi Bandara, Sukka, Timothy Klopotoski, Takahiro Tsuruda, Shawn Wilsher and John Brothers- added a commit that references this issue
on Sep 1, 2026 Upstream github oauth now supports refresh token for OAuth apps. So I wonder whether this feature in milestone of
ghCLI? And where can i track that status?https://github.blog/changelog/2026-08-14-multiple-redirect-uris-and-token-refresh-for-oauth-apps/
@aqaurius6666 we're working on it; you can track it here:
Reacted by Tetsuro Aoki, Daniel Fernández Núñez, Karl Horky and hsmith-nudgeReacted by Barabazs
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 withgitseems to be simply putting the token in~/.git-credentials, unlike GCM (which is installed as a credential helper), in cases wheregitis used directly, the user would need to manuallygh auth refreshwhen the tokens expired. However, doing so with a refresh token should at least allow that to proceed without redoing the browser flow. When usinggit fetch,gh push, etc, the only impact would be a minor speed bump every 8 hours when it needed to refresh the token.