DEV Community

Mohamed Zrouga
Mohamed Zrouga

Posted on

Build a Secure Multi-Tenant SSO System with Keycloak, Go & React: Step-by-Step Guide

Managing authentication across multiple tenants can be a nightmare—different domains, identity providers, and security models all add complexity. In this guide, you’ll learn how to build a production-ready multi-tenant SSO system using Keycloak, React, and Go, enabling your users to log in with Google, GitHub, or Microsoft accounts, while keeping each tenant securely isolated.


Stack Overview

Layer Tech Purpose
Identity Keycloak Central identity provider (OAuth2, JWT, social login, multi-tenancy)
Frontend React User and admin interfaces
Backend Go Stateless API with JWT validation and business logic
Data PostgreSQL Stores tenants, users, and metadata
DevOps Docker Compose Container orchestration for local setup

Architecture: A Layered Security Model

The solution follows a cleanly separated, layered architecture:

  • Identity Providers Layer: Social login via Google, Microsoft, and GitHub
  • Frontend Layer:
    • React user interface (http://localhost:3000)
    • Admin dashboard (http://localhost:3001)
  • Authentication Layer:
    • Keycloak (http://localhost:8080) handles all identity and access flows
  • Backend Layer:
    • Go API (http://localhost:8081) that verifies JWTs and executes tenant-aware logic
  • Data Layer:
    • PostgreSQL database for user, tenant, and relationship data

Why This Stack?

Image description

Keycloak

  • Open-source IAM platform with OAuth2, OpenID Connect, social login, and multi-tenancy.
  • Saves you from writing brittle auth code.
  • Highly customizable with realms, clients, and mappers.

React

  • Modern, component-driven framework.
  • Perfect separation of user frontend and admin interface.
  • Great developer experience and large ecosystem.

Go

  • Lightweight and performant.
  • Excellent standard library for JWT handling and HTTP.
  • Strong concurrency model for scalable APIs.

Authentication Flow

Here’s how the secure OAuth2-based login works:

  1. User starts login from the React frontend.
  2. Keycloak redirects to the selected identity provider.
  3. User authenticates, and the OAuth callback returns to Keycloak.
  4. Keycloak issues a JWT with user and tenant context.
  5. Frontend includes the JWT in API requests.
  6. Go backend validates the token and extracts tenant info.
  7. Tenant-isolated operations run based on JWT claims.

Image description

This setup ensures centralized auth with stateless APIs and strong tenant isolation.


Multi-Tenancy: Key Considerations

Concern Solution
Tenant Isolation Users and data are scoped to their own organization.
Flexible Auth Each tenant chooses which social login providers to enable.
Self-Service Admin Admin panel allows tenant admins to manage users without overlap.
Scalable Infrastructure Each component is containerized and independently scalable.

Security Best Practices

  • JWT Validation: Go backend checks tokens against Keycloak’s JWKS endpoint.
  • CORS Configuration: Proper headers configured in both Keycloak and backend.
  • Environment Variables: All sensitive values are managed via .env files.
  • Isolated Networks: Docker containers communicate over private networks.

Getting Started

Clone and boot the system using Docker Compose:

# Clone and navigate to the repo
git clone https://github.com/zrougamed/multitenant-sso
cd multitenant-sso

# Start all services
docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

Access services at:


Configuring OAuth Providers

Google

  1. Go to Google Cloud Console
  2. Create OAuth credentials
  3. Set redirect URI: http://localhost:8080/realms/{realm}/broker/google/endpoint

GitHub

  1. Go to GitHub Developer Settings
  2. Set callback URI: http://localhost:8080/realms/{realm}/broker/github/endpoint

Microsoft

  1. Register an app via Azure App Registrations
  2. Set redirect URI: http://localhost:8080/realms/{realm}/broker/azure/endpoint

Common Challenges and Solutions

Problem Solution
Port Conflicts Modify docker-compose.yml or Keycloak config.
CORS Errors Ensure correct CORS settings in backend and Keycloak.
JWT Validation Fails Double-check audience (aud), issuer (iss), and realm configuration.

Extending the System

  • Add more identity providers: Twitter, Facebook, etc.
  • Add Role-Based Access Control (RBAC) via Keycloak groups and roles.
  • Implement API rate limiting in Go middleware.
  • Add monitoring with Prometheus, Grafana, or ELK.

Production Considerations

  • High Availability: Cluster Keycloak and PostgreSQL with redundancy.
  • SSL/TLS: Use reverse proxy like NGINX or Traefik for HTTPS.
  • Backups: Regular backups for Keycloak and PostgreSQL.
  • Monitoring: Alerting on auth failures, performance, and token expiry issues.

Conclusion

Building a secure, scalable, multi-tenant SSO system doesn’t have to be painful. By using Keycloak for identity management, React for the frontend, and Go for the API, you get a powerful and maintainable architecture that scales with your needs.

The system supports:

  • Multi-tenant user isolation
  • Social logins via OAuth
  • Stateless APIs with secure JWTs
  • Admin management for each tenant

Source Code

👉 GitHub Repository – multitenant-sso


Questions or feedback?

Open an issue on GitHub or connect with me on LinkedIn

Top comments (0)