Skip to content

gh auth status should have a JSON output option #8637

Closed

Description

@evilhamsterman

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.

Additional context

An example output could be something like

{
    "github.com": {
        "active": true,
        "token": "gho_*******",
        "scopes": [
            "gist",
            "repo",
            "write:packages"
        ]
    }
}

Activity

  1. williammartin commented on Feb 20, 2024

    @williammartin
    Member

    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!

  2. added
    more-info-neededMore info needed from user/contributor
    and removed on Feb 20, 2024
  3. evilhamsterman commented on Feb 20, 2024

    @evilhamsterman
    Author

    @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.

  4. williammartin commented on Feb 21, 2024

    @williammartin
    Member

    @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.

  5. evilhamsterman commented on Feb 21, 2024

    @evilhamsterman
    Author

    Thanks it'll also make my life easier for work

  6. vedosis commented on Mar 8, 2024

    @vedosis

    Here's a real world example:

    https://xbarapp.com/docs/plugins/Dev/GitHub/pull-requests.5m.js.html

    Being able to use automation to:

    1. fetch your current tokens (rather than hard-coding the values)
    2. ping a GitHub API with a specific query + tokens
    3. send off a notification or flash your IoT lights 🤷🏻
  7. added and removed
    more-info-neededMore info needed from user/contributor
    on Mar 14, 2024
  8. andyfeller commented on Mar 14, 2024

    @andyfeller
    Contributor

    @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":

    Never use structured data as a secret

    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.

  9. williammartin commented on Mar 14, 2024

    @williammartin
    Member

    In an internal conversation I mentioned that I believe --show-token should still be required to remove the token mask even if --json is provided.

  10. evilhamsterman commented on Mar 14, 2024

    @evilhamsterman
    Author

    @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 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.

  11. 26 remaining items

  12. BagToad commented on Aug 18, 2025

    @BagToad
    Member

    @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 👍

  13. benjlevesque commented on Aug 19, 2025

    @benjlevesque
    Contributor

    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?

  14. BagToad commented on Aug 20, 2025

    @BagToad
    Member

    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...

    @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'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 🤔

    WDYT?

  15. benjlevesque commented on Aug 20, 2025

    @benjlevesque
    Contributor

    @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:

    1. The --json fields don’t align with the top-level properties of the returned object.
    2. 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 👍

  16. BagToad commented on Aug 25, 2025

    @BagToad
    Member

    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.


    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.

  17. benjlevesque commented on Aug 28, 2025

    @benjlevesque
    Contributor

    @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.

    Let me know what you think!

  18. babakks commented on Aug 28, 2025

    @babakks
    Member

    Thanks for picking up this work, @benjlevesque! 🍻

    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:

      echo '{"foo":[{"bar":0},{"bar":1}],"baz":[{"bar":2}]}' | jq add
      # [
      #   {
      #     "bar": 0
      #   },
      #   {
      #     "bar": 1
      #   },
      #   {
      #     "bar": 2
      #   }
      # ]  

      Since some folks might prefer the flat array we can surely add an example in the --help docs to show them how to do it.

    All said, I'm open to discussion if you strongly feel toward the flat array, @benjlevesque @BagToad

  19. srid commented on Sep 24, 2025

    @srid

    FWIW: my main use case is to programatically tell if the user has already gh auth login'ed once.

  20. evilhamsterman commented on Sep 24, 2025

    @evilhamsterman
    Author

    @srid it looks like @benjlevesque has a pr just about done so we should get this soon 🎆

  21. babakks commented on Sep 26, 2025

    @babakks
    Member

    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 hosts field):

    {
      "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 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):

    gh auth status --json hosts --show-token
    
  22. evilhamsterman commented on Oct 10, 2025

    @evilhamsterman
    Author

    WOOHOO! 🥳

    $ gh auth status --json hosts
    {
      "hosts": {
        "github.com": [
          {
            "state": "success",
            "active": true,
            "host": "github.com",
            "login": "evilhamsterman",
            "tokenSource": "keyring",
            "scopes": "gist, read:org, repo, workflow",
            "gitProtocol": "https"
          }
        ]
      }
    }
    

    Thanks so much @benjlevesque and @babakks! Now at some point when I get time I'll work on building a Docker credential plugin using gh

  23. sparrowt commented on Mar 26, 2026

    @sparrowt

    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!):

    gh auth status --active --json hosts --jq ".hosts | add.[0].login"
    

    EDIT: though it turns out you can get that more easily via just:

    gh api user --jq ".login"
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementa request to improve CLIgh-authrelating to the gh auth commandhelp wantedContributions welcome

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions