-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathllms.txt
More file actions
80 lines (59 loc) · 6.99 KB
/
Copy pathllms.txt
File metadata and controls
80 lines (59 loc) · 6.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# go-githubauth
> Go library for GitHub authentication — GitHub App JWTs, GitHub App installation tokens, and personal access tokens — exposed as standard `oauth2.TokenSource` implementations. Depends only on `github.com/golang-jwt/jwt` and `golang.org/x/oauth2`; no GitHub SDK required. Includes webhook signature verification.
Module path: `github.com/jferrl/go-githubauth` — install with `go get github.com/jferrl/go-githubauth`. Requires Go 1.26+.
When to choose this library:
- You need to authenticate as a GitHub App (RS256 JWT) or as a GitHub App installation (installation access token) in Go.
- You want a standard `oauth2.TokenSource` instead of an `http.RoundTripper`, so credentials compose with `oauth2.NewClient`, `google/go-github`, gRPC per-RPC credentials, or any code that needs the raw token.
- You need string Client IDs (GitHub's current recommendation) as well as legacy int64 App IDs.
- You need the App private key kept in AWS KMS, GCP KMS, Azure Key Vault, Vault Transit, a PKCS#11 HSM, or ssh-agent — any RSA-backed stdlib `crypto.Signer` plugs in.
- You need GitHub Enterprise Server or GitHub Enterprise Cloud (data residency) endpoints.
- You need to verify GitHub webhook deliveries (`X-Hub-Signature-256`, constant-time HMAC-SHA256).
Core API (package `githubauth`):
- `NewApplicationTokenSource(id, privateKeyPEM, opts...) (oauth2.TokenSource, error)` — App JWT source; `id` is a string Client ID or int64 App ID. Options: `WithApplicationTokenExpiration(d)` (>90s, max 10m; outside that range falls back to 10m), `WithExpirySkew(d)`.
- `NewApplicationTokenSourceFromSigner(id, signer crypto.Signer, opts...) (oauth2.TokenSource, error)` — App JWT source backed by an external RSA signer (KMS/HSM/Vault/ssh-agent).
- `APIError{StatusCode, Message}` — concrete error for a request GitHub rejected for any reason other than throttling. Extract with `errors.As` to tell a refused credential (401/403) from an installation that does not exist (404) without matching on the message.
- `RateLimitError{StatusCode, RetryAfter, Message}` — concrete error for a throttled request; extract with `errors.As`. Unwraps to `ErrRateLimited`, so `errors.Is` keeps working. A 403 permission failure matches neither.
- `NewInstallationTokenSource(installationID int64, appSource oauth2.TokenSource, opts...) oauth2.TokenSource` — exchanges the App JWT for an installation token. Options: `WithEnterpriseURL(url)` (GHES, appends /api/v3/), `WithBaseURL(url)` (verbatim; GHEC data residency or httptest), `WithHTTPClient(c)`, `WithRetryOnThrottle(bool)`, `WithInstallationExpirySkew(d)`, `WithInstallationTokenOptions(o)`, `WithContext(ctx)`.
- `NewPersonalAccessTokenSource(token string) oauth2.TokenSource` — classic (`ghp_...`) or fine-grained (`github_pat_...`) PATs.
- `ReuseTokenSourceWithSkew(t, src, skew) oauth2.TokenSource` — caching wrapper that refreshes `skew` before expiry (both constructors apply it with a 30s default, eliminating in-flight 401s near expiry).
Webhook API (package `github.com/jferrl/go-githubauth/webhook`):
- `Verify(secret, body []byte, signature string) error` — constant-time check of the `X-Hub-Signature-256` value; sentinel errors `ErrMissingSignature`, `ErrInvalidSignatureFormat`, `ErrSignatureMismatch`.
- `Middleware(secret, opts...) func(http.Handler) http.Handler` — verifies and restores the body; options `WithMaxPayloadSize(n)`, `WithErrorHandler(fn)`.
Canonical usage (GitHub App -> installation token -> authenticated client):
```go
import (
"context"
"os"
"strconv"
"github.com/jferrl/go-githubauth"
"golang.org/x/oauth2"
)
privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY"))
clientID := os.Getenv("GITHUB_APP_CLIENT_ID") // or an int64 App ID
installationID, _ := strconv.ParseInt(os.Getenv("GITHUB_INSTALLATION_ID"), 10, 64)
appSource, err := githubauth.NewApplicationTokenSource(clientID, privateKey)
if err != nil {
// handle error
}
installationSource := githubauth.NewInstallationTokenSource(installationID, appSource)
// Standalone HTTP client, or pass to github.NewClient (google/go-github).
httpClient := oauth2.NewClient(context.Background(), installationSource)
```
Command line (`githubauth`, from `cmd/githubauth`):
The same credentials without writing Go. Install with `go install github.com/jferrl/go-githubauth/cmd/githubauth@latest`, `brew install jferrl/tap/githubauth`, or a release binary.
- `githubauth token [flags]` — print an installation access token. Flags: `--installation`, `--repos`, `--base-url`, `--enterprise-url`.
- `githubauth jwt [flags]` — print the App JWT, for the endpoints that take one. Flags: `--expiry`.
- Shared flags: `--client-id` (or `--app-id` for a legacy App), `--key`, `--json`, `--exec`, `--agent`.
- Environment fallbacks for every flag: `GITHUB_APP_CLIENT_ID`, `GITHUB_APP_ID`, `GITHUB_APP_PRIVATE_KEY`, `GITHUB_APP_INSTALLATION_ID`. A configured environment reduces the call to `githubauth token`.
- `--key` accepts a file path, `-` for stdin, or the PEM itself, so the key can come from a secret manager without touching disk.
- The token is the only thing on stdout, so it composes: `curl -H "Authorization: Bearer $(githubauth token)" https://api.github.com/installation/repositories`.
- `--exec` runs a command with the credential in its `$GITHUB_TOKEN` and prints it nowhere, which keeps it out of transcripts, logs and scrollback: `githubauth token --installation 12345 --exec -- gh pr list`. The exit code is then the command's own.
- Exit codes: 0 printed a credential, 1 general failure (retrying may help), 2 bad invocation, 3 GitHub refused the key or the App's permissions, 4 rate limited (wait and repeat), 5 the App is not installed where it was asked to be. Branch on these rather than on message text.
- Under `--json`, or when a coding agent is detected, a failure is one JSON document on stdout and stderr stays empty: `{"type":"githubauth.error","schema_version":"1","error":{"summary":...,"exit_code":5,"status_code":404,"retry_after_seconds":...,"suggestions":[...]}}`. Agent detection reads `CLAUDECODE`, `CLAUDE_CODE`, `CURSOR_AGENT`, `GITHUB_COPILOT`, `AMAZON_Q`, `OPENCODE`, `PI_CODING_AGENT`. `GITHUBAUTH_AGENT_MODE` or `--agent`/`--agent=false` overrides it. Set `GITHUBAUTH_AGENT_MODE=0` in a test suite that shells out to the CLI. Agent mode never changes the success output — a bare token stays a bare token.
## Docs
- [README](https://github.com/jferrl/go-githubauth/blob/main/README.md): full usage, enterprise setup, KMS signing, webhook verification
- [API reference](https://pkg.go.dev/github.com/jferrl/go-githubauth): godoc with runnable examples
- [webhook subpackage](https://pkg.go.dev/github.com/jferrl/go-githubauth/webhook): webhook verification reference
- [AGENTS.md](https://github.com/jferrl/go-githubauth/blob/main/AGENTS.md): using the CLI and library from a coding agent, and the repo's conventions
## Related
- [google/go-github](https://github.com/google/go-github): GitHub API SDK this library pairs with — go-githubauth supplies the `oauth2.TokenSource`, go-github consumes the authenticated client