You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
gh auth status should have a JSON output option #8637
Describe the feature or problem you’d like to solve
There isn't a good way to easily integrate tools with the gh command to use the token. For example to create a Docker credential helper like in #5150 because the current output of gh auth status is formatted for human viewing and isn't guaranteed to remain stable.
Proposed solution
The command gh auth status should have an optional JSON output option to allow for integration with other tools that might need to use a Github token.
You can get just the token with gh auth token but it could be helpful to have other information such as the username, and the scopes. That way if necessary a command could run a gh auth refresh --scopes <scope> if the appropriate scope is not available. So for example a Docker credential helper as mentioned above could check if the token has the "read:packages" or even "write:packages" scope if necessary to push.
Reacted by Bernhard Kaindl, Tim Petricola, Petr Stupka, Jesse Houwing, Toby Dimmick, Will Crichton, Josh Soref, Desmond Kirrane, cliffchapmanrbx, loomanss and 7 more
Reacted by Bernhard Kaindl, Eugene Myasyshchev and Andrey Kozhev
Hey @evilhamsterman thanks for opening this enhancement request. It generally seems sensible to me though I'm curious if you have a specific need as opposed to a theorised one around docker credential managers? I'm not at all opposed to the idea but I would like the design to be motivated by some real need, if that makes sense. Cheers!
@williammartin it isn't a theorized one, #5150 has been open for a while without any apparent movement. I was looking to go ahead and build one as my company is looking to use ghcr for internal containers and other packages.
Another example in my company, I have written scripts to help administer various aspects of our GitHub organizations. I'd prefer to grab the token from gh than have them generate and manage PATs, or setup my own GitHub app. We already use gh and takes care of storing things rather than having to reinvent the wheel for small scripts.
I can get the token from gh auth token, but I also would like to be able to check that the token has the appropriate scopes for the appropriate orgs. I can do that by either trying to parse the existing output, or by making a general API call and inspecting the headers returned, but it would be much easier and quicker to just call the command, get a json object to parse and grab the values needed.
@evilhamsterman, sure I'm familiar with that issue. My point was less "is a docker credential helper needed" and more "is this going to help someone build a docker credential helper right now" because having a real user of this change is important both for design and prioritisation. It sounds like if we added support for this it would help you right now.
It generally sounds like a reasonable idea to me, I'm just gonna tag @andyfeller on here in case he has any additional thoughts.
@evilhamsterman, @williammartin: Thank you for your patience catching up! 🙇 My main thought stems from a security perspective, which I think is minimized as I elaborate below.
Structured data can cause secret redaction within logs to fail, because redaction largely relies on finding an exact match for the specific secret value. For example, do not use a blob of JSON, XML, or YAML (or similar) to encapsulate a secret value, as this significantly reduces the probability the secrets will be properly redacted. Instead, create individual secrets for each sensitive value.
In the case of GitHub Actions, this required the person who created a workflow or custom action to intentionally know how the secrets used worked and handling explicitly masking them. Knowing it might be complicated if the GitHub CLI had to emit the necessary ::add-mask workflow commands, I got confirmation from our actions friends that all of the known GitHub token formats are automatically masked as secrets without further intervention.
My secondary thought is whether we should intentionally disallow the --jq support for this command. 🤔
After saying that, I realize practically there is nothing to stop a user from manipulating the output of gh auth status --json externally with jq or other tools, so it would merely be a hindrance with no real security.
In this case I think the the ability to more easily use gh to manage tokens in personal scripts vs something like generating and storing a PAT far out weighs the concern of use in something like GitHub Actions where most people will be using GITHUB_TOKEN directly rather than passing it to gh just to get it again from gh auth status --json. Plus as you said it should be masked automatically anyway. If it is really a major concern in somewhat I can't see you could disable the flag when running in an Action workflow. You can still get the token with gh auth token or gh auth status --show-token this is just to help scripts by also providing a format that's easy to parse not just the token but the features like the token scopes by machine.
I'm not sure how limiting the --jq functionality would create any more security concerns than is already present in just showing the token. It's just a way to easily pick the data you want from the output. Especially since like you said there isn't anything stopping you from piping it through jq or yq yourself. In fact it could improve security because it would be easier to have gh output just the scopes if that's what you want.
@williammartin I can see the value in including --show-token without --json, but I personally think that if you are requesting a json output with --json, that already implies you have an idea of what you're doing and you want all the values so --show-token shouldn't be necessary. However that's a minor quibble and would not be a blocker.
Ultimately all the values that you would get from a --json flag are available already through other methods, really this is just a nice to have that enables easier integration of gh with other scripts and tools to securely manage your GitHub token.
@benjlevesque@evilhamsterman 👋 Since you folks expressed interest in taking a stab at this, it is ready for implementation following the acceptance criteria in #8637 (comment). If anyone else is also interested, let us know, we can assign whoever to the issue 👍
Hey @BagToad thanks for the ping, I'd be happy to give this a try :)
The AC seems pretty clear overall, but I have a few comments
Conflict in flag alias
I noticed is that the -t short flag of --show-token conflicts with --template when using AddJSONFlags. What do you think should be done about this? Removing -t for --show-token would be a breaking change... Maybe make -f optional in AddJSONFlags? I'll look into options...
Error message for --show-token and --json usage
I've seen in other parts of the code that MarkFlagsMutuallyExclusive is used to mark flags exclusive. Would this be an acceptable solution, rather than a custom message?
I noticed is that the -t short flag of --show-token conflicts with --template when using AddJSONFlags. What do you think should be done about this? Removing -t for --show-token would be a breaking change... Maybe make -f optional in AddJSONFlags? I'll look into options...
I think we should cut the short flag in this case 🤔 It sounds like you're on the right track with what you're looking into regarding AddJSONFlags 👍 Interested to see what it looks like in a PR and maybe we could spot other options.
I've seen in other parts of the code that MarkFlagsMutuallyExclusive is used to mark flags exclusive. Would this be an acceptable solution, rather than a custom message?
I think that's reasonable. While I think it would be a slightly better user experience to have an explanation for why they're mutually exclusive like the AC suggests, if it makes the code unreasonable or requires way more work, then I don't think that specific error message should block the PR. Especially if we have the reason documented in the command's Long help doc output 🤔
@BagToad thanks for the response! I found a pretty good option for the -t conflict, let me know what you think in the PR :)
Regarding the exclusive flags, I do agree the message is clearer, I was only asking for consistency with other commands.
Please take a look at the PR and let me know what you think! 😊
On another note, after testing the --json, --jq and --template options, I still find a flat array output (without `"github.com") would improve the UX. Two main pain points:
The --json fields don’t align with the top-level properties of the returned object.
Using --template/--jq feels unnecessarily complex for this use case.
gh auth status --json login --template '{{ range (index . "github.com") }}{{ .login }}{{ end }}'
gh auth status --json login --jq '.["github.com"].[].login'
With a flat array, it could be
gh auth status --json login --hostname github.com --jq '.[].login'
gh auth status --json login,host --jq '.[] | select(.host=="github.com") | .login'
gh auth status --json login --hostname github.com --template '{{ range . }}{{ .login }}{{ end }}'
f you get a chance to test the flat array approach, I’d love to hear your thoughts about which approach feels more natural / easier to use 👍
I'm not sure about the flat array thing, but it sounds like it would be better 🤔 I would like @babakks's thoughts.
I found a pretty good option for the -t conflict, let me know what you think in the PR :)
Very cool idea! I am going to give it some thought to understand the impact of something like this, just in case 🤔 I'll comment more on the PR if I think of anything.
@BagToad Regarding the -t flag, I didn’t verify if it would conflict with other flags, but I don’t think there’s a risk of collision since the code was crashing during execution when registering the second flag.
However, the current implementation has a downside: it could mask future conflicts by silently disabling the -t alias for --template. This might introduce breaking changes down the line, so it may not be the best approach.
Initially, I considered creating a separate function to register JSON flags without aliases and then manually adding the aliases afterward.
Good call out regarding the -t conflict. I didn't notice it when I was writing the A/C. I Just commented (#11544 (comment)) on your PR with a suggestion. Let's discuss there on the comment.
About the array/map structure, I have a few arguments in favour of maps:
It's consistent with our human-friendly output which is grouped by hostnames.
Looking up for a specific hostname is easier with a map.
I kind of feel like most of the time automation scripts would prefer working with the JSON output and the --jq option over --template. It's not a 100% correct, of course, but to me the --template option is more like a way of reshaping the data for human readability.
If a flat array is needed, (the seemingly redundant) hostname field is there in the entries which allows users to simply flatten the map without the need to somehow keep the map key. For example, jq's add function does what's needed:
This structure makes room for future extensibility without breaking automations (e.g. adding more top-level fields without them being interpreted as yet another host). This is more consistent with other gh commands. Also it'd be much easier for the user to invoke the command without the need to specify fields per entry, i.e.:
gh auth status --json hosts
To include the token in the JSON output, users can just add the --show-token (or -t):
Activity
williammartin commentedon Feb 20, 2024
Hey @evilhamsterman thanks for opening this enhancement request. It generally seems sensible to me though I'm curious if you have a specific need as opposed to a theorised one around docker credential managers? I'm not at all opposed to the idea but I would like the design to be motivated by some real need, if that makes sense. Cheers!
evilhamsterman commentedon Feb 20, 2024
@williammartin it isn't a theorized one, #5150 has been open for a while without any apparent movement. I was looking to go ahead and build one as my company is looking to use ghcr for internal containers and other packages.
Another example in my company, I have written scripts to help administer various aspects of our GitHub organizations. I'd prefer to grab the token from gh than have them generate and manage PATs, or setup my own GitHub app. We already use gh and takes care of storing things rather than having to reinvent the wheel for small scripts.
I can get the token from gh auth token, but I also would like to be able to check that the token has the appropriate scopes for the appropriate orgs. I can do that by either trying to parse the existing output, or by making a general API call and inspecting the headers returned, but it would be much easier and quicker to just call the command, get a json object to parse and grab the values needed.
williammartin commentedon Feb 21, 2024
@evilhamsterman, sure I'm familiar with that issue. My point was less "is a docker credential helper needed" and more "is this going to help someone build a docker credential helper right now" because having a real user of this change is important both for design and prioritisation. It sounds like if we added support for this it would help you right now.
It generally sounds like a reasonable idea to me, I'm just gonna tag @andyfeller on here in case he has any additional thoughts.
evilhamsterman commentedon Feb 21, 2024
Thanks it'll also make my life easier for work
vedosis commentedon Mar 8, 2024
Here's a real world example:
https://xbarapp.com/docs/plugins/Dev/GitHub/pull-requests.5m.js.html
Being able to use automation to:
andyfeller commentedon Mar 14, 2024
@evilhamsterman, @williammartin: Thank you for your patience catching up! 🙇 My main thought stems from a security perspective, which I think is minimized as I elaborate below.
Security concerns 🤔
My main concern, which I believe is abated, relates to "Security hardening for GitHub Actions" given "GitHub CLI use also in GitHub Actions workflows":
In the case of GitHub Actions, this required the person who created a workflow or custom action to intentionally know how the secrets used worked and handling explicitly masking them. Knowing it might be complicated if the GitHub CLI had to emit the necessary
::add-maskworkflow commands, I got confirmation from ouractionsfriends that all of the known GitHub token formats are automatically masked as secrets without further intervention.My secondary thought is whether we should intentionally disallow the
--jqsupport for this command. 🤔After saying that, I realize practically there is nothing to stop a user from manipulating the output of
gh auth status --jsonexternally withjqor other tools, so it would merely be a hindrance with no real security.williammartin commentedon Mar 14, 2024
In an internal conversation I mentioned that I believe
--show-tokenshould still be required to remove the token mask even if--jsonis provided.evilhamsterman commentedon Mar 14, 2024
@andyfeller I appreciate the security concern, but I also feel that it isn't always you job to prevent a useful function that could improve security in several ways because of a concern for what could be an occasional issue in other situations. This feels like a "but sometimes" of software, https://youtu.be/GiYO1TObNz8.
In this case I think the the ability to more easily use
ghto manage tokens in personal scripts vs something like generating and storing a PAT far out weighs the concern of use in something like GitHub Actions where most people will be usingGITHUB_TOKENdirectly rather than passing it toghjust to get it again fromgh auth status --json. Plus as you said it should be masked automatically anyway. If it is really a major concern in somewhat I can't see you could disable the flag when running in an Action workflow. You can still get the token withgh auth tokenorgh auth status --show-tokenthis is just to help scripts by also providing a format that's easy to parse not just the token but the features like the token scopes by machine.I'm not sure how limiting the
--jqfunctionality would create any more security concerns than is already present in just showing the token. It's just a way to easily pick the data you want from the output. Especially since like you said there isn't anything stopping you from piping it throughjqoryqyourself. In fact it could improve security because it would be easier to haveghoutput just the scopes if that's what you want.@williammartin I can see the value in including
--show-tokenwithout--json, but I personally think that if you are requesting a json output with--json, that already implies you have an idea of what you're doing and you want all the values so--show-tokenshouldn't be necessary. However that's a minor quibble and would not be a blocker.Ultimately all the values that you would get from a
--jsonflag are available already through other methods, really this is just a nice to have that enables easier integration ofghwith other scripts and tools to securely manage your GitHub token.26 remaining items
BagToad commentedon Aug 18, 2025
@benjlevesque @evilhamsterman 👋 Since you folks expressed interest in taking a stab at this, it is ready for implementation following the acceptance criteria in #8637 (comment). If anyone else is also interested, let us know, we can assign whoever to the issue 👍
benjlevesque commentedon Aug 19, 2025
Hey @BagToad thanks for the ping, I'd be happy to give this a try :)
The AC seems pretty clear overall, but I have a few comments
Conflict in flag alias
I noticed is that the
-tshort flag of--show-tokenconflicts with--templatewhen usingAddJSONFlags. What do you think should be done about this? Removing-tfor--show-tokenwould be a breaking change... Maybe make-foptional inAddJSONFlags? I'll look into options...Error message for
--show-tokenand--jsonusageI've seen in other parts of the code that
MarkFlagsMutuallyExclusiveis used to mark flags exclusive. Would this be an acceptable solution, rather than a custom message?BagToad commentedon Aug 20, 2025
@benjlevesque that is a good question!
I think we should cut the short flag in this case 🤔 It sounds like you're on the right track with what you're looking into regarding
AddJSONFlags👍 Interested to see what it looks like in a PR and maybe we could spot other options.I think that's reasonable. While I think it would be a slightly better user experience to have an explanation for why they're mutually exclusive like the AC suggests, if it makes the code unreasonable or requires way more work, then I don't think that specific error message should block the PR. Especially if we have the reason documented in the command's
Longhelp doc output 🤔WDYT?
benjlevesque commentedon Aug 20, 2025
@BagToad thanks for the response! I found a pretty good option for the
-tconflict, let me know what you think in the PR :)Regarding the exclusive flags, I do agree the message is clearer, I was only asking for consistency with other commands.
Please take a look at the PR and let me know what you think! 😊
On another note, after testing the
--json,--jqand--templateoptions, I still find a flat array output (without `"github.com") would improve the UX. Two main pain points:With a flat array, it could be
f you get a chance to test the flat array approach, I’d love to hear your thoughts about which approach feels more natural / easier to use 👍
BagToad commentedon Aug 25, 2025
Thank you @benjlevesque! 🙌
I'm not sure about the flat array thing, but it sounds like it would be better 🤔 I would like @babakks's thoughts.
Very cool idea! I am going to give it some thought to understand the impact of something like this, just in case 🤔 I'll comment more on the PR if I think of anything.
benjlevesque commentedon Aug 28, 2025
@BagToad Regarding the
-tflag, I didn’t verify if it would conflict with other flags, but I don’t think there’s a risk of collision since the code was crashing during execution when registering the second flag.However, the current implementation has a downside: it could mask future conflicts by silently disabling the
-talias for--template. This might introduce breaking changes down the line, so it may not be the best approach.Initially, I considered creating a separate function to register JSON flags without aliases and then manually adding the aliases afterward.
Let me know what you think!
babakks commentedon Aug 28, 2025
Thanks for picking up this work, @benjlevesque! 🍻
Good call out regarding the
-tconflict. I didn't notice it when I was writing the A/C. I Just commented (#11544 (comment)) on your PR with a suggestion. Let's discuss there on the comment.About the array/map structure, I have a few arguments in favour of maps:
It's consistent with our human-friendly output which is grouped by hostnames.
Looking up for a specific hostname is easier with a map.
I kind of feel like most of the time automation scripts would prefer working with the JSON output and the
--jqoption over--template. It's not a 100% correct, of course, but to me the--templateoption is more like a way of reshaping the data for human readability.If a flat array is needed, (the seemingly redundant)
hostnamefield is there in the entries which allows users to simply flatten the map without the need to somehow keep the map key. For example, jq'saddfunction does what's needed:Since some folks might prefer the flat array we can surely add an example in the
--helpdocs to show them how to do it.All said, I'm open to discussion if you strongly feel toward the flat array, @benjlevesque @BagToad
srid commentedon Sep 24, 2025
FWIW: my main use case is to programatically tell if the user has already
gh auth login'ed once.evilhamsterman commentedon Sep 24, 2025
@srid it looks like @benjlevesque has a pr just about done so we should get this soon 🎆
babakks commentedon Sep 26, 2025
The PR for this is merged now and the JSON output will be available with the next release, which will be
v2.81.0.However, we ended up formatting the JSON output like this (note the top-level
hostsfield):{ "hosts": { "github.com": [/*...*/], "another.host": [/*...*/], } }This structure makes room for future extensibility without breaking automations (e.g. adding more top-level fields without them being interpreted as yet another host). This is more consistent with other
ghcommands. Also it'd be much easier for the user to invoke the command without the need to specify fields per entry, i.e.:To include the token in the JSON output, users can just add the
--show-token(or-t):evilhamsterman commentedon Oct 10, 2025
WOOHOO! 🥳
Thanks so much @benjlevesque and @babakks! Now at some point when I get time I'll work on building a Docker credential plugin using
ghfix(github): properly parse scopes and use additive refresh
sparrowt commentedon Mar 26, 2026
Thanks for this!
To get just the username of the active authenticated user (which is what I was after, and it took me too long to figure out!):
EDIT: though it turns out you can get that more easily via just: