zitadel-sveltekit Svelte Themes

Zitadel Sveltekit

SvelteKit + Zitadel OIDC Authentication Example

A modern, production-ready example demonstrating how to implement Zitadel authentication in a SvelteKit application using OpenID Connect (OIDC) flow.

๐ŸŽฏ Overview

This project showcases how to integrate Zitadel's authentication service into a SvelteKit application using the OIDC flow with PKCE (Proof Key for Code Exchange) for enhanced security. PKCE eliminates the need for client secrets in public clients, provides additional protection against authorization code interception attacks, and follows OAuth 2.1 security best practices.

Why PKCE?

  • โœ… No client secrets stored in browser/app
  • โœ… Protection against code interception attacks
  • โœ… Perfect for Single Page Applications (SPAs)
  • โœ… Enhanced security for mobile and public clients
  • โœ… OAuth 2.1 compliant

๐Ÿ“‹ Prerequisites

  • Node.js 18+
  • pnpm
  • Just command runner
  • Docker (or Podman, Orbstack) and Docker Compose
  • A Zitadel instance (local via docker-compose or cloud)

๐Ÿ›  Tech Stack

  • Frontend: SvelteKit, TypeScript, Auth.js
  • Authentication: Zitadel
  • Task Runner: Just
  • Local Services: Docker Compose

Why This Project?

  • Educational Resource: Learn how to properly implement OIDC authentication in SvelteKit
  • Production-Ready: Follow security best practices and modern development patterns
  • Fully Typed: Complete TypeScript support for better developer experience
  • Well-Documented: Extensive comments and documentation throughout the codebase

๐ŸŽฏ Features

  • โœ… OIDC Authentication Flow
  • โœ… Protected Routes
  • โœ… Session Management
  • โœ… Automatic Token Refresh
  • โœ… Logout Handling
  • โœ… User Profile Display
  • โœ… TypeScript Support
  • โœ… Responsive UI

๐Ÿš€ Installation

1. Clone the Repository

git clone https://github.com/robots4life/zitadel-sveltekit.git
cd zitadel-sveltekit

2. Install dependencies:

just install

3. Start local Zitadel instance:

just start-zitadel

4. Copy environment variables:

cp .env.example .env.local

5. Configure your environment variables (see Configuration)

6. Run the development server:

just dev

โš™๏ธ Configuration

Quick Start with Local Zitadel

  1. Start Zitadel locally:

    just zitadel-up
    
  2. Access Zitadel Console: http://localhost:8080

Manual Environment Variables

Create a .env.local file with the following variables:

# Zitadel Configuration (Local)
ZITADEL_ISSUER=http://localhost:8080
ZITADEL_CLIENT_ID=your-client-id

# Zitadel Configuration (Cloud - Alternative)
# ZITADEL_ISSUER=https://your-instance.zitadel.cloud
# ZITADEL_CLIENT_ID=your-client-id

# Application URLs
PUBLIC_BASE_URL=http://localhost:5173
REDIRECT_URI=http://localhost:5173/auth/callback

# Session Secret (for server-side session storage)
AUTH_SECRET=your-super-secret-jwt-secret

Zitadel Setup (Manual)

  1. Create a Project in your Zitadel console
  2. Add an Application with the following settings:
    • Application Type: Single Page Application (SPA) or Native
    • Authentication Method: PKCE
    • Redirect URIs: http://localhost:5173/auth/callback
    • Post Logout URIs: http://localhost:5173
    • Grant Types: Authorization Code
    • Response Types: Code
    • Important: No client secret is generated or needed

๐Ÿš€ Available Commands

This project uses Just for task automation. Run just --list to see all available commands.

Development

# Install dependencies
just install

# Start development server
just dev

# Run development server with host binding
just dev-host

# Build the application
just build

# Preview production build
just preview

Docker & Services

# Start Zitadel locally
just zitadel-up

# Stop Zitadel
just zitadel-down

# View Zitadel logs
just zitadel-logs

# Restart Zitadel services
just zitadel-restart

# Reset Zitadel data (โš ๏ธ  destroys all data)
just zitadel-reset

Utilities

# Run type checking
just check

# Format code
just format

# Run linting
just lint

# Clean build artifacts
just clean
To Be Done (TBD) Repository Layout

๐Ÿ” Authentication Flow (PKCE)

  1. Login Initiation: User clicks login, app generates PKCE code challenge
  2. Authorization: User redirected to Zitadel with code challenge
  3. User Authentication: User authenticates with Zitadel
  4. Callback: Zitadel redirects back with authorization code
  5. Token Exchange: App exchanges code + code verifier for tokens
  6. Session Creation: User session established (no client secret needed)
  7. Protected Access: User can access protected routes

PKCE Benefits:

  • No client secret required (perfect for SPAs and public clients)
  • Protection against authorization code interception
  • Enhanced security for mobile and browser-based applications

๐Ÿงช Usage Examples

Work In Progress (WIP)

๐Ÿ”’ Security Considerations

PKCE Security Benefits

  • No Client Secrets: Eliminates secret storage in public clients
  • Code Interception Protection: Dynamic code verifiers prevent replay attacks
  • OAuth 2.1 Compliance: Follows latest security recommendations
  • Perfect Forward Secrecy: Each authentication flow uses unique codes

๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit changes: git commit -m 'Add amazing feature'
  4. Push to branch: git push origin feature/amazing-feature
  5. Open a Pull Request

Development Guidelines

  • Follow TypeScript best practices
  • Add tests for new features
  • Update documentation as needed
  • Ensure responsive design
  • Test authentication flows thoroughly

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ†˜ Support & Troubleshooting

Common Issues

Zitadel not accessible

# Check if services are running
just zitadel-logs

# Restart services
just zitadel-restart

Authentication redirect issues

  • Ensure redirect URIs match exactly in Zitadel console
  • Check that PUBLIC_BASE_URL is correct in .env.local

CORS errors

  • Verify Zitadel allowed origins include http://localhost:5173

Top categories

Loading Svelte Themes