clerkhelper

package module
v1.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 1, 2026 License: MIT Imports: 17 Imported by: 0

README

Clerk Helper Go

A lightweight, high-performance Go package for easy Clerk authentication and authorization management in Echo-based applications.

Features

  • Unified Middleware: Simple RequireAuth middleware that supports role-based access control (RBAC).
  • Configurable Metadata: Fetch any custom fields from Clerk's public_metadata.
  • High-Performance Caching: Utilizes Ristretto for thread-safe, high-hit-ratio in-memory caching.
  • Concurrent Request Handling: Uses singleflight to prevent "thundering herd" issues.
  • Easy Context Integration: Access user metadata directly from the Echo context.
  • Customizable Cache: Configure TTL and MaxCost for your specific needs.

Installation

go get github.com/mahedikd/clerkhelper

Setup & Initialization

Before using the middleware, you must initialize the package with your desired configuration.

1. Configure and Init

Call clerkhelper.Init in your main.go. The role field is always extracted by default.

import "github.com/mahedikd/clerkhelper"
import "time"

func main() {
    // Initialize with custom settings
    clerkhelper.Init(clerkhelper.Config{
        MetadataKeys: []string{"t_id", "org_id"},
        CacheTTL:     10 * time.Minute, // Optional, default is 5 mins
        CacheLimit:   100_000,          // Optional, default is 100,000 users
    })

    // ... rest of setup
}
2. Full Initialization Example
import (
    "context"
    "time"
    clerkSDK "github.com/clerk/clerk-sdk-go/v2"
    "github.com/clerk/clerk-sdk-go/v2/jwks"
    "github.com/mahedikd/clerkhelper"
)

func main() {
    // 1. Init Helper Config
    clerkhelper.Init(clerkhelper.Config{
        MetadataKeys: []string{"t_id"},
    })

    // 2. Set Clerk Key
    clerkSDK.SetKey("your_secret_key")

    // 3. Optional: Preload JWKS for performance
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    _, _ = jwks.Get(ctx, &jwks.GetParams{})

    // 4. Recommended: Start cache cleanup
    stop := clerkhelper.StartCacheCleanup()
    defer stop()
}

Middleware Usage

Applying to Routes
import (
    "github.com/labstack/echo/v4"
    clerkhttp "github.com/clerk/clerk-sdk-go/v2/http"
    "github.com/mahedikd/clerkhelper"
)

func Register(e *echo.Echo) {
    api := e.Group("/api")

    // Mandatory: Verify Clerk session from Authorization header
    api.Use(echo.WrapMiddleware(clerkhttp.WithHeaderAuthorization()))

    // RBAC: Allow only specific roles (e.g. ADMIN)
    admin := api.Group("/admin", clerkhelper.RequireAuth([]string{"ADMIN"}))
    admin.GET("/stats", handleStats)

    // Auth only: Allow any valid session (no role check)
    api.GET("/profile", handleProfile, clerkhelper.RequireAuth(nil))
}
Accessing User Data in Handlers
func handleProfile(c echo.Context) error {
    user, ok := clerkhelper.GetUserFromContext(c)
    if !ok {
        return c.JSON(401, "unauthorized")
    }

    // Role is extracted by default
    role := user.Role

    // Custom keys are accessed via the Extra map
    tenantID := user.Extra["t_id"]

    return c.JSON(200, user)
}

Available Methods

Method Signature Description
Init Init(Config) Initializes the package with metadata keys to extract.
RequireAuth RequireAuth([]string) Echo middleware for RBAC and session verification.
GetUserFromContext GetUserFromContext(echo.Context) Retrieves ClerkUserData from the Echo context.
GetUserData GetUserData(context.Context, string) Fetches cached user data directly using a User ID.
ValidateClerkToken ValidateClerkToken(ctx, token, roles) Manual token verification and role checking.
InvalidateCache InvalidateCache(string) Evicts a user from the in-memory cache (next fetch hits Clerk API). Useful after metadata updates.
StartCacheCleanup StartCacheCleanup() Returns a function to gracefully close the cache.
VerifySvixSignature VerifySvixSignature(payload []byte, svixID, svixTimestamp, svixSignature, secret string) error Verifies a Clerk/Svix webhook request (HMAC-SHA256 over id.timestamp.payload, base64 v1, signatures, whsec_<key> secrets).

Data Structures

ClerkUserData
type ClerkUserData struct {
    UserID string            // The Clerk User ID
    Role   string            // Extracted from "role" in public_metadata
    Extra  map[string]string // Custom fields defined during Init()
}
Config
type Config struct {
    MetadataKeys []string      // List of keys to pull from public_metadata
    CacheTTL     time.Duration // Time-to-live for cached users
    CacheLimit   int64         // Maximum number of users to cache
}

License

MIT License - see the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Init

func Init(cfg Config)

func InvalidateCache added in v1.0.2

func InvalidateCache(userID string)

func RequireAuth

func RequireAuth(allowedRoles []string) echo.MiddlewareFunc

func StartCacheCleanup

func StartCacheCleanup() func()

func ValidateClerkToken

func ValidateClerkToken(ctx context.Context, token string, roles []string) bool

func VerifySvixSignature added in v1.0.3

func VerifySvixSignature(payload []byte, svixID, svixTimestamp, svixSignature, secret string) error

VerifySvixSignature verifies a Clerk webhook request using the Svix signature scheme. The secret must be in the form "<prefix>_<base64key>" (e.g. "whsec_<key>"). Signed content is "<svixID>.<svixTimestamp>.<payload>" HMAC-SHA256'd with the decoded key; any "v1,<sig>" entry in the Svix signature header that matches is accepted.

Types

type ClerkUserData

type ClerkUserData struct {
	UserID string            `json:"user_id"`
	Role   string            `json:"role"`
	Extra  map[string]string `json:"extra,omitempty"`
}

func GetUserData

func GetUserData(ctx context.Context, userID string) (*ClerkUserData, error)

func GetUserFromContext

func GetUserFromContext(c echo.Context) (*ClerkUserData, bool)

func ValidateAndGetUserData added in v1.0.1

func ValidateAndGetUserData(ctx context.Context, token string, roles []string) (*ClerkUserData, error)

type Config

type Config struct {
	MetadataKeys []string
	CacheTTL     time.Duration
	CacheLimit   int64
}

type UserCache

type UserCache struct {
	// contains filtered or unexported fields
}

func (*UserCache) GetUserData

func (uc *UserCache) GetUserData(ctx context.Context, userID string) (*ClerkUserData, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL