{"id":46049128,"url":"https://github.com/meysam81/go-auth","last_synced_at":"2026-03-01T08:34:48.011Z","repository":{"id":324353867,"uuid":"1091890169","full_name":"meysam81/go-auth","owner":"meysam81","description":"Production-ready authentication library for Go with Basic Auth, JWT, WebAuthn/Passkeys, TOTP 2FA, and OAuth2/OIDC SSO (Google, GitHub, Microsoft, and 7+ providers). Storage-agnostic, framework-agnostic, SOC2/GDPR compliant audit logging.","archived":false,"fork":false,"pushed_at":"2026-02-23T18:16:09.000Z","size":199,"stargazers_count":2,"open_issues_count":10,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-24T01:30:36.958Z","etag":null,"topics":["audit-logging","auth-library","authentication","bcrypt","compliance","golang","golang-authentication","golang-library","jwt","middleware","oauth2","oidc","passkeys","passwordless","security","session-management","sso","totp","two-factor-authentication","webauthn"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/meysam81.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":"audit/audit.go","citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"meysam81","patreon":"meysam81","buy_me_a_coffee":"meysam"}},"created_at":"2025-11-07T17:11:00.000Z","updated_at":"2025-12-09T03:32:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/meysam81/go-auth","commit_stats":null,"previous_names":["meysam81/go-auth"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/meysam81/go-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meysam81%2Fgo-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meysam81%2Fgo-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meysam81%2Fgo-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meysam81%2Fgo-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/meysam81","download_url":"https://codeload.github.com/meysam81/go-auth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/meysam81%2Fgo-auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29965406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T06:55:38.174Z","status":"ssl_error","status_checked_at":"2026-03-01T06:53:04.810Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audit-logging","auth-library","authentication","bcrypt","compliance","golang","golang-authentication","golang-library","jwt","middleware","oauth2","oidc","passkeys","passwordless","security","session-management","sso","totp","two-factor-authentication","webauthn"],"created_at":"2026-03-01T08:34:47.340Z","updated_at":"2026-03-01T08:34:47.983Z","avatar_url":"https://github.com/meysam81.png","language":"Go","funding_links":["https://github.com/sponsors/meysam81","https://patreon.com/meysam81","https://buymeacoffee.com/meysam"],"categories":[],"sub_categories":[],"readme":"# go-auth\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/meysam81/go-auth.svg)](https://pkg.go.dev/github.com/meysam81/go-auth)\n[![Go Report Card](https://goreportcard.com/badge/github.com/meysam81/go-auth)](https://goreportcard.com/report/github.com/meysam81/go-auth)\n[![codecov](https://codecov.io/github/meysam81/go-auth/graph/badge.svg?token=8WzFAwJa1Z)](https://codecov.io/github/meysam81/go-auth)\n[![Go Version](https://img.shields.io/github/go-mod/go-version/meysam81/go-auth)](https://github.com/meysam81/go-auth/blob/main/go.mod)\n[![License](https://img.shields.io/github/license/meysam81/go-auth)](https://github.com/meysam81/go-auth/blob/main/LICENSE)\n[![CI](https://github.com/meysam81/go-auth/actions/workflows/ci.yml/badge.svg)](https://github.com/meysam81/go-auth/actions/workflows/ci.yml)\n\nA comprehensive, modular, and production-ready authentication library for Go applications. Supports multiple authentication methods including Basic Auth, JWT, WebAuthn/Passkeys, and OIDC/OAuth2 SSO with 10+ popular providers.\n\n## Features\n\n- **Multiple Authentication Methods**\n  - 🔐 Basic Authentication (username/password with bcrypt)\n  - 🎫 JWT Authentication (access + refresh tokens)\n  - 🔑 WebAuthn/Passkey Authentication\n  - 🌐 OIDC/OAuth2 SSO (Single Sign-On)\n\n- **10+ SSO Providers**\n  - Google, GitHub, Microsoft, GitLab\n  - Auth0, Okta, Apple Sign In\n  - Discord, Slack, LinkedIn\n\n- **Modular Architecture**\n  - Framework-agnostic core\n  - Storage-agnostic (bring your own DB)\n  - Isolated HTTP middleware (stdlib compatible)\n  - Interface-based design for easy testing\n\n- **Production-Ready**\n  - Secure password hashing (bcrypt)\n  - Token revocation support\n  - Session management\n  - CSRF protection for OAuth flows\n  - Comprehensive audit logging (SOC2, GDPR, HIPAA compliant)\n  - Follows Google Go Style Guide\n  - Minimal dependencies\n\n## Table of Contents\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Installation](#installation)\n- [30-Second Quick Start](#30-second-quick-start)\n- [Verify Installation](#verify-installation)\n- [Quick Start](#quick-start)\n  - [Basic Authentication](#basic-authentication)\n  - [JWT Authentication](#jwt-authentication)\n  - [TOTP Two-Factor Authentication](#totp-two-factor-authentication)\n  - [OIDC/SSO Authentication](#oidcsso-authentication)\n- [Architecture](#architecture)\n  - [Storage Interfaces](#storage-interfaces)\n  - [Middleware](#middleware)\n  - [Supported Providers](#supported-providers)\n  - [Custom Providers](#custom-providers)\n- [WebAuthn/Passkeys](#webauthnpasskeys)\n- [Session Management](#session-management)\n- [Audit Logging](#audit-logging)\n  - [Basic Usage](#basic-usage)\n  - [Advanced: Custom Audit Logger](#advanced-custom-audit-logger)\n  - [Extracting Request Context](#extracting-request-context)\n  - [Audit Event Types](#audit-event-types)\n  - [PII Redaction](#pii-redaction)\n  - [Custom Audit Implementation](#custom-audit-implementation)\n  - [Compliance Features](#compliance-features)\n- [Examples](#examples)\n- [Advanced Examples](#advanced-examples)\n- [Production Deployment](#production-deployment)\n  - [Security Best Practices](#security-best-practices)\n  - [Database Integration Example](#database-integration-example)\n- [Testing](#testing)\n- [Dependencies](#dependencies)\n- [Troubleshooting](#troubleshooting)\n  - [Common Issues](#common-issues)\n  - [Getting Help](#getting-help)\n- [Contributing](#contributing)\n- [License](#license)\n- [Support](#support)\n- [Roadmap](#roadmap)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Installation\n\n```bash\ngo get github.com/meysam81/go-auth\n```\n\n## 30-Second Quick Start\n\nCopy this complete example into a file and run it:\n\n```go\n// main.go - Complete working example\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\n\t\"github.com/meysam81/go-auth/auth/basic\"\n\t\"github.com/meysam81/go-auth/middleware\"\n\t\"github.com/meysam81/go-auth/storage\"\n)\n\nfunc main() {\n\t// 1. Create storage (in-memory for demo)\n\tuserStore := storage.NewInMemoryUserStore()\n\tcredStore := storage.NewInMemoryCredentialStore()\n\n\t// 2. Create authenticator\n\tauth, err := basic.NewAuthenticator(basic.Config{\n\t\tUserStore:       userStore,\n\t\tCredentialStore: credStore,\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// 3. Register a user\n\t_, err = auth.Register(context.Background(), basic.RegisterRequest{\n\t\tEmail:    \"demo@example.com\",\n\t\tUsername: \"demo\",\n\t\tPassword: \"password123\",\n\t\tName:     \"Demo User\",\n\t})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// 4. Create middleware\n\tmw := middleware.NewBasicAuthMiddleware(middleware.BasicAuthConfig{\n\t\tAuthenticator: auth,\n\t})\n\n\t// 5. Protected endpoint\n\thttp.Handle(\"/protected\", mw.Middleware(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tuser, _ := middleware.GetUser(r)\n\t\tfmt.Fprintf(w, \"Hello, %s!\", user.Name)\n\t})))\n\n\t// 6. Start server\n\tfmt.Println(\"Server running on :8080\")\n\tfmt.Println(\"Test: curl -u demo:password123 http://localhost:8080/protected\")\n\tlog.Fatal(http.ListenAndServe(\":8080\", nil))\n}\n```\n\nRun it:\n\n```bash\ngo run main.go\n```\n\nTest it:\n\n```bash\ncurl -u demo:password123 http://localhost:8080/protected\n# Output: Hello, Demo User!\n```\n\n## Verify Installation\n\nCreate a simple test to verify go-auth is installed correctly:\n\n```go\n// verify.go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/meysam81/go-auth/storage\"\n)\n\nfunc main() {\n\tstore := storage.NewInMemoryUserStore()\n\tfmt.Printf(\"go-auth installed successfully! Store type: %T\\n\", store)\n}\n```\n\n```bash\ngo run verify.go\n# Output: go-auth installed successfully! Store type: *storage.InMemoryUserStore\n```\n\n## Quick Start\n\n### Basic Authentication\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n    \"net/http\"\n\n    \"github.com/meysam81/go-auth/auth/basic\"\n    \"github.com/meysam81/go-auth/middleware\"\n    \"github.com/meysam81/go-auth/storage\"\n)\n\nfunc main() {\n    // Initialize storage\n    userStore := storage.NewInMemoryUserStore()\n    credentialStore := storage.NewInMemoryCredentialStore()\n\n    // Create authenticator\n    auth, err := basic.NewAuthenticator(basic.Config{\n        UserStore:       userStore,\n        CredentialStore: credentialStore,\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // Register a user\n    user, err := auth.Register(context.Background(), basic.RegisterRequest{\n        Email:    \"user@example.com\",\n        Password: \"securepassword123\",\n        Name:     \"John Doe\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // Create middleware\n    authMiddleware := middleware.NewBasicAuthMiddleware(middleware.BasicAuthConfig{\n        Authenticator: auth,\n    })\n\n    // Protected route\n    http.Handle(\"/api/protected\", authMiddleware.Middleware(\n        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n            user, _ := middleware.GetUser(r)\n            w.Write([]byte(\"Hello, \" + user.Name))\n        }),\n    ))\n\n    http.ListenAndServe(\":8080\", nil)\n}\n```\n\n### JWT Authentication\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"encoding/json\"\n    \"log\"\n    \"net/http\"\n    \"time\"\n\n    \"github.com/meysam81/go-auth/auth/jwt\"\n    \"github.com/meysam81/go-auth/middleware\"\n    \"github.com/meysam81/go-auth/storage\"\n)\n\nfunc main() {\n    userStore := storage.NewInMemoryUserStore()\n    tokenStore := storage.NewInMemoryTokenStore()\n\n    // Create JWT manager\n    tokenManager, err := jwt.NewTokenManager(jwt.Config{\n        UserStore:       userStore,\n        TokenStore:      tokenStore,\n        SigningKey:      []byte(\"your-secret-key\"),\n        AccessTokenTTL:  15 * time.Minute,\n        RefreshTokenTTL: 7 * 24 * time.Hour,\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    // Login endpoint - generates tokens\n    http.HandleFunc(\"/login\", func(w http.ResponseWriter, r *http.Request) {\n        user := \u0026storage.User{\n            ID:    \"user123\",\n            Email: \"user@example.com\",\n            Name:  \"John Doe\",\n        }\n\n        tokenPair, err := tokenManager.GenerateTokenPair(r.Context(), user)\n        if err != nil {\n            http.Error(w, \"Failed to generate tokens\", http.StatusInternalServerError)\n            return\n        }\n\n        // Return tokens to client\n        w.Header().Set(\"Content-Type\", \"application/json\")\n        json.NewEncoder(w).Encode(tokenPair)\n    })\n\n    // Protected route with JWT middleware\n    authMiddleware := middleware.NewJWTMiddleware(middleware.JWTConfig{\n        TokenManager: tokenManager,\n    })\n\n    http.Handle(\"/api/protected\", authMiddleware.Middleware(\n        http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n            claims, _ := middleware.GetClaims(r)\n            w.Write([]byte(\"User ID: \" + claims.UserID))\n        }),\n    ))\n\n    http.ListenAndServe(\":8080\", nil)\n}\n```\n\n### TOTP Two-Factor Authentication\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/meysam81/go-auth/auth/totp\"\n    \"github.com/meysam81/go-auth/storage\"\n)\n\nfunc main() {\n    credentialStore := storage.NewInMemoryCredentialStore()\n\n    // Create TOTP manager\n    totpManager, err := totp.NewManager(totp.Config{\n        CredentialStore: credentialStore,\n        Issuer:          \"MyApp\",\n    })\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    ctx := context.Background()\n    userID := \"user123\"\n    accountName := \"user@example.com\"\n\n    // Generate secret for user (returns QR code URL and backup codes)\n    secret, err := totpManager.GenerateSecret(ctx, userID, accountName)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    fmt.Println(\"Scan this QR code URL with your authenticator app:\")\n    fmt.Println(secret.QRCode)\n    fmt.Println(\"\\nBackup codes (save these!):\")\n    for _, code := range secret.BackupCodes {\n        fmt.Println(\" \", code)\n    }\n\n    // Validate a code from the authenticator app\n    code := \"123456\" // User enters this from their app\n    valid, err := totpManager.Validate(ctx, userID, code)\n    if err != nil {\n        log.Fatal(err)\n    }\n\n    if valid {\n        fmt.Println(\"\\n2FA verification successful!\")\n    } else {\n        fmt.Println(\"\\nInvalid code, please try again\")\n    }\n\n    // Check if TOTP is enabled for a user\n    enabled, _ := totpManager.IsEnabled(ctx, userID)\n    fmt.Printf(\"TOTP enabled: %v\\n\", enabled)\n}\n```\n\n### OIDC/SSO Authentication\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n    \"net/http\"\n\n    authoidc \"github.com/meysam81/go-auth/auth/oidc\"\n    \"github.com/meysam81/go-auth/provider\"\n    \"github.com/meysam81/go-auth/storage\"\n)\n\nfunc main() {\n    ctx := context.Background()\n    userStore := storage.NewInMemoryUserStore()\n    stateStore := storage.NewInMemoryOIDCStateStore()\n\n    // Create providers\n    googleProvider, _ := provider.NewGoogleProvider(\n        ctx,\n        \"your-google-client-id\",\n        \"your-google-client-secret\",\n        \"http://localhost:8080/callback/google\",\n    )\n\n    githubProvider := provider.NewGitHubProvider(\n        \"your-github-client-id\",\n        \"your-github-client-secret\",\n        \"http://localhost:8080/callback/github\",\n    )\n\n    // Create OIDC client\n    oidcClient, _ := authoidc.NewClient(authoidc.Config{\n        Providers:  []authoidc.Provider{googleProvider, githubProvider},\n        UserStore:  userStore,\n        StateStore: stateStore,\n    })\n\n    // Login - redirects to provider\n    http.HandleFunc(\"/login/google\", func(w http.ResponseWriter, r *http.Request) {\n        authURL, _ := oidcClient.GetAuthorizationURL(r.Context(), authoidc.AuthURLOptions{\n            Provider: \"google\",\n        })\n        http.Redirect(w, r, authURL, http.StatusTemporaryRedirect)\n    })\n\n    // Callback - handles OAuth response\n    http.HandleFunc(\"/callback/google\", func(w http.ResponseWriter, r *http.Request) {\n        state := r.URL.Query().Get(\"state\")\n        code := r.URL.Query().Get(\"code\")\n\n        result, err := oidcClient.HandleCallback(r.Context(), state, code)\n        if err != nil {\n            http.Error(w, \"Authentication failed\", http.StatusUnauthorized)\n            return\n        }\n\n        // User is authenticated - create session or JWT\n        w.Write([]byte(\"Welcome, \" + result.User.Name))\n    })\n\n    http.ListenAndServe(\":8080\", nil)\n}\n```\n\n## Architecture\n\n### Storage Interfaces\n\nThe library is storage-agnostic. You implement the storage interfaces with your preferred database:\n\n```go\ntype UserStore interface {\n    CreateUser(ctx context.Context, user *User) error\n    GetUserByID(ctx context.Context, id string) (*User, error)\n    GetUserByEmail(ctx context.Context, email string) (*User, error)\n    UpdateUser(ctx context.Context, user *User) error\n    DeleteUser(ctx context.Context, id string) error\n}\n\ntype CredentialStore interface {\n    StorePasswordHash(ctx context.Context, userID string, hash []byte) error\n    GetPasswordHash(ctx context.Context, userID string) ([]byte, error)\n    StoreWebAuthnCredential(ctx context.Context, userID string, credential *WebAuthnCredential) error\n    GetWebAuthnCredentials(ctx context.Context, userID string) ([]*WebAuthnCredential, error)\n    // ...\n}\n\ntype SessionStore interface {\n    CreateSession(ctx context.Context, sessionID string, data *SessionData, ttl time.Duration) error\n    GetSession(ctx context.Context, sessionID string) (*SessionData, error)\n    DeleteSession(ctx context.Context, sessionID string) error\n    // ...\n}\n```\n\nIn-memory implementations are provided for development/testing:\n\n- `storage.NewInMemoryUserStore()`\n- `storage.NewInMemoryCredentialStore()`\n- `storage.NewInMemorySessionStore()`\n- `storage.NewInMemoryTokenStore()`\n- `storage.NewInMemoryOIDCStateStore()`\n\n### Middleware\n\nHTTP middleware is isolated in the `middleware` package and works with any framework that uses `http.Handler`:\n\n```go\n// Token extraction\nextractor := \u0026middleware.HeaderExtractor{\n    HeaderName: \"Authorization\",\n    Scheme:     \"Bearer\",\n}\n\n// Or use cookies\nextractor := \u0026middleware.CookieExtractor{\n    CookieName: \"session_id\",\n}\n\n// Or try multiple sources\nextractor := \u0026middleware.MultiExtractor{\n    Extractors: []middleware.SessionTokenExtractor{\n        \u0026middleware.CookieExtractor{CookieName: \"session\"},\n        \u0026middleware.HeaderExtractor{HeaderName: \"Authorization\", Scheme: \"Bearer\"},\n    },\n}\n```\n\n### Supported Providers\n\n| Provider  | Type   | Constructor                       |\n| --------- | ------ | --------------------------------- |\n| Google    | OIDC   | `provider.NewGoogleProvider()`    |\n| Microsoft | OIDC   | `provider.NewMicrosoftProvider()` |\n| GitLab    | OIDC   | `provider.NewGitLabProvider()`    |\n| Auth0     | OIDC   | `provider.NewAuth0Provider()`     |\n| Okta      | OIDC   | `provider.NewOktaProvider()`      |\n| Apple     | OIDC   | `provider.NewAppleProvider()`     |\n| LinkedIn  | OAuth2 | `provider.NewLinkedInProvider()`  |\n| GitHub    | OAuth2 | `provider.NewGitHubProvider()`    |\n| Discord   | OAuth2 | `provider.NewDiscordProvider()`   |\n| Slack     | OAuth2 | `provider.NewSlackProvider()`     |\n\n### Custom Providers\n\nImplement the `Provider` interface to add custom providers:\n\n```go\ntype Provider interface {\n    Name() string\n    GetOAuth2Config() *oauth2.Config\n    GetOIDCProvider() *oidc.Provider\n    ExtractUserInfo(ctx context.Context, token *oauth2.Token) (*UserInfo, error)\n}\n```\n\n## WebAuthn/Passkeys\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n\n    \"github.com/meysam81/go-auth/auth/webauthn\"\n    \"github.com/meysam81/go-auth/storage\"\n)\n\nfunc main() {\n    userStore := storage.NewInMemoryUserStore()\n    credentialStore := storage.NewInMemoryCredentialStore()\n    sessionStore := storage.NewInMemoryOIDCStateStore() // For challenge storage\n\n    auth, err := webauthn.NewAuthenticator(webauthn.Config{\n        RPDisplayName: \"My App\",\n        RPID:          \"example.com\",\n        RPOrigins:     []string{\"https://example.com\"},\n        UserStore:     userStore,\n        CredentialStore: credentialStore,\n        SessionStore:    sessionStore,\n    })\n\n    // Registration flow\n    options, sessionID, err := auth.BeginRegistration(context.Background(), \"user123\")\n    // Send options to client for navigator.credentials.create()\n\n    // After client response\n    credential, err := auth.FinishRegistration(context.Background(), sessionID, response)\n\n    // Authentication flow\n    options, sessionID, err := auth.BeginLogin(context.Background(), \"user123\")\n    // Send options to client for navigator.credentials.get()\n\n    // After client response\n    user, err := auth.FinishLogin(context.Background(), sessionID, response)\n}\n```\n\n## Session Management\n\n```go\npackage main\n\nimport (\n    \"time\"\n\n    \"github.com/meysam81/go-auth/session\"\n    \"github.com/meysam81/go-auth/storage\"\n)\n\nfunc main() {\n    sessionStore := storage.NewInMemorySessionStore()\n\n    sessionManager, _ := session.NewManager(session.Config{\n        Store:      sessionStore,\n        SessionTTL: 24 * time.Hour,\n    })\n\n    // Create session\n    sess, _ := sessionManager.Create(context.Background(), session.CreateSessionRequest{\n        UserID:   \"user123\",\n        Email:    \"user@example.com\",\n        Provider: \"google\",\n    })\n\n    // Validate session\n    sessionData, _ := sessionManager.Validate(context.Background(), sess.ID)\n\n    // Refresh session\n    sessionManager.Refresh(context.Background(), sess.ID)\n\n    // Delete session (logout)\n    sessionManager.Delete(context.Background(), sess.ID)\n}\n```\n\n## Audit Logging\n\nThe library provides comprehensive audit logging for compliance with modern security standards (SOC2, GDPR, HIPAA, PCI-DSS). By default, audit logging is disabled (no-op) for zero overhead.\n\n### Basic Usage\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"os\"\n\n    \"github.com/meysam81/go-auth/audit\"\n    \"github.com/meysam81/go-auth/auth/basic\"\n    \"github.com/meysam81/go-auth/storage\"\n)\n\nfunc main() {\n    // Create an audit logger\n    auditor := audit.DefaultStdLogger()\n    // Or for production with PII redaction:\n    // auditor := audit.ProductionStdLogger()\n\n    // Create authenticator\n    userStore := storage.NewInMemoryUserStore()\n    credStore := storage.NewInMemoryCredentialStore()\n\n    auth, _ := basic.NewAuthenticator(basic.Config{\n        UserStore:       userStore,\n        CredentialStore: credStore,\n    })\n\n    // Wrap with audit logging\n    auditedAuth := audit.NewBasicAuthWrapper(auth, auditor, nil)\n\n    // Now all authentication operations are logged\n    user, err := auditedAuth.Register(context.Background(), basic.RegisterRequest{\n        Email:    \"user@example.com\",\n        Password: \"password123\",\n    })\n    // Logs: {\"timestamp\":\"2025-11-15T12:00:00Z\",\"event_type\":\"auth.register\",\"event_result\":\"success\",...}\n\n    user, err = auditedAuth.Authenticate(context.Background(), \"user@example.com\", \"password123\")\n    // Logs: {\"timestamp\":\"2025-11-15T12:00:01Z\",\"event_type\":\"auth.login\",\"event_result\":\"success\",...}\n}\n```\n\n### Advanced: Custom Audit Logger\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"log\"\n    \"os\"\n\n    \"github.com/meysam81/go-auth/audit\"\n)\n\nfunc main() {\n    // Create a custom logger with specific configuration\n    auditor := audit.NewStdLogger(audit.StdLoggerConfig{\n        Output: os.Stdout, // or a file, syslog, etc.\n        RedactionConfig: \u0026audit.RedactionConfig{\n            RedactEmail:     true,\n            RedactUsername:  true,\n            RedactIPAddress: true,\n            MetadataRedactionKeys: []string{\"password\", \"secret\"},\n        },\n    })\n\n    // Use the auditor with wrappers\n    // ... (wrap your auth components)\n}\n```\n\n### Extracting Request Context\n\nFor web applications, you can extract client IP, user agent, and other request metadata:\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"net/http\"\n\n    \"github.com/meysam81/go-auth/audit\"\n    \"github.com/meysam81/go-auth/auth/basic\"\n)\n\n// SourceExtractor extracts audit context from HTTP request\nfunc sourceExtractorFromRequest(r *http.Request) audit.SourceExtractor {\n    return func(ctx context.Context) *audit.Source {\n        return \u0026audit.Source{\n            IPAddress: r.RemoteAddr,\n            UserAgent: r.UserAgent(),\n            RequestID: r.Header.Get(\"X-Request-ID\"),\n        }\n    }\n}\n\nfunc loginHandler(w http.ResponseWriter, r *http.Request) {\n    auditor := audit.ProductionStdLogger()\n    auth := getAuthenticator() // your authenticator\n\n    // Create wrapper with source extractor\n    auditedAuth := audit.NewBasicAuthWrapper(\n        auth,\n        auditor,\n        sourceExtractorFromRequest(r),\n    )\n\n    user, err := auditedAuth.Authenticate(\n        r.Context(),\n        r.FormValue(\"email\"),\n        r.FormValue(\"password\"),\n    )\n    // Logs include IP address, user agent, and request ID\n}\n```\n\n### Audit Event Types\n\nThe library logs the following security events:\n\n**Authentication Events:**\n\n- `auth.login` - User login attempts\n- `auth.logout` - User logout\n- `auth.register` - New user registration\n- `auth.password_change` - Password changes\n- `auth.password_reset` - Password resets\n\n**Token Events:**\n\n- `token.generate` - Token generation\n- `token.validate` - Token validation\n- `token.refresh` - Token refresh\n- `token.revoke` - Token revocation\n\n**Session Events:**\n\n- `session.create` - Session creation\n- `session.validate` - Session validation\n- `session.refresh` - Session refresh\n- `session.delete` - Session deletion (logout)\n\n**User Management Events:**\n\n- `user.create`, `user.read`, `user.update`, `user.delete`\n\n### PII Redaction\n\nFor compliance with privacy regulations (GDPR, CCPA), enable PII redaction:\n\n```go\nconfig := \u0026audit.RedactionConfig{\n    RedactEmail:     true,  // user@example.com -\u003e u***@example.com\n    RedactUsername:  true,  // username -\u003e u***e\n    RedactIPAddress: true,  // 192.168.1.1 -\u003e 192.168.*.*\n    MetadataRedactionKeys: []string{\"ssn\", \"phone\", \"address\"},\n}\n\nauditor := audit.NewStdLogger(audit.StdLoggerConfig{\n    RedactionConfig: config,\n})\n```\n\n### Custom Audit Implementation\n\nImplement the `AuditLogger` interface to integrate with your logging system:\n\n```go\ntype CustomAuditor struct {\n    // your logging backend (e.g., Elasticsearch, Splunk, DataDog)\n}\n\nfunc (c *CustomAuditor) Log(ctx context.Context, event *audit.AuditEvent) error {\n    // Send event to your logging backend\n    return c.backend.Send(event)\n}\n\n// Use with wrappers\nauditor := \u0026CustomAuditor{backend: myBackend}\nauditedAuth := audit.NewBasicAuthWrapper(auth, auditor, nil)\n```\n\n### Compliance Features\n\nThe audit logging implementation follows industry best practices:\n\n- **Tamper-proof**: Logs are append-only\n- **Structured**: JSON format for machine parsing\n- **Timestamped**: UTC timestamps in RFC3339 format\n- **Contextual**: Includes actor, resource, source, and result\n- **Privacy-aware**: Built-in PII redaction\n- **Traceable**: Supports trace IDs for distributed tracing\n- **Non-blocking**: Logging failures don't prevent operations\n\n## Examples\n\nSee the `examples/` directory for complete working examples:\n\n- `examples/basic/` - Basic authentication example\n- `examples/jwt/` - JWT authentication example\n- `examples/oidc/` - OIDC/SSO authentication example\n- `examples/complete/` - Full-featured example with all auth methods\n\nRun an example:\n\n```bash\ncd examples/basic\ngo run main.go\n```\n\n## Advanced Examples\n\nFor production-ready patterns and comprehensive implementations, see the **complete example** at [`examples/complete/`](./examples/complete/).\n\nThis standalone example includes:\n\n- **All authentication methods**: Basic auth, JWT, TOTP 2FA, WebAuthn/Passkeys, Google SSO\n- **PostgreSQL integration**: Complete storage implementations with SQL schema\n- **Password reset flow**: Token-based password recovery\n- **Session management**: Secure session handling\n- **Audit logging**: Using stdlib `log/slog` for compliance logging\n- **Full HTTP API**: RESTful endpoints for all operations\n\nThe example is completely self-contained with its own `go.mod` and can be run immediately:\n\n```bash\ncd examples/complete\ngo run main.go\n```\n\nSee [`examples/complete/README.md`](./examples/complete/README.md) for detailed setup instructions and API documentation.\n\n## Production Deployment\n\n### Security Best Practices\n\n1. **Use strong signing keys**\n\n   ```go\n   // Generate a secure random key\n   signingKey := make([]byte, 32)\n   rand.Read(signingKey)\n   ```\n\n2. **Use HTTPS in production**\n   - Set `Secure: true` on cookies\n   - Configure proper CORS policies\n\n3. **Store secrets in environment variables**\n\n   ```go\n   signingKey := []byte(os.Getenv(\"JWT_SIGNING_KEY\"))\n   ```\n\n4. **Implement rate limiting**\n   - Limit login attempts\n   - Use exponential backoff\n\n5. **Use persistent storage**\n   - Implement storage interfaces with PostgreSQL, MySQL, etc.\n   - Use Redis for sessions and ephemeral data\n\n### Database Integration Example\n\n```go\n// PostgreSQL implementation example\ntype PostgresUserStore struct {\n    db *sql.DB\n}\n\nfunc (s *PostgresUserStore) CreateUser(ctx context.Context, user *storage.User) error {\n    _, err := s.db.ExecContext(ctx,\n        \"INSERT INTO users (id, email, username, name, provider, created_at, updated_at) VALUES ($1, $2, $3, $4, $5, $6, $7)\",\n        user.ID, user.Email, user.Username, user.Name, user.Provider, user.CreatedAt, user.UpdatedAt,\n    )\n    return err\n}\n\nfunc (s *PostgresUserStore) GetUserByEmail(ctx context.Context, email string) (*storage.User, error) {\n    user := \u0026storage.User{}\n    err := s.db.QueryRowContext(ctx,\n        \"SELECT id, email, username, name, provider, created_at, updated_at FROM users WHERE email = $1\",\n        email,\n    ).Scan(\u0026user.ID, \u0026user.Email, \u0026user.Username, \u0026user.Name, \u0026user.Provider, \u0026user.CreatedAt, \u0026user.UpdatedAt)\n\n    if err == sql.ErrNoRows {\n        return nil, storage.ErrNotFound\n    }\n    return user, err\n}\n\n// Implement remaining methods...\n```\n\n## Testing\n\nThe library is designed for easy testing with interface-based architecture:\n\n```go\n// Mock storage for testing\ntype MockUserStore struct {\n    users map[string]*storage.User\n}\n\nfunc (m *MockUserStore) GetUserByID(ctx context.Context, id string) (*storage.User, error) {\n    user, ok := m.users[id]\n    if !ok {\n        return nil, storage.ErrNotFound\n    }\n    return user, nil\n}\n\n// Use in tests\nfunc TestAuthentication(t *testing.T) {\n    mockStore := \u0026MockUserStore{\n        users: map[string]*storage.User{\n            \"user123\": {ID: \"user123\", Email: \"test@example.com\"},\n        },\n    }\n\n    auth, _ := basic.NewAuthenticator(basic.Config{\n        UserStore: mockStore,\n        // ...\n    })\n\n    // Test authentication\n}\n```\n\n## Dependencies\n\n- `golang.org/x/crypto` - Password hashing (bcrypt)\n- `github.com/golang-jwt/jwt/v5` - JWT implementation\n- `github.com/go-webauthn/webauthn` - WebAuthn/FIDO2\n- `github.com/coreos/go-oidc/v3` - OIDC client\n- `golang.org/x/oauth2` - OAuth2 flows\n\nAll dependencies are production-ready, well-maintained, and widely used.\n\n## Troubleshooting\n\n### Common Issues\n\n**\"cannot find module\" error**\n\n```bash\n# Ensure you're using Go 1.21+ and modules are enabled\ngo version\ngo env GO111MODULE\n# Should be \"on\" or empty (auto)\n\n# Try cleaning module cache\ngo clean -modcache\ngo get github.com/meysam81/go-auth\n```\n\n**\"storage.ErrNotFound\" when authenticating**\n\nThis means the user doesn't exist. Ensure you've registered the user first:\n\n```go\n// Register before authenticating\n_, err := auth.Register(ctx, basic.RegisterRequest{\n    Email:    \"user@example.com\",\n    Password: \"password\",\n})\n```\n\n**JWT token validation fails**\n\n- Ensure the signing key is the same for generation and validation\n- Check that the token hasn't expired (default: 15 minutes for access tokens)\n- Verify the token is being passed correctly in the `Authorization: Bearer \u003ctoken\u003e` header\n\n**TOTP codes always invalid**\n\n- Ensure server time is synchronized (TOTP is time-based)\n- Check that the secret was stored correctly during setup\n- Verify the user is using a compatible authenticator app (Google Authenticator, Authy, etc.)\n\n**WebAuthn registration fails**\n\n- WebAuthn requires HTTPS in production (localhost works for development)\n- Ensure `RPID` matches your domain exactly\n- Check that `RPOrigins` includes the full origin URL (e.g., `https://example.com`)\n\n### Getting Help\n\nIf you encounter issues not covered here:\n\n1. Check the [GitHub Issues](https://github.com/meysam81/go-auth/issues) for similar problems\n2. Review the examples in `examples/` directory\n3. Use `go doc` to explore package documentation\n\n## Contributing\n\nContributions are welcome! Please follow these guidelines:\n\n1. Follow the Google Go Style Guide\n2. Write tests for new features\n3. Update documentation\n4. Keep dependencies minimal\n\n## License\n\nApache 2.0 License - see LICENSE file for details\n\n## Support\n\n- GitHub Issues: [Report bugs or request features](https://github.com/meysam81/go-auth/issues)\n- Documentation: See package documentation with `go doc`\n\n## Roadmap\n\n- [ ] Support for SAML (if requested)\n- [ ] Built-in OIDC Provider/Server (nice to have)\n- [ ] Additional SSO providers\n- [ ] Rate limiting middleware\n- [x] Audit logging interface ✅\n- [x] Password reset flow helpers ✅\n- [x] Email verification flow helpers ✅\n- [x] Two-factor authentication (TOTP) ✅\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeysam81%2Fgo-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmeysam81%2Fgo-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmeysam81%2Fgo-auth/lists"}