--- description: Use the ghtkn Go SDK, which lets tools such as aqua, pinact, ghir, and ghaperf reuse ghtkn tokens without a PAT. Use when a tool's ghtkn integration doesn't kick in, when deciding what enables it (the configuration file alone is usually enough - GHTKN_ENABLE and tool-specific switches only override it), or when embedding ghtkn in your own Go CLI. --- # Go SDK [ghtkn Go SDK](https://pkg.go.dev/github.com/suzuki-shunsuke/ghtkn-go-sdk/ghtkn) lets a Go application obtain GitHub App User Access Tokens the same way the ghtkn CLI does - normally by reading the token ghtkn has already stored in the [backend](backend.md). ghtkn itself is built on it, so a tool using the SDK reads the same configuration file, the same backend, and the same cached tokens as the `ghtkn` command. There are two sides to this document: using a tool that already embeds the SDK, and embedding it in your own CLI. ## Tools that already use the SDK [aqua](https://aquaproj.github.io/), [pinact](https://github.com/suzuki-shunsuke/pinact), [ghir](https://github.com/suzuki-shunsuke/ghir), and [ghaperf](https://github.com/suzuki-shunsuke/ghaperf) embed the SDK. They obtain a ghtkn access token themselves, so you don't have to set `GITHUB_TOKEN` for them or wrap them in [`ghtkn exec`](exec.md). Nothing has to be wired up: install ghtkn, run `ghtkn auth` once, and these tools authenticate as you with a short-lived token. ## When the integration is enabled Normally nothing enables the integration but the [ghtkn configuration file](configuration.md): once `ghtkn init` has created `ghtkn.yaml`, every tool that embeds the SDK turns it on by itself, and no environment variable has to be set. The variables below only override that, and the one worth knowing is the one that turns it off - `GHTKN_ENABLE=false` disables ghtkn for every tool that uses the SDK without deleting anything. This is about enabling and disabling only; variables that decide what ghtkn does, such as `GHTKN_APP`, are a separate matter - see [Using Multiple Apps](multiple-apps.md). A tool asks the SDK whether the integration should be enabled (`ghtkn.Enabled`), and the answer is resolved in this order: 1. the first environment variable the tool itself nominates that is set, if it defines one (for instance a tool-specific `_GHTKN_ENABLE` switch - check the tool's own documentation), 1. the `GHTKN_ENABLE` environment variable, 1. whether the [ghtkn configuration file](configuration.md) exists. For the first two, the value must be a boolean (`true`, `false`, `1`, `0`); anything else is an error rather than a silent "disabled". A tool-specific switch wins over `GHTKN_ENABLE`, so a leftover `_GHTKN_ENABLE=false` keeps that one tool disabled however `GHTKN_ENABLE` is set. Being enabled is not the same as running the device flow. A tool using the SDK never runs the device flow, just as `ghtkn get` doesn't, so it fails rather than prompting when there is no usable token. Run [`ghtkn auth`](token-management.md) yourself beforehand; that is the interactive part, and it belongs in your terminal, not inside another tool's run. ## When the integration doesn't work Almost always a version is old, on one side or the other, so find out which versions are actually in play before reasoning about what the tool does. Run these three checks first: 1. Which version of the tool is installed - ` --version`, compared with the tool's latest release. Check the installed binary, not a source checkout: a checkout is usually `main`, which can be far ahead of what the user runs, so reading it tells you how a version nobody is running behaves. 1. Which SDK version that binary was built with - `go version -m "$(command -v )" | grep ghtkn-go-sdk`. The tools above are all Go binaries, so this reports the embedded SDK version without checking anything out. For a tool managed by aqua, pass `"$(aqua which )"` instead, because what is on your `PATH` is the aqua proxy. 1. What ghtkn itself resolves - `ghtkn info` prints the resolved configuration, the backend in use, and every `GHTKN_*` variable ghtkn reads. See [Troubleshooting](troubleshooting.md). Then check the SDK version from step 2 against the boundaries below. The SDK is a separate module from the CLI, so a tool keeps whatever SDK version it was built with until it is rebuilt and released - a current `ghtkn` binary does not upgrade the SDK inside `aqua` or `pinact`. Updating the tool is what moves the SDK, so update both the tool and the ghtkn CLI to their latest versions. Version boundaries worth knowing: - SDK `>= v0.3.0` - `ghtkn.Enabled` exists, so the integration turns on automatically when the configuration file exists. Older SDKs required the tool's own switch. - SDK `>= v0.3.0` - the [agent backend](backend.md) is supported. Older SDKs cannot read tokens from it. - SDK `>= v0.4.0` - the backend set in the configuration file is respected. Older SDKs ignore it, so a tool may look in the keyring while ghtkn stores tokens in the agent. Nothing warns you when a boundary isn't met. A tool built against an older SDK simply behaves the way that SDK behaves, so a token `ghtkn get` returns fine can be invisible to the tool. The same boundary decides whether an old environment variable can go. A tool's own switch used to be the only way to turn the integration on, so many setups still set one; from SDK v0.3.0 on it is redundant, because the configuration file enables the integration by itself. Check the version from step 2 before deleting it: against an older SDK that switch is what turns the integration on, and removing it turns the integration off with nothing warning you. ## Embedding the SDK in your own CLI The API reference is the [SDK's Go documentation](https://pkg.go.dev/github.com/suzuki-shunsuke/ghtkn-go-sdk/ghtkn), and runnable examples live in [the SDK repository](https://github.com/suzuki-shunsuke/ghtkn-go-sdk/tree/main/examples). Both ship with the SDK, so they describe the version you actually depend on; this document deliberately doesn't restate them. Two things are worth knowing before you read them, because they are decisions ghtkn made rather than API details: - `Client.Get` never starts the device flow, so a token that could only come from one makes it fail with `ghtkn.ErrDisableDeviceFlow` instead of prompting. Tell the user to run `ghtkn auth`. It is the interactive path that is closed, not token creation: with the agent backend and [refresh](refresh-token.md) enabled, `Get` still renews an expiring token silently. The device flow runs only in `Client.Auth`, which is what `ghtkn auth` calls; unless you are writing something that authenticates, you want `Get`. - The access token you get back is a live secret. Don't print it, log it, or include it in an error message. See [Token Management](token-management.md).