ghtkn (G-H Token)

repository·main·Indexed 42 days ago

https://github.com/suzuki-shunsuke/ghtkn

A security tool that generates short-lived (8-hour) GitHub User Access Tokens using the GitHub App Device Flow to replace long-lived Personal Access Tokens (PATs) in local development. It features a secure execution command (`ghtkn exec`) to inject tokens into environment variables, multiple storage backends (keyring, text, and agent), and support for encrypted token storage with automatic refreshing via the ghtkn agent.

Tokens
26K
Snippets
97
Records
116
Agent score
48%

What's inside ghtkn

  1. Overview of ghtkn

    main

    ghtkn (G-H Token) is a tool for creating short-lived GitHub App User Access Tokens via the OAuth device flow. It is designed to replace long-lived Personal Access Tokens (PATs) for secure local development.

    Tokens can be cached in several backends:

    • OS keyring
    • The ghtkn agent (recommended for containers, VMs, or minimal Linux environments)
    • A plain text file

    Use ghtkn to authenticate the GitHub CLI (gh), Git, and other tools without exposing long-lived credentials.

    $ ghtkn --help
  2. Handle token acquisition failures with `--continue-on-error`

    main

    By default, if ghtkn exec cannot acquire a token for an app, it will exit with code 111 and the target command will not run.

    If you want the command to run even if a token is unavailable, use the --continue-on-error flag.

    Behavior with --continue-on-error:

    1. The command runs regardless of token availability.
    2. A warning is logged to stderr.
    3. Environment variables for which tokens were acquired are set.
    4. Environment variables for which tokens could not be acquired retain whatever value they had in ghtkn's own environment. If GITHUB_TOKEN was already set to a different credential in your shell, the command will silently use that existing value.
  3. Configure and switch between multiple GitHub Apps

    main

    You can manage multiple GitHub Apps in the apps section of your ghtkn configuration file. This allows you to use different Apps for different Organizations or Users. By default, ghtkn uses the first App listed in the apps array.

    Configuration Rules

    Each app entry must include a name and a client_id. To prevent token collisions and ensure predictable behavior, the following constraints apply:

    • Uniqueness: No two apps may share the same name, client_id, or repository owner (defined via git_owner or git_owners).
    • Client ID Identity: The client_id is the primary key for the stored access token, its refresh, and its revocation. Do not create multiple entries for the same client_id.
    • Owner Scoping: Use git_owner (single owner) or git_owners (multiple owners) to scope an app to specific repositories. These fields are mutually exclusive.

    If you need to use an app for a repository where the owner is not explicitly listed (such as a fork), you must select the app manually using the methods described below.

  4. How refresh tokens and the exposure window work

    main

    Enabling refresh tokens improves UX but slightly widens the security exposure window while the agent is unlocked.

    The Exposure Window

    • Active Apps: For apps you use regularly, the risk is minimal. An attacker would need to deliberately force a renewal (e.g., running ghtkn auth) to extend a token's life.
    • Idle Apps: For apps not used within 8 hours, an attacker can obtain a fresh access token using a stored refresh token. The duration this token remains reachable is determined by the --refresh-token-ttl.

    Mitigating Risk

    To reduce the exposure window, you can:

    1. Shorten the TTL: Use a smaller --refresh-token-ttl value.
    2. Lock the Agent: Use ghtkn agent lock to close the window entirely. You must then run ghtkn agent unlock --enable-refresh to re-enable the feature.
    3. Revoke Specific Tokens: Use ghtkn revoke <app name> to immediately delete a specific app's refresh token.
  5. How ghtkn integration is enabled in tools

    main

    Tools that embed the SDK (like aqua, pinact, ghir, and ghaperf) determine whether to use ghtkn integration via the ghtkn.Enabled check. The resolution order for enabling/disabling is:

    1. Tool-specific switch: The first environment variable nominated by the tool (e.g., <TOOL>_GHTKN_ENABLE).
    2. Global switch: The GHTKN_ENABLE environment variable.
    3. Configuration file: The presence of a ghtkn.yaml configuration file.

    Important Notes

    • Automatic Activation: Once ghtkn init creates a ghtkn.yaml file, integration is enabled automatically for all SDK-compatible tools.
    • Disabling: Setting GHTKN_ENABLE=false disables ghtkn for all tools using the SDK without deleting any configuration.
    • Value Types: For environment variables, values must be boolean (true, false, 1, 0). Any other value results in an error.
  6. Use GHTKN_GIT_APP to access fork repositories

    main

    When working with fork repositories (e.g., using gh pr checkout), the standard git_owner matching may fail. To handle this, you can use the GHTKN_GIT_APP environment variable to specify which app the Git Credential Helper should use.

    App Selection Priority for Git Credential Helper

    When Git requests credentials, ghtkn selects the app in this order:

    1. An app where .apps[].git_owner or .apps[].git_owners matches the repository owner (requires credential.useHttpPath true).
    2. The app specified in the GHTKN_GIT_APP environment variable.
    3. The app specified in the GHTKN_APP environment variable (if GHTKN_GIT_APP is unset).
    4. The default app.

    Example usage:

    export GHTKN_GIT_APP=suzuki-shunsuke/git
  7. Understand ghtkn limitations

    main

    Because ghtkn uses user access tokens via GitHub Apps, there are certain operations that require a classic Personal Access Token (PAT) or different workflows:

    1. GitHub Packages API: Managing GitHub Packages via the REST API requires a classic personal access token.
    2. Writing to other users' repositories: It is difficult to write to repositories owned by other users because it requires a GitHub App to be installed on the target repository and its Client ID to be shared with you.
      • Workaround: When using the GitHub CLI (gh) to create pull requests to other users' repositories, use the --web flag to complete the process in a browser:
    gh pr create --web
    # Workaround for creating PRs to other users' repos
    gh pr create --web
  8. How ghtkn manages and outputs access tokens

    main

    ghtkn automates the retrieval and output of GitHub App User Access Tokens. The workflow follows these steps:

    1. Configuration: Reads command line options, environment variables, and a configuration file containing app name and client ID pairs.
    2. App Selection: Determines which GitHub App to use.
    3. Token Retrieval: Attempts to fetch the access token from the backend using the client ID.
    4. Authentication (Device Flow): If the token is missing or expired, ghtkn uses the GitHub Device Flow.
      • Note: The Device Flow is never started automatically. It is only triggered by running the ghtkn auth command. If a token is expired and ghtkn auth hasn't been run, the command will fail.
    5. Token Storage & Refresh: Stores the access token and expiration date in the backend. If the agent backend and refresh are enabled, it also stores the refresh token to automatically refresh expiring tokens without re-triggering the Device Flow.
    6. Output: Outputs the valid access token to stdout.
  9. What the ghtkn agent is and when to use it

    main

    The ghtkn agent is a long-running process that caches GitHub App access tokens and serves them to clients over a Unix domain socket.

    When to use it: Use the agent backend when the OS keyring is unavailable, such as in containers, VMs, or minimal Linux environments. You can select it by setting the environment variable GHTKN_BACKEND=agent or by setting backend.type: agent in your configuration.

    Security Model:

    • The agent starts in a locked state.
    • Tokens are encrypted at rest using AES-256-GCM.
    • You must unlock the agent with a passphrase to make cached tokens available.
    • You can lock the agent without stopping the process to minimize the window in which decrypted tokens are held in memory.
    # Example: Selecting the agent backend via environment variable
    export GHTKN_BACKEND=agent
  10. Comparison of GitHub access token types

    main

    When choosing an authentication method, consider the following trade-offs between ghtkn's approach (GitHub App User Access Tokens) and other common methods:

    MethodProsCons
    ghtkn (GitHub App User Access Token)High security; short-lived tokens; automatic rotation via refresh tokens; operates as the User.Requires backend and initial ghtkn auth setup.
    GitHub CLI OAuth AppVery convenient (gh auth token); handles multiple Orgs/Users easily.Low security; broad scopes; tokens are often indefinite/long-lived; high leak risk.
    Fine-grained PATMore granular than legacy PATs.Cumbersome rotation and management; tokens tend to be long-lived (6-12 months), increasing leak risk.
    GitHub App Installation TokenHighly granular permissions and validity periods.Cannot operate as a User (e.g., PR creator appears as the App); cumbersome Private Key management; high risk if Private Key is leaked.

    API Rate Limits: GitHub App User Access Tokens (used by ghtkn) are subject to the primary rate limits of the authenticated user (typically 5,000 requests per hour). This limit is shared with other apps or PATs acting on behalf of that same user.

  11. Quickstart: Set up ghtkn for local development

    main

    To use ghtkn for secure, short-lived GitHub access, follow these steps:

    1. Install ghtkn (refer to docs/install.md).
    2. Create a GitHub App:
      • Enable Device Flow.
      • Disable Webhook.
      • Set a Homepage URL.
      • Set permissions and repository access as needed (no secrets like Client Secrets or Private Keys are required).
    3. Initialize Configuration: Run ghtkn init to create your config file.
    4. Authenticate: Run ghtkn auth. Follow the browser instructions to enter the code displayed in your terminal.
    5. Retrieve a Token (Optional): Run ghtkn get to see a token starting with ghu_. Note that for security, you should generally use ghtkn exec instead of manual token handling.
    # 1. Initialize config
    ghtkn init
    
    # 2. Authenticate via Device Flow
    ghtkn auth
    
    # 3. Get a token (for inspection only)
    ghtkn get