ZITADEL: identity and access management with SSO and passkeys. Signed; SBOM and SLSA v1 provenance.
3.4K
readystack/zitadel:v4.20.0-CE-ubuntu24.04-r1
Source, recipe and records
v4.20.0): https://github.com/zitadel/zitadel/tree/8afa5dd37a8e723efb9eace8d09fd5c1cccef694A cosign-signed build of github.com/zitadel/zitadel v4.20.0 (AGPL-3.0-only; the embedded login/proto/docs subtrees are MIT/Apache-2.0 but the shipped server binary is AGPL-3.0-only), built clean-room from official upstream source, with the source changes listed below by ReadyStack.
Who: Developers building SaaS and business-to-business applications who need login, single sign-on and multi-tenancy.
Why: ZITADEL is an open-source identity and access management platform with single sign-on over OpenID Connect and SAML, multi-factor login and passkeys, multi-tenancy, an audit trail of all events, and APIs.
Use case: A software company sells its application to other businesses, each wanting its own branding and users. In ZITADEL each customer is an organisation with its own branded login and self-service user management, and the application signs everyone in through OpenID Connect.
About the upstream project, written from its own description: https://github.com/zitadel/zitadel · https://zitadel.com/docs
Signature, user and attestations below were measured on the published digest sha256:3f9af2e2aaa50db0cc8997819f37c43ba164b9696eec96fd012f89cb26bfd53e on 2026-10-29.
04daa92344a52dbc) on this release's index digest sha256:3f9af2e2aaa50db0cc8997819f37c43ba164b9696eec96fd012f89cb26bfd53e; verify with cosign verify --key https://readystack.dev/keys/cosign.pub readystack/zitadel:v4.20.0-CE-ubuntu24.04-r1.zitadel).This image follows the ReadyStack release-tag convention:
The current release is v4.20.0-CE-ubuntu24.04-r1 — the release listed at readystack.dev. Release tags use the pattern <upstream-version>-CE-<base-os>-r<N>; the current one is signed, attested (SBOM + provenance), and is provided under the ReadyStack Agreement.
Earlier release tags (an older version or revision in the same pattern) are superseded. They stay pullable so existing deployments can pin them, but they are no longer re-graded, and fixes appear only in newer releases: move to the current release. For a superseded release's build kit, ask support.
Release tags never move, so pulling the same tag again never changes the image. To be offered each new release automatically (a new revision r<N+1>, or a new upstream version), use the ReadyStack Renovate preset: https://readystack.dev/updates.html
Any tag beginning with internal- is an engineering-pipeline artifact published for build observability. It is unsupported, may change or disappear without notice, and must not be used in production.
# ✓ current release
docker pull readystack/zitadel:v4.20.0-CE-ubuntu24.04-r1
# ✗ unsupported (do not pull)
docker pull readystack/zitadel:internal-...
This release is signed; verify it with cosign verify --key https://readystack.dev/keys/cosign.pub readystack/zitadel:v4.20.0-CE-ubuntu24.04-r1 (the signature is recorded in the public Sigstore transparency log). Support: [email protected], as set out in the ReadyStack Agreement.
Single container, single static Go binary (CGO-free), foreground process — a cloud-native Identity & Access Management (IAM) / OIDC + OAuth2 + SAML + OpenID provider. REQUIRES an EXTERNAL PostgreSQL database the customer provisions and points the container at via ZITADEL_DATABASE_POSTGRES_* env vars — there is NO embedded/SQLite database. zitadel creates and migrates its own schema (event-sourced) in that postgres on first start. NOT a docker-compose-only or Kubernetes-only product, but it is NOT self-contained: postgres is a hard external dependency.
Secrets go in an env file that only you can read, not on the command line, and passwords that only set up the first start come out of it after setup. Create zitadel.env with install -m 600 /dev/null zitadel.env, then write these lines into it with an editor, with your own values (a value typed into a shell stays in its history). Docker reads each line as written: no quotes around a value, no spaces around =.
# The password ZITADEL gives its own database user; needed at every start.
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD=YOUR_ZITADEL_DB_PW
# Your PostgreSQL administrator's password; start-from-init connects with it at every start.
ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD=YOUR_POSTGRES_ADMIN_PW
# The first administrator's password; this image requires it at every start-from-init, and ZITADEL uses it only for the first instance.
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD=YOUR_ADMIN_PW
openssl rand -hex 16 | tr -d '\n' > zitadel-masterkey
sudo chown 999:999 zitadel-masterkey && sudo chmod 400 zitadel-masterkey
# --tlsMode external already sets ZITADEL_EXTERNALSECURE=true; were you to set it yourself, -e goes before the image name
docker run -d --name zitadel -p 8080:8080 -v "$PWD/zitadel-masterkey":/run/secrets/zitadel-masterkey:ro -e ZITADEL_DATABASE_POSTGRES_HOST=YOUR_POSTGRES_HOST -e ZITADEL_DATABASE_POSTGRES_PORT=5432 -e ZITADEL_DATABASE_POSTGRES_DATABASE=zitadel -e ZITADEL_DATABASE_POSTGRES_USER_USERNAME=zitadel -e ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE=require -e ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME=postgres -e ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE=require --env-file ./zitadel.env readystack/zitadel:v4.20.0-CE-ubuntu24.04-r1 start-from-init --masterkeyFile /run/secrets/zitadel-masterkey --tlsMode external --externalDomain YOUR_DOMAIN --externalPort 443
The first two lines create the masterkey: exactly 32 bytes, readable only by the container's user (uid 999). It encrypts the secrets in the database, so keep it with every database backup. zitadel.env holds the three passwords, all needed at every start-from-init: the password ZITADEL gives its own database user, your PostgreSQL administrator's password (start-from-init connects with it on every start and creates that user and the zitadel database the first time), and the first administrator's password (at least 8 characters with upper and lower case, a digit and a symbol; the image needs it on every start-from-init, ZITADEL uses it only for the first instance). The two PostgreSQL passwords must not contain a space or a backslash followed by ' or another backslash (\', \\), begin with ' or end with a backslash: ZITADEL passes them to PostgreSQL unquoted, and start-from-init then fails (password authentication failed, or unterminated quoted string in connection info string for a leading '). Replace YOUR_POSTGRES_HOST and YOUR_DOMAIN with your own values, and reach ZITADEL at https://YOUR_DOMAIN through your TLS proxy: it answers its APIs, discovery and login only under that host name, not under http://localhost:8080 or the server's IP address. For a local HTTP trial use --tlsMode disabled --externalDomain localhost --externalPort 8080 and open http://localhost:8080 (ZITADEL_EXTERNALSECURE is not needed: --tlsMode overrides it).
This software is licensed under the GNU Affero General Public License, and the releases below are built from a modified copy of its source. Each line names a release, what ReadyStack changed and where the diff is published. From 2026-10-27 a release's diff carries every upstream file its build changes, the dependency manifests and lockfiles included, so its complete corresponding source is the upstream tag with that diff applied; the diff of an earlier release carries the source edits its line names, and the dependency files that release's build changed are in its release archive (vendored/). If you let users interact with the server over a network, AGPL-3.0 section 13 asks you to offer them its source; for a release from 2026-10-27 on, a link to its diff and the upstream tag does that.
v4.20.0-CE-ubuntu24.04-r1 — one line in internal/i18n/translator.go stops the 'missing translation' warning from logging its arguments, which include one-time password-reset, email-verification and initial-password codes; full diff at https://readystack.dev/source/zitadel/v4.20.0/zitadel-v4.20.0-readystack.patchv4.19.5-CE-ubuntu24.04-r1 — one line in internal/i18n/translator.go stops the 'missing translation' warning from logging its arguments, which include one-time password-reset, email-verification and initial-password codes; full diff at https://readystack.dev/source/zitadel/v4.19.5/zitadel-v4.19.5-readystack.patchv4.19.3-CE-ubuntu24.04-r1 — one line in internal/i18n/translator.go stops the 'missing translation' warning from logging its arguments, which include one-time password-reset, email-verification and initial-password codes; full diff at https://readystack.dev/source/zitadel/v4.19.3/zitadel-v4.19.3-readystack.patch (notice: https://readystack.dev/source/zitadel/v4.19.3/README.txt)The complete --network=none build kit for this image — plus admin/DB/API handbooks, the build's validation records, and its build provenance records — is a free download for any registered account at readystack.dev/products/zitadel. A clean-room rebuild from this release's archive on an egress-blocked host reproduced its linux/amd64 digest sha256:7af834957f0ed4bb1a7ab007a0ee63e94812d14f5fbf1ee14f8d14e6fb5da8d8 on 2026-10-28.
— ReadyStack · readystack.dev
Content type
Image
Digest
sha256:3f9af2e2a…
Size
83.4 MB
Last updated
1 day ago
docker pull readystack/zitadel:v4.20.0-CE-ubuntu24.04-r1