Skip to content

bauer-group/CS-IAM

Repository files navigation

CS-IAM — Zitadel OIDC/IAM Stack

Central, self-hosted OIDC/IAM provider for BAUER GROUP, built on Zitadel. It federates to Microsoft Entra ID, keeps its own accounts, syncs profiles/avatars/groups, and provisions itself as code — so it can eventually run fully autonomous.

Release & Docker Build


Highlights

Capability How
Federates to Entra ID (and later Google/GitHub/…) upstream IdP, provisioned via Terraform
Own local accounts (need not exist in Entra) login policy allows local + IdP; federated users are password-less (IdP-only); ForceMFALocalOnly
Avatar + extended attributes kept current directory-sync delta job → native phone + metadata (fax/mobile/office/dept) + avatar
Roles/groups drive app login Entra groups → namespaced project roles + grants; project authorization-on-auth gate
Self-service UI Zitadel Console + Login v2
Everything as code native config → Terraform (IaC init container) → Python sync; non-destructive
Stable migration subject-preservation (sub = Entra OID) → zero app changes
Self-healing, backups, CI/CD restart + healthchecks, pg_dump sidecar, reusable-workflow pipeline

Architecture

            ┌──────────────┐   OIDC    ┌──────────────┐  upstream
 apps  ───▶ │   Zitadel    │ ───SSO───▶│   Entra ID   │  (+ Google/GitHub later)
(Outline,   │  v4 (h2c)    │           └──────────────┘
 Documenso) │  sub = OID   │
            └──────┬───────┘
                   │ Postgres 18
            ┌──────▼───────┐   provisioner (OpenTofu, one-shot, non-destructive)
            │  database-server  │   directory-sync      (Graph delta → profiles/avatar/groups)
            └──────────────┘   database-backup    (pg_dump, --profile backup)

Quick start (development)

python scripts/generate-env.py          # generate secrets into .env
# edit .env: set AZURE_* (optional for standalone) — IAM_DEV_HOSTNAME defaults to zitadel.localhost
docker compose -f docker-compose.development.yml up -d --build
# console: http://zitadel.localhost:8080   (login admin@example.com)
curl http://zitadel.localhost:8080/.well-known/openid-configuration

Production (Traefik): set IAM_HOSTNAME, point DNS at the host, then docker compose -f docker-compose.traefik.yml up -d. See docs/installation.md.

Repository layout

config/zitadel/   defaults.yaml + steps.yaml   (native Zitadel config — policies, org, admin, SA)
terraform/        IdPs, project, OIDC apps, role catalog, grants  (IaC)
src/zitadel/             thin-wrapper image
src/provisioner/   OpenTofu init container (guarded, non-destructive)
src/directory-sync/        directory-sync (Python)
src/database-backup/      pg_dump sidecar (Python)
scripts/generate-env.py  cross-platform secret generator
docker-compose.{development,traefik,coolify}.yml
docs/             setup / management / operation / migration guides

Layered "everything-as-code"

  1. Native config (config/zitadel/*.yaml) — policies, branding, SMTP, token lifetimes, org + admin + machine SA.
  2. Terraform (terraform/, run by the provisioner init container) — IdPs, project, OIDC apps, role catalog, grants. Non-destructive: never prunes UI-made resources; aborts on any destroy.
  3. Directory-sync (directory-sync) — Graph delta → extended attributes, avatar, Entra groups → namespaced roles/grants. Login-time JIT refresh is native to Zitadel.

Documentation

Guide Topic
architecture.md the big picture: one instance/host, three orgs + user populations, domain discovery, access model
installation.md deploy (dev / Traefik / Coolify), first login
endpoints-and-portals.md every URL/portal: Console, Login v2, OIDC endpoints, APIs, dev vs prod
configuration.md .env + defaults.yaml/steps.yaml reference
provisioning-terraform.md IaC, state, non-destructive guard, adding apps/IdPs
applications-oidc.md connect your apps as OIDC clients (internal/external tiers, scopes, claims)
identity-providers.md per-org IdPs: Entra single/multi-tenant, Google + social catalog
branding-and-login.md brand colors/logo/font, Login v2 theming, translations, IdP-logo plan
directory-sync.md freshness model (JIT + delta), namespacing
users-roles-groups.md local vs federated, role/grant app-gating, grants-vs-scopes-vs-roles, self-service
console-guide.md view/manage each thing in the Console + how code (TF/branding) re-applies on deploy
migration.md Entra → Zitadel cutover (avatar + data preserved)
operations.md health, upgrades, HA path, decoupling
decoupling-from-entra.md step-by-step runbook to go MS-free (credential migration, clean IdP removal)
sizing-and-tuning.md PG18 presets (SSD/HDD + RAM size)
backup-and-restore.md pg_dump snapshots, off-site, restore
security-hardening.md security posture
troubleshooting.md h2c/502, PG18, duplicate users, …

Supported versions

Component Pin Note
Zitadel v4.15.0 PostgreSQL 18 needs ≥ v4.11.0
PostgreSQL 18-alpine volume path /var/lib/postgresql (no /data)
OpenTofu 1.12.0 provisioner image base
Python 3.14-alpine directory-sync + database-backup sidecars

License

This stack (config, compose, Terraform, sidecars) is MIT — see LICENSE. It is not a fork of Zitadel: Zitadel is consumed only as a pre-built container image, so its copyleft does not attach to this repository.

Zitadel is AGPL-3.0. The images this stack pulls (ghcr.io/zitadel/zitadel and the EP-Zitadel login base) are AGPL-3.0. Running them self-hosted is fine; if you modify Zitadel or the login and offer it over a network, AGPL §13 requires you to make your modified source available. This repository ships no Zitadel source — the modified login lives in the separate ep-zitadel repository, which carries that obligation for its image.

Trademarks. "Zitadel" is a trademark of its respective owner. This project is an independent deployment stack and is not affiliated with, endorsed by, or sponsored by Zitadel; the name is used only nominatively to identify the upstream software it deploys.

Security

See SECURITY.md for how to report a vulnerability, and docs/security-hardening.md for the stack's security posture.

About

OIDC, SAML, User Management, MFA, Token Issuance. Based on Zitadel.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages