go-githubauth is a Go package that provides utilities for GitHub authentication, including generating and using GitHub App tokens, installation tokens, and personal access tokens.
v1.5.0 removes the go-github dependency, implementing a lightweight internal GitHub API client. This reduces external dependencies while maintaining full compatibility with the OAuth2 token source interface.
⭐ Found this package useful? Give it a star on GitHub! Your support helps others discover this project and motivates continued development.
go-githubauth package provides implementations of the TokenSource interface from the golang.org/x/oauth2 package. This interface has a single method, Token, which returns an *oauth2.Token.
- 📦 Zero External Dependencies: Removed go-githubdependency - lightweight internal implementation
- 🔐 Personal Access Token Support: Native support for both classic and fine-grained personal access tokens
- ⚡ Token Caching: Dual-layer caching system for optimal performance
- JWT tokens cached until expiration (up to 10 minutes)
- Installation tokens cached until expiration (defined by GitHub response)
 
- 🚀 Pooled HTTP Client: Production-ready HTTP client with connection pooling
- 📈 Performance Optimizations: Up to 99% reduction in unnecessary GitHub API calls
- 🏗️ Production Ready: Optimized for high-throughput and enterprise applications
- 🌐 Simplified Enterprise Support: Streamlined configuration with single base URL parameter
- Generate GitHub Application JWT Generating a jwt for a github app
- Obtain GitHub App installation tokens Authenticating as a GitHub App
- Authenticate with Personal Access Tokens (classic and fine-grained) Managing your personal access tokens
- RS256-signed JWTs with proper clock drift protection
- Support for both legacy App IDs and modern Client IDs (recommended by GitHub)
- Intelligent token caching with automatic refresh for optimal performance
- Clean HTTP clients with connection pooling and no shared state
- Go 1.21 or higher (for generics support)
- This package is designed to be used with the golang.org/x/oauth2package
- No external GitHub SDK dependencies required
To use go-githubauth in your project, you need to have Go installed. You can get the package via:
go get -u github.com/jferrl/go-githubauthUsage with oauth2
You can use this package standalone with any HTTP client, or integrate it with the go-github SDK if you need additional GitHub API functionality.
package main
import (
 "context"
 "fmt"
 "os"
 "strconv"
 "github.com/google/go-github/v76/github"
 "github.com/jferrl/go-githubauth"
 "golang.org/x/oauth2"
)
func main() {
 privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY"))
 clientID := os.Getenv("GITHUB_APP_CLIENT_ID") // e.g., "Iv1.1234567890abcdef"
 installationID, _ := strconv.ParseInt(os.Getenv("GITHUB_INSTALLATION_ID"), 10, 64)
 // Go automatically infers the type as string for Client ID
 appTokenSource, err := githubauth.NewApplicationTokenSource(clientID, privateKey)
 if err != nil {
  fmt.Println("Error creating application token source:", err)
  return
 }
 installationTokenSource := githubauth.NewInstallationTokenSource(installationID, appTokenSource)
 // oauth2.NewClient creates a new http.Client that adds an Authorization header with the token
 httpClient := oauth2.NewClient(context.Background(), installationTokenSource)
 githubClient := github.NewClient(httpClient)
 _, _, err = githubClient.PullRequests.CreateComment(context.Background(), "owner", "repo", 1, &github.PullRequestComment{
  Body: github.String("Awesome comment!"),
 })
 if err != nil {
  fmt.Println("Error creating comment:", err)
  return
 }
}package main
import (
 "context"
 "fmt"
 "os"
 "strconv"
 "github.com/google/go-github/v76/github"
 "github.com/jferrl/go-githubauth"
 "golang.org/x/oauth2"
)
func main() {
 privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY"))
 appID, _ := strconv.ParseInt(os.Getenv("GITHUB_APP_ID"), 10, 64)
 installationID, _ := strconv.ParseInt(os.Getenv("GITHUB_INSTALLATION_ID"), 10, 64)
 // Explicitly cast to int64 for App ID - Go automatically infers the type
 appTokenSource, err := githubauth.NewApplicationTokenSource(int64(appID), privateKey)
 if err != nil {
  fmt.Println("Error creating application token source:", err)
  return
 }
 installationTokenSource := githubauth.NewInstallationTokenSource(installationID, appTokenSource)
 httpClient := oauth2.NewClient(context.Background(), installationTokenSource)
 githubClient := github.NewClient(httpClient)
 _, _, err = githubClient.PullRequests.CreateComment(context.Background(), "owner", "repo", 1, &github.PullRequestComment{
  Body: github.String("Awesome comment!"),
 })
 if err != nil {
  fmt.Println("Error creating comment:", err)
  return
 }
}First, create a GitHub App and generate a private key. To authenticate as a GitHub App, you need to generate a JWT. Generating a JWT for a GitHub App
package main
import (
 "fmt"
 "os"
 "time"
 "github.com/jferrl/go-githubauth"
)
func main() {
 privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY"))
 clientID := os.Getenv("GITHUB_APP_CLIENT_ID") // e.g., "Iv1.1234567890abcdef"
 // Type automatically inferred as string
 tokenSource, err := githubauth.NewApplicationTokenSource(
  clientID, 
  privateKey, 
  githubauth.WithApplicationTokenExpiration(5*time.Minute),
 )
 if err != nil {
  fmt.Println("Error creating token source:", err)
  return
 }
 token, err := tokenSource.Token()
 if err != nil {
  fmt.Println("Error generating token:", err)
  return
 }
 fmt.Println("Generated JWT token:", token.AccessToken)
}package main
import (
 "fmt"
 "os"
 "strconv"
 "time"
 "github.com/jferrl/go-githubauth"
)
func main() {
 privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY"))
 appID, _ := strconv.ParseInt(os.Getenv("GITHUB_APP_ID"), 10, 64)
 // Type automatically inferred as int64
 tokenSource, err := githubauth.NewApplicationTokenSource(
  int64(appID), 
  privateKey, 
  githubauth.WithApplicationTokenExpiration(5*time.Minute),
 )
 if err != nil {
  fmt.Println("Error creating token source:", err)
  return
 }
 token, err := tokenSource.Token()
 if err != nil {
  fmt.Println("Error generating token:", err)
  return
 }
 fmt.Println("Generated JWT token:", token.AccessToken)
}To authenticate as a GitHub App installation, you need to obtain an installation token using your GitHub App JWT.
package main
import (
 "fmt"
 "os"
 "strconv"
 "github.com/jferrl/go-githubauth"
)
func main() {
 privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY"))
 clientID := os.Getenv("GITHUB_APP_CLIENT_ID") // e.g., "Iv1.1234567890abcdef"
 installationID, _ := strconv.ParseInt(os.Getenv("GITHUB_INSTALLATION_ID"), 10, 64)
 // Create GitHub App JWT token source with Client ID
 appTokenSource, err := githubauth.NewApplicationTokenSource(clientID, privateKey)
 if err != nil {
  fmt.Println("Error creating application token source:", err)
  return
 }
 // Create installation token source using the app token source
 installationTokenSource := githubauth.NewInstallationTokenSource(installationID, appTokenSource)
 token, err := installationTokenSource.Token()
 if err != nil {
  fmt.Println("Error generating installation token:", err)
  return
 }
 fmt.Println("Generated installation token:", token.AccessToken)
}GitHub Personal Access Tokens provide direct authentication for users and organizations. This package supports both classic personal access tokens and fine-grained personal access tokens.
package main
import (
 "context"
 "fmt"
 "io"
 "net/http"
 "os"
 "github.com/jferrl/go-githubauth"
 "golang.org/x/oauth2"
)
func main() {
 // Personal access token from environment variable
 token := os.Getenv("GITHUB_TOKEN") // e.g., "ghp_..." or "github_pat_..."
 // Create token source
 tokenSource := githubauth.NewPersonalAccessTokenSource(token)
 // Create HTTP client with OAuth2 transport
 httpClient := oauth2.NewClient(context.Background(), tokenSource)
 // Use the HTTP client for GitHub API calls
 resp, err := httpClient.Get("https://api.github.com/user")
 if err != nil {
  fmt.Println("Error getting user:", err)
  return
 }
 defer resp.Body.Close()
 body, _ := io.ReadAll(resp.Body)
 fmt.Printf("User info: %s\n", body)
}package main
import (
 "context"
 "fmt"
 "os"
 "github.com/google/go-github/v76/github"
 "github.com/jferrl/go-githubauth"
 "golang.org/x/oauth2"
)
func main() {
 // Personal access token from environment variable
 token := os.Getenv("GITHUB_TOKEN") // e.g., "ghp_..." or "github_pat_..."
 // Create token source
 tokenSource := githubauth.NewPersonalAccessTokenSource(token)
 // Create HTTP client with OAuth2 transport
 httpClient := oauth2.NewClient(context.Background(), tokenSource)
 githubClient := github.NewClient(httpClient)
 // Use the GitHub client for API calls
 user, _, err := githubClient.Users.Get(context.Background(), "")
 if err != nil {
  fmt.Println("Error getting user:", err)
  return
 }
 fmt.Printf("Authenticated as: %s\n", user.GetLogin())
}- Classic Personal Access Token: Visit GitHub Settings > Developer settings > Personal access tokens > Tokens (classic)
- Fine-grained Personal Access Token: Visit GitHub Settings > Developer settings > Personal access tokens > Fine-grained tokens
🔐 Security Note: Store your personal access tokens securely and never commit them to version control. Use environment variables or secure credential management systems.
Contributions are welcome! Please open an issue or submit a pull request on GitHub.
This project is licensed under the MIT License. See the LICENSE file for details.