Go library for OpenID Connect authentication and JWT management in distributed systems.
Built with Vibe Coding: This entire project was developed using vibe-based planning and programming.
- Multi-Provider Support: Works with Azure AD, Google, Okta, Auth0, or any OIDC provider
- Distributed JWT Architecture: Issue internal JWTs with JWKS endpoints for service verification
- Multi-Instance Ready: Supports horizontal scaling with shared key management
- HTTP Middleware: Simple JWT verification middleware for web services
- Production Security: Built-in security best practices and proven cryptography
- Clean Go Design: Follows Go conventions with context-first interfaces
go get github.com/davidbz/go-oidc-auth
Perfect for microservices that need to issue and verify tokens:
package main
import (
"context"
"fmt"
"time"
"github.com/davidbz/go-oidc-auth/pkg/jwt"
)
func main() {
config := jwt.Config{
Issuer: "https://auth.mycompany.com",
Audience: "myapp-api",
Expiry: 30 * time.Minute,
}
// Create signer and verifier
signer, _ := jwt.NewSigner(config)
keySet, _ := signer.GetJWKS(context.Background())
verifier := jwt.NewVerifier(config, *keySet)
// Issue JWT
claims := jwt.Claims{
Subject: "user123",
Email: "user@company.com",
Provider: "internal",
Custom: map[string]interface{}{
"role": "admin",
},
}
token, _ := signer.Sign(context.Background(), claims)
fmt.Printf("JWT: %s...\n", token[:50])
// Verify JWT
verifiedClaims, _ := verifier.Verify(context.Background(), token)
fmt.Printf("Verified user: %s\n", verifiedClaims.Email)
}
For distributed deployments where multiple instances need consistent JWT operations:
package main
import (
"context"
"fmt"
"os"
"github.com/davidbz/go-oidc-auth/pkg/jwt"
)
func main() {
config := jwt.Config{
Issuer: "https://auth.mycompany.com",
Audience: "myapp-api",
Expiry: 30 * time.Minute,
}
// Load shared private key (all instances use the same key)
privateKeyPEM := loadPrivateKeyFromSecureStorage() // Your key management
// Create signer with shared key
signer, _ := jwt.NewSignerWithPEM(config, privateKeyPEM)
keySet, _ := signer.GetJWKS(context.Background())
verifier := jwt.NewVerifier(config, *keySet)
// Now all instances can verify each other's JWTs
claims := jwt.Claims{
Subject: "user123",
Email: "user@company.com",
Provider: "internal",
Custom: map[string]interface{}{
"role": "admin",
"instance": os.Getenv("INSTANCE_ID"),
},
}
token, _ := signer.Sign(context.Background(), claims)
verifiedClaims, _ := verifier.Verify(context.Background(), token)
fmt.Printf("Token verified across instances: %s\n", verifiedClaims.Email)
}
Complete authentication flow with external providers:
import (
"github.com/davidbz/go-oidc-auth/pkg/auth"
"github.com/davidbz/go-oidc-auth/pkg/config"
"github.com/davidbz/go-oidc-auth/pkg/providers"
"github.com/davidbz/go-oidc-auth/pkg/jwt"
)
func main() {
// Configure providers
config := config.Config{
JWT: jwt.Config{
Issuer: "https://myapp.com",
Audience: "myapp-users",
Expiry: 30 * time.Minute,
},
Providers: []providers.ProviderConfig{
{
Name: "azure",
ClientID: "your-client-id",
ClientSecret: "your-client-secret",
IssuerURL: "https://login.microsoftonline.com/tenant/v2.0",
RedirectURI: "http://localhost:8080/auth/callback",
Scopes: []string{"openid", "profile", "email"},
},
},
}
// Setup authentication manager
signer, _ := jwt.NewSigner(config.JWT)
keySet, _ := signer.GetJWKS(context.Background())
verifier := jwt.NewVerifier(config.JWT, *keySet)
registry := providers.NewRegistry()
manager := auth.NewManager(config, registry, signer, verifier)
// Register providers and handle auth flow
manager.RegisterProvider(context.Background(), config.Providers[0])
// In your HTTP handlers:
// loginURL, _ := manager.GetLoginURL(ctx, "azure", "secure-state")
// tokenResponse, _ := manager.HandleCallback(ctx, "azure", code, state)
}
Verify JWTs from other services:
import (
"context"
"net/http"
"github.com/davidbz/go-oidc-auth/pkg/jwt"
"github.com/lestrrat-go/jwx/v2/jwk"
)
// Fetch public keys from auth service
resp, _ := http.Get("https://auth.company.com/.well-known/jwks.json")
defer resp.Body.Close()
keySet, _ := jwk.ParseReader(resp.Body)
config := jwt.Config{
Issuer: "https://auth.company.com",
Audience: "myapp-api",
}
verifier := jwt.NewVerifier(config, keySet)
// Verify incoming JWT
claims, err := verifier.Verify(context.Background(), tokenString)
Easily protect HTTP endpoints with JWT verification:
import (
"context"
"net/http"
"time"
"github.com/davidbz/go-oidc-auth/pkg/jwt"
"github.com/davidbz/go-oidc-auth/pkg/middleware"
)
func main() {
// Setup JWT config and verifier
jwtConfig := jwt.Config{
Issuer: "https://auth.mycompany.com",
Audience: "myapp-api",
Expiry: 30 * time.Minute,
}
// Create signer and get key set
signer, _ := jwt.NewSigner(jwtConfig)
keySet, _ := signer.GetJWKS(context.Background())
verifier := jwt.NewVerifier(jwtConfig, *keySet)
// Create middleware
authMiddleware, _ := middleware.New(middleware.Config{
Verifier: verifier,
})
// Protect specific routes
mux := http.NewServeMux()
mux.Handle("/api/users", authMiddleware.Handler(usersHandler))
mux.Handle("/api/admin", authMiddleware.Handler(adminHandler))
mux.HandleFunc("/public", publicHandler) // No auth required
http.ListenAndServe(":8080", mux)
}
func usersHandler(w http.ResponseWriter, r *http.Request) {
// Extract verified claims from context
claims, ok := middleware.ClaimsFromContext(r.Context())
if !ok {
http.Error(w, "No claims", http.StatusInternalServerError)
return
}
// Access user attributes
userID := claims.Subject
email := claims.Email
name := claims.Name
provider := claims.Provider
// Access custom claims
role, _ := claims.Custom["role"].(string)
// Use claims for business logic...
}
Works with any OIDC-compliant provider:
- Microsoft Azure AD / Entra ID
- Google Identity Platform
- Okta, Auth0, Keycloak
- AWS Cognito
- Custom OIDC providers
# Run examples
go run ./examples/jwt-only # Single instance JWT operations
go run ./examples/multi-instance # Multi-instance deployment
go run ./examples/real-oidc # Production OIDC setup
# Build and test
go build ./...
go test ./...
golangci-lint run ./...
pkg/
├── auth/ # Authentication manager and orchestration
├── providers/ # OIDC provider implementations
├── jwt/ # JWT signing and verification
├── middleware/ # HTTP middleware for JWT verification
└── config/ # Configuration types
See agents.md for detailed architecture and development context.