Skip to content

Architecture

Component topology, deployment patterns, data model, and API surface of Zitadel.

Component Topology

flowchart TB
    subgraph Clients["Client Applications"]
        Browser["Browser\n(Login UI)"]
        Console["Console\n(Angular Admin UI)"]
        Apps["Your Applications\n(Web, Mobile, API)"]
    end

    subgraph Zitadel["Zitadel Server (Go Binary)"]
        direction TB
        APIGW["API Gateway\n(connectRPC / gRPC / REST)"]

        subgraph Services["Domain Services"]
            AuthSvc["Authentication\nService"]
            UserSvc["User\nService"]
            OrgSvc["Organization\nService"]
            ProjSvc["Project\nService"]
            SessSvc["Session\nService"]
            ActSvc["Actions\nService"]
        end

        subgraph Core["Core Engine"]
            Cmd["Command Handlers\n(Write Path)"]
            Query["Query Handlers\n(Read Path)"]
            ES["Eventstore\n(Events2 Table)"]
            ProjW["Projection\nWorkers"]
        end

        subgraph Ext["Extensibility"]
            Actions["JS Actions\nRuntime"]
            Hooks["Webhook\nDispatcher"]
            SCIM["SCIM 2.0\nServer"]
        end
    end

    subgraph Data["Data Layer"]
        PG["PostgreSQL\n(Events + Projections)"]
        Redis["Redis\n(Query Cache)"]
    end

    subgraph External["External Systems"]
        IdP["Identity Providers\n(Google, GitHub, Azure AD)"]
        SMTP["SMTP / SMS\n(Notifications)"]
        OTel["OpenTelemetry\nCollector"]
    end

    Browser --> APIGW
    Console --> APIGW
    Apps --> APIGW

    APIGW --> Services
    Services --> Core
    Cmd --> ES
    ProjW --> ES
    Query --> Redis
    ProjW --> PG
    ES --> PG
    Query --> PG

    APIGW --> Ext
    Actions --> Hooks
    SCIM --> UserSvc

    AuthSvc --> IdP
    ActSvc --> SMTP
    APIGW --> OTel

    style Zitadel fill:#1565c0,color:#fff
    style Data fill:#2e7d32,color:#fff
    style External fill:#e65100,color:#fff

Monolithic Binary, Modular Internals

Zitadel ships as a single Go binary with modular internal packages:

Package Purpose
internal/eventstore/ Event store abstraction, PostgreSQL implementation, push/pop logic
internal/command/ Write-side command handlers, business rule validation
internal/query/ Read-side query handlers, projection consumers
internal/auth/ OIDC, OAuth 2.0, SAML 2.0 protocol implementations
internal/authz/ Authorization resolution, permission checking
internal/api/ gRPC/REST API layer, connectRPC integration
internal/actions/ JavaScript runtime for custom auth flows
internal/crypto/ Encryption, hashing, key management
internal/webauthn/ FIDO2/WebAuthn authentication
internal/notification/ Email, SMS delivery pipeline
internal/idp/ External identity provider integrations
internal/user/ User domain logic (human + machine)
internal/org/ Organization domain logic
internal/project/ Project, application, role management
internal/i18n/ Internationalization
internal/cache/ Redis caching abstraction

API Surface

Zitadel exposes a dual-versioned API surface:

V1 APIs (Legacy, Context-Based)

API Scope Base Path Purpose
Auth API Per-user /auth/v1/ User-specific ops (profile, tokens, MFA)
Management API Per-org /management/v1/ Org admin ops (users, projects, apps)
Admin API Instance-wide /admin/v1/ Instance-level configuration
System API Self-hosted /system/v1/ Superordinate control

V2 APIs (Current, Resource-Oriented)

API Base Path Purpose
User Service /v2/users/ User management (preferred for new integrations)
Session Service /v2/sessions/ Session lifecycle management
Organization Service /v2/orgs/ Organization management
Project Service /v2/projects/ Projects, apps, roles
Action Service /v2/actions/ Actions and webhooks
Feature Service /v2/features/ Feature flag management
Settings Service /v2/settings/ Login, password, branding policies
Authorization Service /v2/authorizations/ User authorization (grants)
OIDC Service Standard OIDC endpoints OpenID Connect operations
SAML Service Standard SAML endpoints SAML 2.0 operations
SCIM 2.0 /scim/v2/{orgID}/ User provisioning
Web Key Service /v2/webkeys/ JWT signing key management

API Conventions

