What Kotauth actually ships
Every feature listed here is in production today. No beta labels, no roadmap promises — this is the current v1.10.0 release, built on Ktor 3.4, Kotlin 2.3, and Gradle 9.
Auth screens that don't look like auth screens
Production-ready login, registration, MFA, and account management pages — beautiful by default, fully white-labeled per tenant, zero rebuild required.
Server-rendered, zero JS overhead
Auth pages are pure server-rendered HTML. No client-side framework, no hydration delay — first meaningful paint in under 100ms.
White-label per workspace
CSS custom properties injected at render time. Each tenant gets its own colors, logo, and favicon with zero rebuild or CDN invalidation.
Complete screen set
Login, register, forgot password, reset password, accept invite, TOTP MFA, and email verification — all styled and production-ready.
Three presets, full customization
Start with Dark, Light, or Simple. Override any design token to match your brand without touching backend code.
Sign in
to continue to your workspace
No account? Sign up
Click the theme tabs to preview — same URL, different tenant config
OAuth 2.0 & OpenID Connect
Authorization Code + PKCE (required for all public clients), Client Credentials for machine-to-machine, Refresh Token rotation with immediate invalidation, token introspection (RFC 7662), revocation (RFC 7009), OIDC Discovery at /.well-known/openid-configuration, and RP-initiated end-session logout with id_token_hint. Any OIDC-compliant client library works without modification.
Multi-Tenant by Design
Every workspace gets its own RS256 key pair provisioned on first use — no shared signing key across tenants. Admin-initiated key rotation lets you generate a new signing key, promote it to active, and retire the old key when all tokens have expired. Isolated user directories, slug-routed APIs (/t/{workspace}/api/v1), independent issuer URLs, and configurable token TTLs. The same email address is treated as a completely separate identity in each workspace.
Flexible Authentication
Password authentication with history tracking (prevent reuse of last N passwords), blacklist checking, complexity enforcement, and configurable max age with forced expiry. TOTP MFA (RFC 6238) with recovery codes. Google and GitHub OAuth with automatic account linking by email — users can view and manage connected social identities from the self-service portal. Admin-initiated user invitations with branded email, 72-hour activation links, and automatic account setup. MFA enforcement is configurable per workspace.
Account Lockout & Brute-Force Protection
Configurable failed login threshold with automatic account lockout. Locked users receive an email notification with a password reset link. Admins can manually unlock accounts. Combined with per-IP rate limiting and per-workspace scoping, every layer of the login path is protected. Password change and account lock events trigger async security notification emails.
RBAC with Groups & Inheritance
Assign roles directly to users or via groups. Groups inherit roles, users inherit group membership. Composite inheritance means a user in multiple groups accumulates all permissions. Access revocation is immediate — no waiting for token expiry. Admin and user-initiated session revocation, plus bulk revocation from the admin console.
Custom JWT Claims
Attach per-user key-value attributes and project them into JWT access and/or ID tokens via tenant-level claim mappers. 41 reserved OIDC claim names are blocked to prevent overwriting standard claims (sub, iss, email, etc.). Claim mapper cache with 60-second TTL keeps token issuance fast. Changes propagate on next token issuance or immediately on refresh token renewal. Admin console and REST API for managing both attributes and mappers. Max 20 mappers per tenant to prevent JWT bloat. PII safeguard — admin UI warns that attribute values flow unencrypted into tokens.
Security That Ships by Default
bcrypt password hashing, AES-256-GCM encryption at rest (RSA private keys, SMTP credentials, TOTP secrets), SHA-256 hashed API keys, HMAC-SHA256 signed cookies, strict CSP headers with zero inline JavaScript (style-src permits unsafe-inline for server-injected theme tokens), SRI integrity on all JS bundles, CSRF protection, SameSite cookies, open redirect prevention, mandatory KAUTH_SECRET_KEY with no dev-mode fallback, admin-initiated signing key rotation with JWT kid headers per RFC 7517, and tiered rate limiting (login, MFA, password reset) per IP per workspace. Hardened before your first deploy.
Real-time Webhooks
HMAC-SHA256 signed payloads delivered for 8 event types: user.created, user.updated, user.deleted, login.success, login.failed, password.reset, mfa.enrolled, and session.revoked. Configurable endpoint URLs with exponential backoff retry logic (3 attempts: immediate, 5 min, 30 min). React to identity events without polling.
White-label Auth Pages
CSS variables injected server-side at render time — no CDN cache invalidation, no rebuild required. Custom primary color, background, logo, and favicon per tenant. Three presets included: Dark, Light, and Simple. Theming is fully isolated — changing one tenant's theme has zero effect on others.
Docker-Native Deployment
~120 MB multi-stage image published to GHCR (ghcr.io/inumansoul/kotauth). One-command quickstart with demo data pre-loaded — or bring your own .env for a custom setup. Flyway migrations run automatically on startup — no init scripts, no manual schema setup. Built-in CLI tools (generate-secret-key, reset-admin-mfa) for key provisioning and emergency recovery. HTTP compression (gzip/deflate), static asset caching, and bundled Swagger UI for air-gapped environments. Bundled PostgreSQL included, or bring your own database (RDS, Supabase, Neon, Railway, Render) via a dedicated compose file.
AI-Native Management (MCP)
Manage your entire identity infrastructure from Claude, Cursor, or any MCP-compatible AI assistant. The @kotauth/mcp package exposes 25 tools across 8 domains: users, roles, groups, applications, sessions, audit logs, user attributes, and claim mappers. Scope-based access control — each API key grants only the permissions you choose. One command to connect: npx @kotauth/mcp. No SDK to learn, no HTTP to write. Ask your AI assistant to create a user, set custom attributes, configure claim mappings, or query audit logs — it calls the right endpoints automatically.
Magic-Link Passwordless
Email-based passwordless login with 15-minute one-time tokens. Same-device cookie binding via KOTAUTH_AUTH_CONTEXT prevents token replay from a different browser. User-enumeration safe — consistent response timing regardless of whether the email exists. MFA invariant preserved — magic link authenticates the first factor, TOTP is still required if enrolled. Workspaces can go fully passwordless by disabling password login entirely.
Tenant Backup & Restore
Export entire workspaces as encrypted, portable snapshots. Archives use PBKDF2 with 600,000 iterations for key derivation and AES-256-GCM for encryption, packaged in a self-contained bkp1 envelope format. Import with schema-version compatibility validation to prevent data corruption. Available via CLI (export-tenant / import-tenant) and admin REST API endpoints.
Redis Distributed Sessions
Optional Redis sidecar via KAUTH_REDIS_URL upgrades in-memory stores to distributed session storage and rate limiting. Lua-scripted rate limiting ensures consistent enforcement across all Kotauth instances. Fail-closed semantics — Redis unavailability rejects requests rather than bypassing limits. Lettuce client with connection pooling and automatic reconnection. Sticky sessions no longer required behind a load balancer.
Admin Impersonation
Act as any user without knowing their password. Impersonation sessions carry an RFC 8693 act claim identifying the admin, creating a full audit trail. Dual-session model — the admin session stays active underneath. Cascade revocation — revoking the admin session also terminates the impersonated session. Available from the admin console with one click.
App Launcher
Per-workspace tile grid at /t/{slug}/launcher showing all applications the user is entitled to access. Entitlement model based on client-scoped roles — users only see apps they have permission to use. Automatic tile generation from registered OAuth applications with logo and description.
Internationalization (i18n)
All auth and portal UI strings are externalized via a TranslationPort. Volume-mounted JSON bundles let you add languages without recompiling — just drop a file in KAUTH_I18N_BUNDLE_DIR. Accept-Language header resolution with quality-factor ranking and graceful English fallback. Zero hardcoded English strings in auth or portal views. 174 Spanish translation keys shipped as a reference implementation.
Breached Password Detection (HIBP)
Passwords are checked against the Have I Been Pwned database using k-Anonymity range queries during registration and password changes — only the first 5 characters of the SHA-1 hash leave the server. BreachedPasswordPort provides a pluggable interface in the domain layer. Combined with password history, complexity rules, and max age, Kotauth enforces password hygiene at every touchpoint.
Built on open standards
Any OIDC-compliant client library works with Kotauth without modification. These are the RFCs implemented — not approximated.
RFC 7519
JSON Web Token (JWT)
RFC 7636
PKCE for OAuth 2.0
RFC 7009
Token Revocation
RFC 7662
Token Introspection
RFC 8414
Authorization Server Metadata
RFC 6238
TOTP Algorithm
RFC 7807
Problem Details for APIs
Hardened before your first deploy
Security decisions are made at the framework level — not left as configuration exercises for the operator.
bcrypt
Password hashing
AES-256-GCM
RSA keys + secrets at rest
SHA-256
API key hashing
RS256
Per-tenant JWT signing
SRI
JS bundle integrity
Token rotation
Refresh token invalidation
Account lockout
Brute-force protection
CSP + CSRF
Transport & request hardening
End-session logout
RP-initiated OIDC logout
Ready to deploy?
Everything above ships in a single Docker image. No licensing, no per-seat cost, no SaaS dependency. See it running before you deploy.