Skip to content

crydensync/cryden

CrydenSync 🔐

Embeddable authentication engine for Go — offline-first, framework-agnostic.

Go Reference Go Report Card License: MIT

GitHub Stars GitHub Forks GitHub Watchers GitHub Downloads

## 🎯 The Problem

Authentication is not business logic, yet every project rewrites it. Developers face three painful choices:

  1. Rewrite auth logic for every project — risky, inconsistent, time-consuming
  2. Use hosted auth services — vendor lock-in, users aren't yours, requires internet
  3. Use framework-specific tools — tied to Express, Django, Next.js — not reusable

💡 The Solution

CrydenSync is an embeddable authentication engine that gives you a standard, reusable auth system you control:

package main import ( "context" "fmt" "log" "github.com/crydensync/cryden" ) func main() { // Create context ctx := context.Background() // 1. Create engine (in-memory storage - perfect for testing) engine := cryden.New() fmt.Println("✅ Engine created") // 2. Sign up a new user email := "alice@example.com" password := "SecurePass123" user, err := cryden.SignUp(ctx, engine, email, password) if err != nil { log.Fatalf("❌ SignUp failed: %v", err) } fmt.Printf("✅ User created: %s (%s)\n", user.ID, user.Email) // 3. Login tokens, rateLimit, err := cryden.Login(ctx, engine, email, password) if err != nil { log.Fatalf("❌ Login failed: %v", err) } fmt.Printf("✅ Login successful!\n") fmt.Printf(" Access Token: %s...\n", tokens.AccessToken[:50]) fmt.Printf(" Refresh Token: %s...\n", tokens.RefreshToken[:50]) fmt.Printf(" Rate Limit Remaining: %d\n", rateLimit.Remaining) // 4. Verify token userID, err := cryden.VerifyToken(engine, tokens.AccessToken) if err != nil { log.Fatalf("❌ Token verification failed: %v", err) } fmt.Printf("✅ Token verified for user: %s\n", userID) // 5. Logout err = cryden.Logout(ctx, engine, tokens.RefreshToken) if err != nil { log.Fatalf("❌ Logout failed: %v", err) } fmt.Println("✅ Logout successful") // 6. Try to use logged out token (should fail) _, err = cryden.RefreshToken(ctx, engine, tokens.RefreshToken) if err != nil { fmt.Printf("✅ Expected error after logout: %v\n", err) } fmt.Println("\n🎉 All tests passed!") } 

View full example →

✨ Features

✅ v1.0.0 (Current)

· Email/password authentication — Secure, bcrypt hashed · JWT access tokens — Short-lived, stateless · Opaque refresh tokens — Stored in DB for revocation · Rate limiting — Per IP with headers (X-RateLimit-*) · Audit logging — Track every auth event · Session management — Logout single device or all devices · Multiple storage backends — Memory, SQLite, PostgreSQL, MongoDB · Complete test suite — 90%+ coverage · Offline-first — Works without internet, SQLite by default

🚧 Coming Soon

Feature Status Target gRPC API 🚧 Planned v1.1.0 CLI tool (csax) 🚧 Planned v1.1.0 Language SDKs (JS, Python, PHP) 🚧 Planned v1.2.0 MFA/2FA (TOTP) 📅 Future v1.3.0 Magic Links 📅 Future v1.3.0 WebAuthn/Passkeys 📅 Future v2.0.0

📦 Installation

go get github.com/crydensync/cryden@v1.0.0
## 🧪 Local Development Want to hack on CrydenSync itself? Use it locally in your own app: ```bash git clone https://github.com/crydensync/cryden.git cd your-app go mod edit -replace github.com/crydensync/cryden=../cryden go run main.go # Uses your local version!

📚 Full Local Dev Guide → (CrydenSync web docs soon)

📖 Documentation

Section Description 📚 Getting Started 60-second working auth 🎯 Philosophy Why Cryden exists 🏗️ Architecture How it works 📐 Design Decisions Why we built it this way 🔧 Guide Installation, config, middleware, testing 🔌 Adapters Interface implementations 📘 API Reference Complete API docs 💡 Examples Copy-paste working code

🧪 Testing

CrydenSync is designed for maximum testability:

func TestLogin(t *testing.T) { engine := cryden.New() // In-memory storage // Optional: Use mock hasher for faster tests engine.WithHasher(&core.MockHasher{}) // Optional: Disable rate limiting engine.WithRateLimiter(&core.NoopRateLimiter{}) ctx := context.Background() cryden.SignUp(ctx, engine, "test@example.com", "pass") tokens, _, err := cryden.Login(ctx, engine, "test@example.com", "pass") assert.NoError(t, err) assert.NotEmpty(t, tokens.AccessToken) }

📖 Testing Guide →

🔧 Configuration

// With SQLite persistence engine, err := cryden.WithSQLite("users.db") // With custom JWT secret (required in production) cryden.WithJWTSecret(engine, os.Getenv("JWT_SECRET")) // With custom rate limiter engine.WithRateLimiter(redis.NewRateLimiter()) // With custom audit logger engine.WithAuditLogger(file.NewAuditLogger("auth.log"))

📊 Storage Backends

Backend Status Use Case Memory ✅ Stable Testing SQLite ✅ Stable Offline-first, development PostgreSQL ✅ Stable Production MongoDB ✅ Stable Document stores MySQL 🚧 Planned v1.1.0 Redis 🚧 Planned v1.1.0 (rate limiting)

📛 About the Name

CrydenSync is the full name of the project, but the Go package is simply cryden for brevity.

import "github.com/crydensync/cryden" // Notice: crydensync/cryden auth := cryden.New() // Short and sweet!

✅ Perfect! Let's add a "How It Works" section to your README.md

Add this after Features:

## 🔧 How CrydenSync Works (Under the Hood) ### The Authentication Flow When a user logs in, here's what happens: ```mermaid sequenceDiagram  participant App as Your App  participant Engine as Cryden Engine  participant Hasher as Password Hasher  participant Store as Database Store  participant Logger as Audit Logger  participant Limiter as Rate Limiter   App->>Engine: Login(email, password)  Engine->>Limiter: Check rate limit  Limiter-->>Engine: ✅ Allowed (remaining: 4)    Engine->>Store: GetUserByEmail(email)  Store-->>Engine: User (with hashed password)    Engine->>Hasher: Compare(password, hash)  Hasher-->>Engine: ✅ Match    Engine->>Store: CreateSession(userID)  Store-->>Engine: Session (with refresh token)    Engine->>Engine: Generate JWT access token    Engine->>Logger: Log successful login    Engine-->>App: TokenPair + RateLimit info

The Dual-Token System

┌─────────────────────────────────────────────────────┐ │ CLIENT SIDE │ ├─────────────────────────────────────────────────────┤ │ Access Token (JWT) │ Refresh Token (Opaque) │ │ • Short-lived (15m) │ • Long-lived (7d) │ │ • Stateless │ • Stored in database │ │ • Contains user ID │ • Can be revoked │ │ • No DB lookup │ • Supports "logout all" │ └─────────────────────────────────────────────────────┘ 

Why This Design?

JWT for Speed

// API can verify without database lookup claims, _ := cryden.VerifyToken(token) userID := claims.UserID // Fast!

Opaque Tokens for Control

// Logout all devices = delete all refresh tokens cryden.LogoutAll(ctx, engine, userID) // Instant revocation

The Interface Architecture

┌─────────────────────────────────────────────────────┐ │ YOUR APPLICATION │ ├─────────────────────────────────────────────────────┤ │ cryden.New() │ ├─────────────────────────────────────────────────────┤ │ ┌─────────────────────────────────────────────────┐ │ │ CRYDEN ENGINE │ │ │ • SignUp, Login, Logout │ │ │ • Token generation & validation │ │ │ • Session management │ │ └─────────────────────────────────────────────────┘ ├─────────────────────────────────────────────────────┤ │ INTERFACES │ ├──────────────┬──────────────┬──────────────────────┤ │ UserStore │ SessionStore │ Hasher │ │ • Create │ • Create │ • Compare │ │ • GetByEmail│ • GetByToken │ • Hash │ │ • Update │ • Revoke │ │ │ • Delete │ • RevokeAll │ │ ├──────────────┼──────────────┼──────────────────────┤ │ RateLimiter │ AuditLogger │ (More adapters...) │ │ • Allow │ • Log │ │ │ • Reset │ │ │ └──────────────┴──────────────┴──────────────────────┘ 

Storage Adapters in Action

// Same code works with ANY database! type UserStore interface { GetByEmail(email string) (*User, error) Create(user *User) error // ... } // Memory adapter (testing) type MemoryUserStore struct { users map[string]*User } // SQLite adapter (offline) type SQLiteUserStore struct { db *sql.DB } // PostgreSQL adapter (production) type PostgresUserStore struct { db *sql.DB } // MongoDB adapter (NoSQL) type MongoUserStore struct { coll *mongo.Collection }

The Audit Trail

Every action is logged for security:

{ "timestamp": "2026-03-10T10:30:00Z", "user_id": "usr_123", "action": "SIGN_IN_SUCCESS", "ip_address": "192.168.1.100", "user_agent": "Mozilla/5.0...", // comming soon "status": "SUCCESS" }

Rate Limiting with Headers

HTTP/1.1 200 OK X-RateLimit-Limit: 5 X-RateLimit-Remaining: 3 X-RateLimit-Reset: 45

Frontend can show: "3 attempts remaining. Try again in 45 seconds."

Session Management

**Planed for v1.1.0

┌─────────────────────────────────────────────────────┐ │ USER SESSIONS │ ├─────────────────────────────────────────────────────┤ │ Device: iPhone 15 │ │ Location: Lagos, Nigeria │ │ Last active: 2 minutes ago │ │ Status: ● Active │ ├─────────────────────────────────────────────────────┤ │ Device: MacBook Pro │ │ Location: Lagos, Nigeria │ │ Last active: 2 hours ago │ │ Status: ● Active │ └─────────────────────────────────────────────────────┘ [Logout All Devices] 

Security Layers

┌─────────────────────────────────────────────────────┐ │ SECURITY LAYERS │ ├─────────────────────────────────────────────────────┤ │ Layer 1: Rate Limiting │ │ → Prevents brute force attacks │ │ → 5 attempts per minute per IP │ ├─────────────────────────────────────────────────────┤ │ Layer 2: Password Hashing │ │ → bcrypt with salt │ │ → Argon2id coming in v1.1 │ ├─────────────────────────────────────────────────────┤ │ Layer 3: JWT Signing │ │ → HMAC-SHA256 with secret │ │ → Short expiration (15m) │ ├─────────────────────────────────────────────────────┤ │ Layer 4: Refresh Token Rotation │ │ → New token on every refresh │ │ → Old tokens revoked immediately │ ├─────────────────────────────────────────────────────┤ │ Layer 5: Audit Logging │ │ → Every action tracked │ │ → Suspicious activity detection (future) │ └─────────────────────────────────────────────────────┘ 

The Complete Request Lifecycle

1. Request arrives ↓ 2. Rate Limiter checks IP ↓ 3. User credentials validated ↓ 4. Password compared (constant time) ↓ 5. Session created in database ↓ 6. JWT access token generated ↓ 7. Audit log entry created ↓ 8. Response with tokens + rate limit headers ↓ 9. Frontend stores tokens securely 

Why This Matters for Your Users

// Your users get: // ✅ Security (bcrypt, rate limiting) // ✅ Control (logout all devices) // ✅ Visibility (audit logs, session list) // ✅ Flexibility (any database) // ✅ Freedom (no vendor lock-in)

🎯 The Bottom Line

CrydenSync isn't just an auth library — it's a complete authentication infrastructure that you control completely.

  • You own the data
  • You choose the database
  • You control the security
  • You keep your users

No vendor lock-in. No hidden costs. Just auth that works everywhere.

🔒 Security Notes v1.0.0

✅ Implemented

  • Password hashing with bcrypt
  • JWT signing with HMAC-SHA256
  • Rate limiting to prevent brute force
  • Audit logging for all auth events

⚠️ Planned for v1.1.0

  • Refresh token hashing in database
  • Session token hashing
  • Device fingerprinting
  • Argon2id hasher option

Future Security Enhancements

  • Email verification (v1.1)
  • Password reset flow (v1.1)
  • MFA/2FA (v1.2)
  • Login notifications (v1.2)
  • Breached password detection (v1.2)

🔐 Best Practices

  1. Always use HTTPS in production
  2. Set strong JWT secrets via environment variables
  3. Monitor audit logs for suspicious activity
  4. Add email verification before sensitive actions

🤝 Contributing

We welcome contributions! See CONTRIBUTING.md for:

· Code of Conduct · Development setup · Pull request process · Coding standards

📄 License

MIT © Crydensync

⭐ Support

If you find Cryden useful, please star the repo!

📊 Project Stats

Metric Value
⭐ Stars Stars
🍴 Forks Forks
👀 Watchers Watchers
📥 Downloads Downloads
🏷️ Version Version
✅ Build Build
📚 Docs Go Reference
📦 Go Version Go Version
📄 License License: MIT

🗺️ Roadmap

Current: v1.0.0 (March 2026)

✅ Core authentication with email/password. ✅ JWT + refresh tokens. ✅ Rate limiting & audit logs. ✅ Multiple databases (SQLite, PostgreSQL, MongoDB)

Coming in v1.1.0 (Q2 2026)

🚀 CLI tool (csax) 📱 Device tracking (IP, user agent, last seen) 🔐 Argon2id hasher ⚡ Redis rate limiter le audit logger 🐬 MySQL support

Coming in v1.2.0 (Q3 2026)

🔌 gRPC API 🌐 Language SDKs (JS, Python, PHP) 🔔 Webhooks 🔄 Migration tools (Clerk, Auth0, Supabase)

Coming in v1.3.0 (Q4 2026)

🔐 Multi-Factor Authentication (TOTP) 📧 Magic links & passwordless 🔑 WebAuthn / Passkeys 🌍 Social login (OAuth2)

Future (2027+)

☁️ Optional cloud sync 📊 Enterprise features 🔌 More adapters 🚀 v2.0.0 (breaking changes if needed)

View full roadmap →


Built with ❤️ in Africa · Own your users, not vendor lock-in

Packages

 
 
 

Contributors

Languages