Operation Method Pattern
Create POST /v2/<resource>
Update POST /v2/<resource>/<id>
Delete DELETE /v2/<resource>/<id>
Set PUT /v2/<resource>
Get GET /v2/<resource>/<id>
Search POST /v2/<resource>/search

All APIs are generated from Protocol Buffer definitions in proto/zitadel/. The server supports connectRPC, standard gRPC, and HTTP/1.1 simultaneously.

Data Model

Hierarchical Resource Model

erDiagram
    INSTANCE ||--o{ ORGANIZATION : contains
    ORGANIZATION ||--o{ USER : manages
    ORGANIZATION ||--o{ PROJECT : owns
    ORGANIZATION ||--o{ IDP_CONFIG : configures
    ORGANIZATION ||--o{ POLICY : enforces
    PROJECT ||--o{ APPLICATION : registers
    PROJECT ||--o{ ROLE : defines
    PROJECT ||--o{ PROJECT_GRANT : shares
    USER ||--o{ USER_GRANT : receives
    USER ||--o{ SESSION : creates
    USER ||--o{ IDP_LINK : links
    PROJECT_GRANT }o--|| ORGANIZATION : "granted to"
    USER_GRANT }o--|| PROJECT : "scoped to"
    USER_GRANT }o--|| USER : "assigned to"
    ROLE }o--|| USER_GRANT : "included in"

    INSTANCE {
        string instance_id PK
        string domain
    }
    ORGANIZATION {
        string org_id PK
        string name
        string state
    }
    USER {
        string user_id PK
        string org_id FK
        string type
        string state
        string email
        string phone
    }
    PROJECT {
        string project_id PK
        string org_id FK
        string name
        string state
    }
    APPLICATION {
        string app_id PK
        string project_id FK
        string name
        string type
    }
    ROLE {
        string role_key PK
        string project_id FK
        string display_name
        string group
    }
    PROJECT_GRANT {
        string grant_id PK
        string project_id FK
        string granted_org_id FK
        string state
    }
    USER_GRANT {
        string grant_id PK
        string user_id FK
        string project_id FK
        string org_id FK
    }

Eventstore Schema

The eventstore uses a custom PostgreSQL schema optimized for append-only operations:

Table Purpose
eventstore.events2 Immutable event log with composite PK (aggregate_id, sequence)
eventstore.unique_constraints Enforces uniqueness across events (e.g., unique email per instance)
projections.* Materialized read-model tables rebuilt from events

Events are inserted atomically via the eventstore.push PostgreSQL function, which handles sequence assignment and unique constraint checking in a single transaction.

Deployment Topologies

Single Instance (Development)

flowchart LR
    subgraph Host["Docker Host"]
        ZA["Zitadel\n:8080"]
        PG["PostgreSQL 17\n:5432"]
    end

    ZA --> PG

Kubernetes Production (HA)

flowchart TB
    subgraph LB["Load Balancer"]
        NGINX["NGINX Ingress\n(TLS Termination)"]
    end

    subgraph K8s["Kubernetes Cluster"]
        subgraph ZA["Zitadel Pods (HPA)"]
            Z1["zitadel-7d4f8"]
            Z2["zitadel-a3b2c"]
            Z3["zitadel-e9f1g"]
        end

        Init["Init Job\n(DB Migrations)"]
        Setup["Setup Job\n(Schema + Defaults)"]

        subgraph Data["Data Plane"]
            PGHA["PostgreSQL HA\n(Patroni / CloudSQL / RDS)"]
            Redis["Redis\n(Cache)"]
        end
    end

    NGINX --> Z1
    NGINX --> Z2
    NGINX --> Z3
    Z1 --> PGHA
    Z2 --> PGHA
    Z3 --> PGHA
    Z1 --> Redis
    Z2 --> Redis
    Z3 --> Redis

    style K8s fill:#1565c0,color:#fff
    style Data fill:#2e7d32,color:#fff

Multi-Cluster / SaaS

flowchart TB
    subgraph Cloud["Zitadel Cloud"]
        ZC["Managed Zitadel\nInstance"]
        PG_C["Managed PostgreSQL"]
    end

    subgraph Remote1["Remote App Cluster 1"]
        App1["Application A"]
    end

    subgraph Remote2["Remote App Cluster 2"]
        App2["Application B"]
    end

    App1 -->|"OIDC / SAML"| ZC
    App2 -->|"OIDC / SAML"| ZC
    ZC --> PG_C

    style Cloud fill:#1565c0,color:#fff

Sources