Documentation
¶
Overview ¶
Package githubauth provides utilities for GitHub authentication, including generating and using GitHub App tokens and installation tokens.
This package implements oauth2.TokenSource interfaces for GitHub App authentication and GitHub App installation token generation. It is built on top of the golang.org/x/oauth2 library.
Index ¶
- Constants
- Variables
- func NewApplicationTokenSource[T Identifier](id T, privateKey []byte, opts ...ApplicationTokenOpt) (oauth2.TokenSource, error)
- func NewApplicationTokenSourceFromSigner[T Identifier](id T, signer crypto.Signer, opts ...ApplicationTokenOpt) (oauth2.TokenSource, error)
- func NewInstallationTokenSource(id int64, src oauth2.TokenSource, opts ...InstallationTokenSourceOpt) oauth2.TokenSource
- func NewPersonalAccessTokenSource(token string) oauth2.TokenSource
- func Ptr[T any](v T) *T
- func ReuseTokenSourceWithSkew(t *oauth2.Token, src oauth2.TokenSource, skew time.Duration) oauth2.TokenSource
- type ApplicationTokenOpt
- type Identifier
- type InstallationPermissions
- type InstallationToken
- type InstallationTokenOptions
- type InstallationTokenSourceOpt
- func WithContext(ctx context.Context) InstallationTokenSourceOpt
- func WithEnterpriseURL(baseURL string) InstallationTokenSourceOpt
- func WithHTTPClient(client *http.Client) InstallationTokenSourceOpt
- func WithInstallationExpirySkew(d time.Duration) InstallationTokenSourceOpt
- func WithInstallationTokenOptions(opts *InstallationTokenOptions) InstallationTokenSourceOpt
- func WithRetryOnThrottle(enabled bool) InstallationTokenSourceOpt
- type Repository
Constants ¶
const ( // DefaultApplicationTokenExpiration is the default expiration time for GitHub App tokens. // The maximum allowed expiration is 10 minutes. DefaultApplicationTokenExpiration = 10 * time.Minute // DefaultExpirySkew is the default early-refresh window applied to cached // tokens returned by NewApplicationTokenSource and NewInstallationTokenSource. // At 30s the effective validity of a default 10-minute application JWT becomes // 9m30s, which is acceptable and eliminates the common in-flight 401 caused // by a request starting near exp and arriving at GitHub after exp. DefaultExpirySkew = 30 * time.Second )
Variables ¶
var ErrRateLimited = errors.New("github API rate limited")
ErrRateLimited wraps errors returned when GitHub has throttled a request (HTTP 429 or 403 with rate-limit headers). Callers can branch with errors.Is.
Functions ¶
func NewApplicationTokenSource ¶
func NewApplicationTokenSource[T Identifier](id T, privateKey []byte, opts ...ApplicationTokenOpt) (oauth2.TokenSource, error)
NewApplicationTokenSource creates a GitHub App JWT token source from a PEM-encoded RSA private key. Accepts either int64 App ID or string Client ID. GitHub recommends Client IDs for new apps. Generated JWTs are RS256-signed with iat, exp, and iss claims. JWTs expire in max 10 minutes and include clock drift protection (iat set 60s in past).
The returned token source is wrapped in ReuseTokenSourceWithSkew with DefaultExpirySkew (30s), so cached tokens are refreshed before exp rather than after. With the default 10-minute expiration the effective validity is 9m30s. Override with WithExpirySkew.
For KMS, HSM, Vault, or ssh-agent backed signing, use NewApplicationTokenSourceFromSigner instead — the private key never leaves its secure boundary.
func NewApplicationTokenSourceFromSigner ¶ added in v1.6.0
func NewApplicationTokenSourceFromSigner[T Identifier](id T, signer crypto.Signer, opts ...ApplicationTokenOpt) (oauth2.TokenSource, error)
NewApplicationTokenSourceFromSigner creates a GitHub App JWT token source backed by an external crypto.Signer. Any RSA-backed signer works: AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault Transit, PKCS#11 HSMs, or ssh-agent. The private key never touches process memory.
The signer's public key must be RSA — GitHub requires RS256 (RSASSA-PKCS1-v1_5 with SHA-256, per RFC 7518 §3.3). The signer must return signatures in that form when called with crypto.SHA256; every stdlib-compatible RSA signer does.
func NewInstallationTokenSource ¶
func NewInstallationTokenSource(id int64, src oauth2.TokenSource, opts ...InstallationTokenSourceOpt) oauth2.TokenSource
NewInstallationTokenSource creates a GitHub App installation token source. Requires installation ID and a GitHub App JWT token source for authentication.
The returned token source is wrapped in ReuseTokenSourceWithSkew so cached tokens are refreshed DefaultExpirySkew before their expiry, eliminating in-flight 401s when a request starts close to exp and reaches GitHub after. Override the window with WithInstallationExpirySkew.
func NewPersonalAccessTokenSource ¶ added in v1.4.0
func NewPersonalAccessTokenSource(token string) oauth2.TokenSource
NewPersonalAccessTokenSource creates a token source for GitHub personal access tokens. The provided token should be a valid GitHub personal access token (classic or fine-grained). This token source returns the same token value for all Token() calls without expiration, making it suitable for long-lived authentication scenarios.
func Ptr ¶ added in v1.5.0
func Ptr[T any](v T) *T
Ptr is a helper function to create a pointer to a value. This is useful when constructing InstallationTokenOptions with permissions.
func ReuseTokenSourceWithSkew ¶ added in v1.6.0
func ReuseTokenSourceWithSkew(t *oauth2.Token, src oauth2.TokenSource, skew time.Duration) oauth2.TokenSource
ReuseTokenSourceWithSkew wraps src so cached tokens are refreshed proactively, skew before their expiry. oauth2.ReuseTokenSource refreshes only once exp has passed (via oauth2.Token.Valid), so a request that starts at T-100ms with a token expiring at T can arrive at GitHub already expired and yield a 401 the caller must manually retry. This wrapper refreshes when time.Until(t.Expiry) <= skew, cutting out that race.
If skew is zero or negative the wrapper delegates to oauth2.ReuseTokenSource, preserving its exact behavior. An initial non-nil t is used until it needs refresh under the same rule. The returned source is safe for concurrent use; concurrent Token calls that find the cache stale collapse into a single upstream fetch.
Types ¶
type ApplicationTokenOpt ¶
type ApplicationTokenOpt func(*applicationTokenSource)
ApplicationTokenOpt is a functional option for configuring an applicationTokenSource.
func WithApplicationTokenExpiration ¶
func WithApplicationTokenExpiration(exp time.Duration) ApplicationTokenOpt
WithApplicationTokenExpiration sets the JWT expiration duration. Must be between 0 and 10 minutes per GitHub's JWT requirements. Invalid values default to 10 minutes. See https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/generating-a-json-web-token-jwt-for-a-github-app#about-json-web-tokens-jwts
func WithExpirySkew ¶ added in v1.6.0
func WithExpirySkew(d time.Duration) ApplicationTokenOpt
WithExpirySkew overrides the default early-refresh window (DefaultExpirySkew, 30s) applied to the token cache returned by NewApplicationTokenSource. The cached token is refreshed when time.Until(exp) <= d. A zero or negative value disables the skew and falls back to oauth2.ReuseTokenSource behavior (refresh only after exp has passed).
Tune this when your application token expiration (see WithApplicationTokenExpiration) is short: the effective validity is expiration - skew, so with the default 10-minute expiration and 30s skew tokens are refreshed at 9m30s.
type Identifier ¶ added in v1.3.0
Identifier constrains GitHub App identifiers to int64 (App ID) or string (Client ID).
type InstallationPermissions ¶ added in v1.5.0
type InstallationPermissions struct {
Actions *string `json:"actions,omitempty"`
Administration *string `json:"administration,omitempty"`
Checks *string `json:"checks,omitempty"`
Contents *string `json:"contents,omitempty"`
ContentReferences *string `json:"content_references,omitempty"`
Deployments *string `json:"deployments,omitempty"`
Environments *string `json:"environments,omitempty"`
Issues *string `json:"issues,omitempty"`
Metadata *string `json:"metadata,omitempty"`
Packages *string `json:"packages,omitempty"`
Pages *string `json:"pages,omitempty"`
PullRequests *string `json:"pull_requests,omitempty"`
RepositoryAnnouncementBanners *string `json:"repository_announcement_banners,omitempty"`
RepositoryHooks *string `json:"repository_hooks,omitempty"`
RepositoryProjects *string `json:"repository_projects,omitempty"`
SecretScanningAlerts *string `json:"secret_scanning_alerts,omitempty"`
Secrets *string `json:"secrets,omitempty"`
SecurityEvents *string `json:"security_events,omitempty"`
SingleFile *string `json:"single_file,omitempty"`
Statuses *string `json:"statuses,omitempty"`
VulnerabilityAlerts *string `json:"vulnerability_alerts,omitempty"`
Workflows *string `json:"workflows,omitempty"`
Members *string `json:"members,omitempty"`
OrganizationAdministration *string `json:"organization_administration,omitempty"`
OrganizationCustomRoles *string `json:"organization_custom_roles,omitempty"`
OrganizationAnnouncementBanners *string `json:"organization_announcement_banners,omitempty"`
OrganizationHooks *string `json:"organization_hooks,omitempty"`
OrganizationPlan *string `json:"organization_plan,omitempty"`
OrganizationProjects *string `json:"organization_projects,omitempty"`
OrganizationPackages *string `json:"organization_packages,omitempty"`
OrganizationSecrets *string `json:"organization_secrets,omitempty"`
OrganizationSelfHostedRunners *string `json:"organization_self_hosted_runners,omitempty"`
OrganizationUserBlocking *string `json:"organization_user_blocking,omitempty"`
TeamDiscussions *string `json:"team_discussions,omitempty"`
}
InstallationPermissions represents the permissions granted to an installation token.
type InstallationToken ¶ added in v1.5.0
type InstallationToken struct {
Token string `json:"token"`
ExpiresAt time.Time `json:"expires_at"`
Permissions *InstallationPermissions `json:"permissions,omitempty"`
Repositories []Repository `json:"repositories,omitempty"`
}
InstallationToken represents a GitHub App installation token.
type InstallationTokenOptions ¶ added in v1.5.0
type InstallationTokenOptions struct {
// Repositories is a list of repository names that the token should have access to.
Repositories []string `json:"repositories,omitempty"`
// RepositoryIDs is a list of repository IDs that the token should have access to.
RepositoryIDs []int64 `json:"repository_ids,omitempty"`
// Permissions are the permissions granted to the access token.
Permissions *InstallationPermissions `json:"permissions,omitempty"`
}
InstallationTokenOptions specifies options for creating an installation token.
type InstallationTokenSourceOpt ¶
type InstallationTokenSourceOpt func(*installationTokenSource)
InstallationTokenSourceOpt is a functional option for InstallationTokenSource.
func WithContext ¶ added in v1.1.0
func WithContext(ctx context.Context) InstallationTokenSourceOpt
WithContext sets the context for the GitHub App installation token source.
func WithEnterpriseURL ¶ added in v1.5.0
func WithEnterpriseURL(baseURL string) InstallationTokenSourceOpt
WithEnterpriseURL sets the base URL for GitHub Enterprise Server. This option should be used after WithHTTPClient to ensure the HTTP client is properly configured. If the provided base URL is invalid, the option is ignored and default GitHub base URL is used.
func WithHTTPClient ¶
func WithHTTPClient(client *http.Client) InstallationTokenSourceOpt
WithHTTPClient sets the HTTP client for the GitHub App installation token source.
func WithInstallationExpirySkew ¶ added in v1.6.0
func WithInstallationExpirySkew(d time.Duration) InstallationTokenSourceOpt
WithInstallationExpirySkew overrides the default early-refresh window (DefaultExpirySkew, 30s) applied to the installation token cache returned by NewInstallationTokenSource. Installation tokens live 1 hour, so the 30s default leaves ~59m30s effective validity — this option exists mostly for parity with WithExpirySkew. A zero or negative value falls back to oauth2.ReuseTokenSource behavior.
func WithInstallationTokenOptions ¶
func WithInstallationTokenOptions(opts *InstallationTokenOptions) InstallationTokenSourceOpt
WithInstallationTokenOptions sets the options for the GitHub App installation token.
func WithRetryOnThrottle ¶ added in v1.6.0
func WithRetryOnThrottle(enabled bool) InstallationTokenSourceOpt
WithRetryOnThrottle enables or disables a single automatic retry when GitHub returns a throttled response (HTTP 429, or 403 with rate-limit headers) for the installation token POST. Enabled by default.
On a throttled response the client sleeps the duration hinted by Retry-After or x-ratelimit-reset (capped at 60s, honoring ctx cancellation) and retries once. Subsequent failures bubble up unchanged. On a terminal throttle the returned error wraps ErrRateLimited so callers can branch with errors.Is.
Disable this when the caller implements its own backoff or when deterministic latency matters more than transient rate-limit resilience.
type Repository ¶ added in v1.5.0
Repository represents a GitHub repository.