{"id":15113827,"url":"https://github.com/link-/gh-token","last_synced_at":"2026-04-01T23:59:50.027Z","repository":{"id":40535024,"uuid":"360687334","full_name":"Link-/gh-token","owner":"Link-","description":"Manage installation access tokens for GitHub apps from your terminal 💻","archived":false,"fork":false,"pushed_at":"2025-12-30T14:39:24.000Z","size":4685,"stargazers_count":362,"open_issues_count":4,"forks_count":35,"subscribers_count":7,"default_branch":"main","last_synced_at":"2026-01-03T08:14:05.196Z","etag":null,"topics":["actions","apps","bash","bash-script","cli","enterprise","gh-extension","github","github-token"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Link-.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"Link-","patreon":"glich_stream"}},"created_at":"2021-04-22T21:34:18.000Z","updated_at":"2025-12-30T14:38:14.000Z","dependencies_parsed_at":"2024-04-30T18:35:13.074Z","dependency_job_id":"74c07138-b727-4bb2-8c2b-d68ea65756a1","html_url":"https://github.com/Link-/gh-token","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/Link-/gh-token","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Link-%2Fgh-token","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Link-%2Fgh-token/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Link-%2Fgh-token/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Link-%2Fgh-token/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Link-","download_url":"https://codeload.github.com/Link-/gh-token/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Link-%2Fgh-token/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30084685,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T13:22:36.021Z","status":"ssl_error","status_checked_at":"2026-03-04T13:20:45.750Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["actions","apps","bash","bash-script","cli","enterprise","gh-extension","github","github-token"],"created_at":"2024-09-26T01:23:26.965Z","updated_at":"2026-03-04T15:00:46.717Z","avatar_url":"https://github.com/Link-.png","language":"Go","readme":"# GH Token\n\n```shell\n* _____ _   *_   _______ *  _      *  *    **   *\n / ____| |* | | |__   __|  | |  *       *         🦄  *\n| | *__| |_*| | ⭐️ | | ___ | | _____*_ __  *     *\n| | |_ |* __ *|    |*|/ _ \\| |/ / _ \\ '_ \\     *   *\n| |__| | |  | | *  | | (_)*|   \u003c  __/ | | |  *\n \\_____|_|  |_|    |_|\\___/|_|\\_\\___|_| |_|   *\n```\n\n\u003c!-- markdownlint-disable --\u003e\n\n\u003e Manage installation access tokens for GitHub apps from your terminal\n\n[![License](https://img.shields.io/github/license/link-/gh-token?style=flat-square)](LICENSE)\n\n\u003c!-- markdownlint-restore --\u003e\n\n[Creates an installation access token](https://docs.github.com/en/rest/reference/apps#create-an-installation-access-token-for-an-app) to make authenticated API requests.\n\nInstallation tokens expire **1 hour** from the time you create them. Using an expired token produces a status code of `401 - Unauthorized`, and requires creating a new installation token.\n\nYou can use this access token to make pretty much any REST or GraphQL API call the app is authorized to make!\n\n![gh-token demo](./images/gh-token.png)\n\n## Why?\n\nIn order to use GitHub's [REST](https://docs.github.com/en/rest) or [GraphQL](https://docs.github.com/en/graphql) APIs you will need either a [Personal Access Token](https://docs.github.com/en/developers/apps/about-apps#personal-access-tokens) (PAT) or a [GitHub App](https://docs.github.com/en/developers/apps/about-apps#about-github-apps).\n\n**PATs are dangerous, they:**\n\n1. have a very wide scope that spans across multiple organizations\n1. never (automatically) expire. They have an indefinite lifetime (or at least until you regenerate them)\n1. cannot be revoked (they're only revoked when a new one is generated)\n\nWith an access token generated with a GitHub App you don't have to worry about the concerns above. These tokens have a limited scope and lifetime. Just make sure you handle the token safely (avoid leaking). In the worst case scenario, the token will expire in **1 hour from creation time.**\n\n## Installation\n\n### Download as a standalone binary\n\nDownload `gh-token` from the [latest release](https://github.com/Link-/gh-token/releases/latest) for your platform.\n\n### Install as a `gh` cli extension\n\nYou can install `gh-token` as a [gh cli](https://github.com/cli/cli) extension!\n\n```shell\n$ gh extension install Link-/gh-token\n\n# Verify installation\n$ gh token\n```\n\nAll the commands and parameters remain the same, the only different is you now can use `gh token` instead of `gh-token`.\n\n### Creating a GitHub App\n\nFollow [these steps](https://docs.github.com/en/developers/apps/creating-a-github-app)\n\n## Usage\n\nCompatible with [GitHub Enterprise Server](https://github.com/enterprise).\n\n```text\nNAME:\n   gh-token - Manage GitHub App installation tokens\n\nUSAGE:\n   gh-token [global options] command [command options] [arguments...]\n\nVERSION:\n   2.0.2\n\nCOMMANDS:\n   generate       Generate a new GitHub App installation token\n   revoke         Revoke a GitHub App installation token\n   installations  List GitHub App installations\n   help, h        Shows a list of commands or help for one command\n\nGLOBAL OPTIONS:\n   --help, -h     show help\n   --version, -v  print the version\n```\n\n### Examples in the Terminal\n\n#### Run `gh token` as a `gh` CLI extension\n\n```shell\ngh token generate \\\n    --key ./.keys/private-key.pem \\\n    --app-id 1122334 \\\n    --installation-id 5566778\n```\n\n```json\n{\n  \"token\": \"ghs_8Joht_______________bLCMS___M0EPOhJ\",\n  \"expires_at\": \"2023-09-08T18:11:34Z\",\n  \"permissions\": {\n    \"actions\": \"write\",\n    \"administration\": \"write\",\n    \"metadata\": \"read\",\n    \"members\": \"read\",\n    \"organization_administration\": \"read\"\n  }\n}\n```\n\n#### Run `gh token` and pass the key as a base64 encoded string\n\n```shell\ngh token generate \\\n    --base64-key $(printf \"%s\" $APP_KEY | base64) \\\n    --app-id 1122334 \\\n    --installation-id 5566778\n```\n\n```json\n{\n  \"token\": \"ghs_8Joht_______________bLCMS___M0EPOhJ\",\n  \"expires_at\": \"2023-09-08T18:11:34Z\",\n  \"permissions\": {\n    \"actions\": \"write\",\n    \"administration\": \"write\",\n    \"metadata\": \"read\",\n    \"members\": \"read\",\n    \"organization_administration\": \"read\"\n  }\n}\n```\n\n#### Run `gh token` with GitHub Enterprise Server\n\n```shell\ngh token generate \\\n    --base64-key $(printf \"%s\" $APP_KEY | base64) \\\n    --app-id 1122334 \\\n    --installation-id 5566778 \\\n    --hostname \"github.example.com\"\n```\n\n```json\n{\n  \"token\": \"ghs_8Joht_______________bLCMS___M0EPOhJ\",\n  \"expires_at\": \"2023-09-08T18:11:34Z\",\n  \"permissions\": {\n    \"actions\": \"write\",\n    \"administration\": \"write\",\n    \"metadata\": \"read\",\n    \"members\": \"read\",\n    \"organization_administration\": \"read\"\n  }\n}\n```\n\n#### Fetch list of installations for an app\n\n```shell\ngh token installations \\\n    --key ./private-key.pem \\\n    --app-id 2233445\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eResponse\u003c/summary\u003e\n\n  ```json\n  [\n    {\n      \"id\": 1,\n      \"account\": {\n        \"login\": \"octocat\",\n        \"id\": 1,\n        \"node_id\": \"MDQ6VXNlcjE=\",\n        \"avatar_url\": \"https://github.com/images/error/octocat_happy.gif\",\n        \"gravatar_id\": \"\",\n        \"url\": \"https://api.github.com/users/octocat\",\n        \"html_url\": \"https://github.com/octocat\",\n        \"followers_url\": \"https://api.github.com/users/octocat/followers\",\n        \"following_url\": \"https://api.github.com/users/octocat/following{/other_user}\",\n        \"gists_url\": \"https://api.github.com/users/octocat/gists{/gist_id}\",\n        \"starred_url\": \"https://api.github.com/users/octocat/starred{/owner}{/repo}\",\n        \"subscriptions_url\": \"https://api.github.com/users/octocat/subscriptions\",\n        \"organizations_url\": \"https://api.github.com/users/octocat/orgs\",\n        \"repos_url\": \"https://api.github.com/users/octocat/repos\",\n        \"events_url\": \"https://api.github.com/users/octocat/events{/privacy}\",\n        \"received_events_url\": \"https://api.github.com/users/octocat/received_events\",\n        \"type\": \"User\",\n        \"site_admin\": false\n      },\n      \"access_tokens_url\": \"https://api.github.com/installations/1/access_tokens\",\n      \"repositories_url\": \"https://api.github.com/installation/repositories\",\n      \"html_url\": \"https://github.com/organizations/github/settings/installations/1\",\n      \"app_id\": 1,\n      \"target_id\": 1,\n      \"target_type\": \"Organization\",\n      \"permissions\": {\n        \"checks\": \"write\",\n        \"metadata\": \"read\",\n        \"contents\": \"read\"\n      },\n      \"events\": [\n        \"push\",\n        \"pull_request\"\n      ],\n      \"single_file_name\": \"config.yaml\",\n      \"has_multiple_single_files\": true,\n      \"single_file_paths\": [\n        \"config.yml\",\n        \".github/issue_TEMPLATE.md\"\n      ],\n      \"repository_selection\": \"selected\",\n      \"created_at\": \"2017-07-08T16:18:44-04:00\",\n      \"updated_at\": \"2017-07-08T16:18:44-04:00\",\n      \"app_slug\": \"github-actions\",\n      \"suspended_at\": null,\n      \"suspended_by\": null\n    }\n  ]\n  ```\n\n\u003c/details\u003e\n\n#### Revoke an installation access token\n\n```shell\ngh token revoke \\\n    --token \"v1.bb1___168d_____________1202bb8753b133919\" \\\n    --hostname \"github.example.com\"\n```\n\n```text\nSuccessfully revoked installation token\n```\n\n### Example in a workflow\n\n\u003cdetails\u003e\n\n  \u003csummary\u003eExpand to show instructions\u003c/summary\u003e\n\n1. You need to create a secret to store the **applications private key** securely (this can be an organization or a repository secret):\n    ![Create private key secret](images/create_secret.png)\n\n1. You need to create another secret to store the **application id** security (same as the step above).\n\n1. The secrets need to be provided as an environment variable then encoded into base64 as show in the workflow example:\n\nThis example is designed to run on GitHub Enterprise Server. To use the same workflow with GitHub.com update the hostname to `api.github.com` and change the API URL in the testing step.\n\n```yaml\nname: Create access token via GitHub Apps Workflow\n\non:\n  workflow_dispatch:\n\njobs:\n  Test:\n    # The type of runner that the job will run on\n    runs-on: [ self-hosted ]\n\n    steps:\n    - name: \"Install gh-token\"\n      run: gh extension install Link-/gh-token\n    # Create access token with a GitHub App ID and Key\n    # We use the private key stored as a secret and encode it into base64\n    # before passing it to gh-token\n    - name: \"Create access token\"\n      run: |\n        token=$(gh token generate \\\n          --base64-key $(printf \"%s\" \"$APP_PRIVATE_KEY\" | base64 -w 0) \\\n          --app-id $APP_ID \\\n          --hostname \"github.example.com\" \\\n          | jq -r \".token\")\n        echo \"token=$token\" \u003e\u003e $GITHUB_OUTPUT\n      env:\n        APP_ID: ${{ secrets.APP_ID }}\n        APP_PRIVATE_KEY: ${{ secrets.APP_KEY }}\n    # To test the token we will use it to fetch the list of repositories\n    # belonging to our organization\n    - name: \"Fetch organization repositories\"\n      run: |\n        curl -X GET \\\n          -H \"Authorization: token $token\" \\\n          -H \"Accept: application/vnd.github.v3+json\" \\\n          https://github.example.com/api/v3/orgs/\u003cORGNAME\u003e/repos\n```\n\n\u003c/details\u003e\n\n## Similar projects\n\n_These are not endorsements, just a listing of similar art work_\n\n### CLI\n\n- [apptokit](https://github.com/jakewilkins/apptokit) in Ruby\n- [gha-token](https://github.com/slawekzachcial/gha-token) in Go\n\n### Actions\n\n- [create-github-app-token](https://github.com/actions/create-github-app-token) (GitHub official)\n- [workflow-application-token-action](https://github.com/peter-murray/workflow-application-token-action)\n- [action-github-app-token](https://github.com/getsentry/action-github-app-token)\n- [github-app-token-generator](https://github.com/navikt/github-app-token-generator)\n","funding_links":["https://github.com/sponsors/Link-","https://patreon.com/glich_stream"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flink-%2Fgh-token","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flink-%2Fgh-token","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flink-%2Fgh-token/lists"}