• v1.0.0 a9c9f3434e

    Rene Nochebuena released this 2026-05-29 10:13:27 -06:00 | 0 commits to main since this release

    v1.0.0

    code.nochebuena.dev/einherjar/auth-jwt


    Architecture Decisions Resolved

    Decision Outcome
    Root factory Excluded — HMAC vs RSA vs EC is a caller choice; no universal default exists (see ADR-001)
    Logger in AuthMiddleware Added — 401 responses routed through httputil.Error for Warn-level visibility (see ADR-002)
    web dependency Accepted — auth-jwt depends on web solely for httputil.Error (see ADR-003)
    ErrTokenRevoked type Plain errors.New sentinel — idiomatic Go, works with errors.Is without Is() method (see ADR-004)
    EC algorithm selection Auto-detected from key curve — eliminates misconfiguration class (see ADR-005)

    API

    import authjwt "code.nochebuena.dev/einherjar/auth-jwt"
    
    // Package sentinel
    // Module identifies this package to observability systems.
    // auth-jwt is a function-only package — not registered with the launcher as a lifecycle component.
    // Register Module manually with any version registry if needed.
    var Module observability.Identifiable
    
    // Interfaces
    type Verifier interface {
        Verify(tokenString string) (*jwt.Token, error)
    }
    type Signer interface {
        Verifier
        Sign(claims jwt.Claims) (string, error)
    }
    type Blacklist interface {
        IsRevoked(ctx context.Context, jti string) (bool, error)
        Revoke(ctx context.Context, jti string, ttl time.Duration) error
    }
    
    // Value types
    type TokenConfig struct {
        AccessTTL  time.Duration
        RefreshTTL time.Duration
        Issuer     string
    }
    type TokenPair struct {
        AccessToken  string
        RefreshToken string
        ExpiresIn    int64
    }
    
    // Sentinel
    var ErrTokenRevoked = errors.New("token revoked")
    
    // Constructors — HMAC
    func NewHMACSigner(secret []byte) Signer
    
    // Constructors — RSA
    func NewRSASigner(privateKey *rsa.PrivateKey) Signer
    func NewRSASignerFromPEM(pemKey []byte) (Signer, error)
    func NewRSAPublicKeyVerifier(publicKey *rsa.PublicKey) Verifier
    func NewRSAPublicKeyVerifierFromPEM(pemKey []byte) (Verifier, error)
    
    // Constructors — EC (algorithm auto-detected from curve)
    func NewECSigner(privateKey *ecdsa.PrivateKey) Signer
    func NewECSignerFromPEM(pemKey []byte) (Signer, error)
    func NewECPublicKeyVerifier(publicKey *ecdsa.PublicKey) Verifier
    func NewECPublicKeyVerifierFromPEM(pemKey []byte) (Verifier, error)
    
    // Token lifecycle
    func IssueTokenPair(signer Signer, uid string, customClaims map[string]any, cfg TokenConfig) (TokenPair, error)
    func RefreshTokenPair(ctx context.Context, signer Signer, refreshToken string, bl Blacklist, cfg TokenConfig, customClaims map[string]any) (TokenPair, error)
    
    // HTTP middleware
    func AuthMiddleware(logger logging.Logger, verifier Verifier, publicPaths []string) func(http.Handler) http.Handler
    

    Wiring example

    signer := authjwt.NewHMACSigner([]byte(os.Getenv("JWT_SECRET")))
    cfg := authjwt.TokenConfig{
        AccessTTL:  15 * time.Minute,
        RefreshTTL: 7 * 24 * time.Hour,
        Issuer:     "myapp",
    }
    
    srv.Use(authjwt.AuthMiddleware(logger, signer, []string{"/health", "/auth/*"}))
    srv.Use(authmw.EnrichmentMiddleware(logger, userEnricher))
    
    pair, err := authjwt.IssueTokenPair(signer, uid, customClaims, cfg)
    newPair, err := authjwt.RefreshTokenPair(ctx, signer, body.RefreshToken, blacklist, cfg, freshClaims)
    

    Install

    go get code.nochebuena.dev/einherjar/auth-jwt@v1.0.0
    

    Dependencies

    Module Version Role
    code.nochebuena.dev/einherjar/auth v1.0.0 authmw.SetTokenData / authmw.GetClaims integration contract
    code.nochebuena.dev/einherjar/contracts v1.0.0 logging.Logger, security.*
    code.nochebuena.dev/einherjar/core v1.0.0 xerrors.Unauthorized
    code.nochebuena.dev/einherjar/web v1.0.0 httputil.Error
    github.com/golang-jwt/jwt/v5 v5.2.1 JWT signing, verification, claims
    Downloads