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.