Zitadel security hardening starts before the first login
Hardening a self-hosted Zitadel means setting controls in a fixed order: secrets first, then transport, database access, administrator access, authentication policy and logging. Each layer depends on the one before it. If the master key is weak or stored in the wrong place, TLS and database settings protect little, and administrator access and login policy rest on a foundation you have not verified. Before anyone signs in, a team deploying Zitadel for customer, partner or workforce identity should agree on this sequence and on who owns each control.
The work is harder than it looks because Zitadel's security depends on several layers at once. The instance is the top-level tenant with full data isolation. Organizations sit inside it and hold users, and projects group applications, roles and grants. Administrative rights can be granted at instance level, organization level or project level, and the Console and hosted login add their own surfaces. An identity provider is a high-value target, because every application that trusts it inherits its decisions. A misconfigured role grant or login policy can affect many downstream applications at once, so reviews should cover each layer rather than only the instance.
The hardening steps also depend on how you deploy. Zitadel documents self-hosting on Linux and macOS binaries, Docker Compose and Kubernetes, and it uses PostgreSQL as its database, with versions 14 through 18 supported. Secret delivery, certificate handling, network segmentation and backup access look different in each model. A Kubernetes deployment usually moves secret management into the cluster and its operators, while a binary or Compose deployment places more responsibility on host configuration and file permissions. Confirm your target PostgreSQL version against the Zitadel database documentation before you lock down database roles, and confirm the deployment method against the self-hosting overview, because the exact configuration keys and file locations differ between them.
Start with an inventory. List every secret the deployment holds, including the master key, database credentials, signing and encryption material, identity provider client secrets and any service account keys used by automation. For each one, record where it lives, who can read it, how it rotates and what breaks if it leaks. Next, list every administrative identity and the scope of its grant. Ask your team to confirm, in writing, which people and systems hold instance-level rights, and whether any of them are shared accounts. These two lists produce the decisions your security owner needs to sign off before go-live, and they set the order of the rest of the work.
Which Zitadel components and settings carry security weight
A self-hosted Zitadel deployment holds signing keys, user credentials, tenant data and administrative power in a small number of places. The cards below name those components and settings, what each one protects, and what a misconfiguration exposes, so the hardening work starts where a failure would matter most.
Application and master key
The Zitadel application encrypts sensitive data at rest with a master key that you supply at deployment. Whoever holds that key can decrypt stored secrets and signing material, so it protects the trust of the whole instance. A weak or shared key, or one stored beside the database backups, exposes every encrypted value. Confirm the exact key setting, its accepted format and rotation guidance in the self-hosting documentation for your chosen version.
PostgreSQL database and roles
PostgreSQL holds users, sessions, grants, client registrations and audit events. Zitadel needs separate credentials for administrative setup and for runtime access, and the runtime role should not hold more privilege than the service requires. Overly broad roles or a shared superuser password let any compromised component read or alter identity data directly. Confirm which PostgreSQL versions are supported for your release and how the role split is configured.
TLS termination and external URLs
Zitadel issues tokens and redirects that embed its external domain, so the public URL, the certificate chain and the point where TLS ends all define what clients trust. A mismatch between the configured external domain and the address users reach can break OIDC checks or enable redirect abuse. Confirm where TLS terminates in your reverse proxy or ingress, which headers are forwarded, and how the external domain is set.
Console and administrator accounts
The Console and the first administrator accounts control every instance, organization and policy. Compromise of one administrator account can change identity providers, redirect URIs and authentication rules across the deployment. Restrict who can reach the Console, require strong authentication for administrators, keep the number of admins small, and confirm the initial setup steps for your version.
Instances and organizations as boundaries
Instances provide full data isolation between tenants, and organizations inside an instance hold projects and users. Choosing whether a workload belongs in a separate instance or a separate organization sets how far a mistake or a compromised administrator can reach. Review delegated roles and project grants so that organization administrators cannot act outside their own scope. Confirm the boundary behavior for your version in the organizations documentation.
Identity provider configuration
Federated identity providers, including Entra ID, Okta, Google, LDAP and OIDC or SAML providers, decide who can sign in and which claims Zitadel trusts. Each provider needs correct client secrets, issuer values and attribute mappings, and a provider added to the wrong organization can admit users it should not. Review client secret storage and rotation, and limit which organizations may configure their own providers.
Authentication policies for MFA, passkeys and passwords
Login policies set whether multi-factor authentication is required, whether passkeys are offered, and how passwords must be built and reset. A policy that allows weak password-only login for administrators, or that leaves MFA optional where the organization expects it, weakens every account it covers. Decide the required level per population, test fallback paths, and confirm the exact policy names and scopes in the documentation for your chosen version.
Zitadel security hardening decisions and their operational cost
This table compares the hardening decisions a team must settle before go-live, the options for each and the ongoing effort each one adds. Read the middle column to see when an option suits your environment and the right column to see who keeps it running. The main takeaway is that each option moves work to a specific owner, so decide who holds each secret, certificate and policy before choosing.
| Decision and option | When it fits | Operational cost | Confirm before choosing |
|---|---|---|---|
| Master key: external secret manager | Teams already running a secret store with audited access and a documented rotation procedure. | Zitadel startup depends on the secret store being reachable. Access policies and rotation runbooks need ongoing ownership. | Confirm how the secret store is reached from your cluster or host and what happens during a store outage. |
| Master key: Kubernetes secret | Clusters where encryption at rest for secrets is enabled and namespace access is tightly limited. | Anyone who can read the secret can read the key. Needs regular RBAC reviews and checks on who can open a shell in pods. | Confirm that secret encryption at rest is enabled in your cluster and list who holds read access to the namespace. |
| Master key: file on host | Single-host Linux or Docker Compose installs where file ownership and permissions can be locked down. | Permissions, backups and host access all need manual control. Rotation means changing the key file directly on the host. | Confirm that backup tooling protects the key file and who can read host volumes. |
| TLS: terminated at ingress or load balancer | Teams with a central certificate manager that already renews certificates for other services. | Renewal lives at the edge. Forwarded protocol and client address headers must be set correctly or login flows fail. | Confirm how traffic between the edge and Zitadel is encrypted and which headers the proxy sets. |
| TLS: terminated inside the Zitadel process | Environments that require encryption end to end or have no shared edge proxy to manage certificates. | Zitadel must load certificate material and pick up renewals. Certificate expiry becomes an incident the identity team owns. | Confirm how your chosen deployment method reloads a renewed certificate without a full outage. |
| Database credentials: rotated | Teams with a secret store that can rotate PostgreSQL passwords on a schedule. Long-lived credentials suit only small installs that accept a longer exposure window. | Rotation needs automation, a connection drain and restart testing. Each rotation is a change window for identity traffic. | Confirm that your PostgreSQL version appears in the range listed in Zitadel's database documentation and test rotation in staging first. |
| Admin access: Console plus API service accounts | Teams that manage Zitadel through Terraform or scripts. Console-only access suits small admin teams with human operators. | Service account keys need issuance, scoping, rotation and monitoring. Each key becomes another secret to protect. | Confirm which admin roles each service account needs and whether your pipeline stores its key securely. |
| MFA and passkey policy: workforce and customer organizations | Workforce organizations with internal applications. Customer organizations can carry separate policy, set per organization where the design allows. | Enrollment, recovery and helpdesk load rise with stricter policy. Choosing whether passkeys can fall back to password needs an explicit owner. | Confirm which MFA and passkey settings apply to each organization and who approves recovery requests. |
| Audit events: exported to a log platform | Teams that must review administrator and sign-in events in a central system with retention they control. | The export pipeline, parsing and retention storage need an owner. Export gaps go unnoticed without alerting. | Confirm which events the audit trail covers and how export is verified after each upgrade. |
Zitadel security hardening build order, step by step
This sequence takes a self-hosted Zitadel instance from its default setup to one where secrets, transport, database access, administrator identity, sign-in factors and event records each have a defined owner and a check you can repeat. Each step closes with a verification that you can rerun after upgrades or configuration changes.
Inventory the deployment and target release
Record how Zitadel runs today, whether as a binary, with Docker Compose or on Kubernetes with the official Helm chart, along with the exact release tag and the PostgreSQL major version behind it. Confirm the target release line against the current release notes, and check that the PostgreSQL version falls within the range the database documentation lists as supported, which is versions 14 through 18. This step is done when the inventory names every component, version and environment, and each one has been checked against the supported range.
Move the master key into the secret store
Zitadel relies on a master key for encryption, so supply it from outside configuration files, container images and Helm values. Place it in the secret store your organization already operates, grant read access only to the service identity that runs Zitadel, and remove copies from environment files and shell history. Confirm the setting name and how the key is supplied in the current self-hosting documentation, including what depends on the key before you rotate or back it up. Closing check: start a test instance without the key and confirm it refuses to run, then start it with the key from the store and confirm it runs.
Terminate TLS and match the public hostname
Terminate TLS at your reverse proxy or ingress using current certificates issued by your certificate authority, and keep the certificate renewal process under the same ownership as other production certificates. Set the external domain, public URL and redirect settings in Zitadel so they match the public hostname exactly, and confirm the setting names against the current configuration reference. Disable or remove any plaintext listener on the public interface. Closing check: the public hostname presents a valid certificate chain, the OpenID discovery document reports the public URL as its issuer, and an external scan finds no plaintext port open.
Create a least-privilege PostgreSQL role
Create a dedicated login role for Zitadel that is separate from the database owner and from administrative roles, and grant it only the privileges the current documentation requires for its schema. Store the password in the secret store and plan for rotation. Check the documentation for whether first start or upgrades need additional rights, and if they do, use a separate migration role that is enabled only for those operations. Closing check: connect with the Zitadel role alone, confirm the application starts and serves requests, and confirm the role cannot create databases or roles.
Restrict first administrator and name admins
Restrict the first administrator created during setup, remove default or shared accounts, and create named administrator accounts through the Console, assigning each the narrowest administrative role that covers their work. Keep the first administrator as a break-glass account with a long credential held offline under dual control, and confirm the process with the people who will hold it. Closing check: export the list of administrator accounts and compare it with your named roster, sign in as each named administrator, and confirm that a login attempt with any former shared account fails.
Set MFA and passkey policies per organization
Configure login policies for each organization, since these settings apply per organization. Decide which second factors and passkeys are required for administrators and workforce users, whether password fallback is allowed for each group, and how customer users enroll. Confirm the policy names and options in the Console and the current passkey documentation before you change production organizations. Closing check: sign in as a test user in each organization, confirm the factor prompt matches that organization's policy, and confirm that a user without an enrolled factor is handled as the policy specifies.
Route audit and login events to central logging
Enable the audit and login event outputs that the current documentation describes, and route them to the central logging or SIEM platform your security team monitors. Define retention in that platform according to your own policy, and confirm which event fields arrive, such as actor, time and target. Ask the platform owner to confirm ingestion and access controls before you rely on the feed. Closing check: perform a test administrative action, such as changing a policy or creating a test user, and find the matching event in central logging with the correct actor, time and target. Also confirm that a failed login appears.
How hardening differs on binaries, Docker Compose and Kubernetes
Running the Zitadel binary directly on a host places the master key and database credentials in the host's process environment or in files the service account can read. TLS is usually terminated by a reverse proxy or load balancer in front of the service, or by the service itself where the documentation describes that setup. Configuration lives in files on the host, so version control depends on how your team manages those files.
- Master key: supply it through an environment file or secret manager agent that is readable only by the service user, and keep it out of unit files stored in shared repositories.
- Database credentials: create a dedicated PostgreSQL role with only the privileges the documentation requires, and rotate the password by updating the file and restarting the service.
- TLS: confirm whether the binary terminates TLS directly or sits behind a proxy, and assign certificate renewal to the team that owns that layer.
- Configuration review: keep configuration and service unit files in Git, deploy from the repository only, and treat manual edits on the host as drift to correct.
- Multiple hosts: replicas sharing one PostgreSQL database need identical configuration, the same master key and a load balancer in front, so confirm the multi-instance steps in the documentation.
Check that the master key cannot be read through shared logs, backups or process listings. In air-gapped or restricted networks, certificate issuance and log export change, so confirm the approach with the vendor self-hosting documentation and your own host baseline.
Compose passes settings through environment variables, .env files and optional secrets, so the central hardening task is keeping sensitive values out of the compose file, image layers and container metadata. TLS is commonly handled by a proxy container or a proxy on the host, and configuration review centers on the compose file and an environment template. Version pinning matters because Compose stacks often pull images by tag.
- Master key and database passwords: use Docker secrets or a read-only file mounted from the host, so values do not appear in docker inspect output.
- Image pinning: pin Zitadel and PostgreSQL images to the releases you tested, and record image digests in the change record.
- TLS: terminate at a proxy container with certificates mounted from a secret store, and keep the network between Zitadel and PostgreSQL limited to the containers that need it.
- Configuration review: store the compose file and an environment template in Git, and keep populated .env files out of the repository.
- Multiple containers: scaling several Zitadel containers against one PostgreSQL database requires a load balancer in front and identical master keys. Compose on a single host gives limited failover, so confirm whether this model meets your availability requirement.
Confirm the image tags, secret handling and proxy configuration with the vendor self-hosting documentation before go-live. In air-gapped or restricted networks, image mirroring, certificate issuance and log export change, so verify each of those paths in your own environment.
The official Helm chart is the model Zitadel recommends for high availability. Chart values typically reference Kubernetes Secrets for the master key and database credentials, TLS is commonly terminated at an ingress or gateway, and configuration is versioned as chart versions and values files. Reviewers can compare changes through pull requests and GitOps tooling before anything reaches the cluster.
- Secrets: create the master key and database credentials through an external secrets operator or sealed secrets, and keep literal values out of values files committed to Git.
- Cluster controls: enable encryption at rest for Secrets and restrict namespace access with role-based access control, so only the deployment pipeline and named operators can read them.
- TLS: automate certificate issuance at the ingress with a controller such as cert-manager or your platform equivalent, and confirm how the chart handles TLS on the connection to PostgreSQL.
- Versioning: pin the chart version and values in Git, promote changes through environments by pull request, and review the rendered manifest diff before each upgrade.
- Multiple replicas: all pods share one PostgreSQL database, so they need the same master key, and you should check PostgreSQL connection limits as replica count grows. Confirm how the chart runs schema migrations during upgrades.
Verify the secret references, ingress TLS settings and migration behavior against the chart documentation for your chart version. In air-gapped or restricted clusters, the chart source, image registry, certificate authority and log pipeline all change, so confirm each path with the vendor documentation and your own cluster design.
Zitadel security hardening controls for admin access, MFA and passkeys
Admin access, login policy and secrets handling decide how far a compromised credential can reach in a self-hosted Zitadel. The cards below cover the decisions to make and the checks to run on each one before go-live and after upgrades.
Separate platform and organization administration
Zitadel separates instance-level administration from administration inside each organization, and the two should not share people or roles by default. Platform administrators manage the instance, while organization administrators manage only their own users, projects and settings. Review who holds instance-level roles, confirm that customer or business-unit administrators hold only organization-scoped roles, and document the reason for each instance-level grant.
Limit instance-level administrators
Instance administrators can change settings that affect every organization, so the list should be short and reviewed on a fixed schedule. Keep at least two named people able to recover the instance, and remove the grant when someone changes role or leaves. Ask your implementation partner or the Zitadel documentation to confirm the exact roles and default grants in the version you run, since these change between releases.
Named accounts and scoped automation credentials
Administrators should sign in with their own accounts, never through a shared login. Automation such as Terraform, provisioning scripts or SCIM clients should use dedicated service users with the narrowest role that works, and their credentials should be rotated or short-lived where the API supports it. Check that every automation identity has an owner, a purpose and a documented expiry or rotation process.
Require MFA for administrators
Administrator accounts should require a second factor at every sign-in, and the policy should apply to instance and organization administrators alike. Confirm in your Zitadel version which login policy settings enforce MFA for a given group of users, and test the policy with an account that has no second factor enrolled. Record the recovery path, such as a second administrator who can reset factors, so a lost device does not leave the instance locked.
Passkey and password fallback policy
Zitadel supports passwordless login with passkeys based on FIDO2 and WebAuthn, with fallback to password login. The policy decision is whether that fallback is allowed for administrators, workforce users and customer users separately. Many teams allow passkeys for everyone, block password-only sign-in for administrators, and keep a documented exception path for lost devices. Set the policy per organization where user populations differ.
Master key and database credential handling
The master key and the PostgreSQL credentials protect the instance's encryption and data, so they belong in a dedicated secrets store, not in configuration files, container images or shared chat. Restrict who can read them, log access, and plan a rotation procedure that is tested in a non-production instance first. Confirm with the Zitadel self-hosting documentation how the master key is supplied and what changing it requires before you commit to a process.
TLS on every network hop
Traffic between clients and Zitadel, between Zitadel and PostgreSQL, between Zitadel and any identity provider, and between the ingress and internal services should use TLS with certificates from a trusted chain. Inventory each hop, confirm that certificate verification is enabled rather than skipped, and set up a renewal process with alerts before expiry. Check each internal component's documentation, since some default to plaintext on private networks.
What drives hardening effort and how to keep it down
This table lists the factors that most change how much design, testing and evidence work a self-hosted Zitadel hardening project needs, with a way to reduce each one. Read each row as a question to answer about your own environment before scoping. Most of the cost is people time, so the biggest savings usually come from standardizing policies and reusing tooling you already run.
| Driver | How it raises effort | How to keep it down |
|---|---|---|
| Instances and organizations | Each Zitadel instance is a separate tenant with its own data and settings, so every instance needs its own review. Each organization that needs different password, MFA or passkey rules adds another policy set to design and test. | Define one standard policy template per organization type and apply it through configuration rather than hand-editing each one. Keep the instance count to what isolation actually requires. |
| Administrators and automation accounts | Each human admin, service account and CI job needs a scoped role, a credential lifecycle and an access review. Broad grants force a longer permission analysis. | Use the smallest set of predefined roles, grant at the organization level where possible, and retire unused service accounts on a set schedule. Record who owns each automation identity. |
| Existing secret management and certificate tooling | If master keys, database passwords and TLS certificates must be created and rotated by hand, each rotation and recovery procedure has to be written and tested from scratch. Gaps in tooling often surface late. | Reuse the secret store and certificate automation your platform team already operates. Confirm how the master key and database credentials are injected at runtime in your deployment model before design starts. |
| Shared database | A PostgreSQL server shared with other workloads means credential scope, connection limits, backup windows and TLS settings must be reviewed against those other applications too. Changes can affect systems outside the identity service. | Give Zitadel a dedicated database user with the privileges it needs and a dedicated database where practical. Document the shared settings once and review them as part of each change. |
| Identity providers and applications to re-test | Each federated identity provider and each relying application can break when MFA, passkey or session policies change. Every affected login path needs a test case, a sign-off and a rollback plan. | Maintain a single test matrix listing each identity provider and application with its expected login flow. Run it after every policy change, and automate the parts that can be scripted. |
| Log export requirements | Shipping audit and access logs to a SIEM or log store requires format decisions, retention settings, access controls on the log pipeline and proof that events arrive complete. Each new destination adds a validation step. | Choose one export destination and format, and reuse the logging pipeline already used for other identity or infrastructure components. Test with known events, such as a failed login and an admin change, to confirm delivery. |
| Compliance evidence needs | If an auditor or customer assessment needs written policies, configuration exports, change records and access reviews in a specific form, each control needs its own evidence collection. Evidence gathered by hand late in a project is costly to rebuild. | Agree the evidence list before hardening starts, map it to the controls your assessor uses, and collect configuration exports through scripts on a regular schedule. DeployOpen prepares evidence but does not issue audit reports or certifications. |
| Scripted configuration review | Without a repeatable check, every hardening review is a manual comparison of settings across instances, which grows with each organization and each release. | Keep the desired configuration in version control, compare it against the live instance on a schedule, and report differences. Re-run the same checks after every Zitadel upgrade. |
How to test that Zitadel security hardening holds and fails safely
The point of this section is to prove each hardening control works and, just as important, that it fails in the safe direction. A control that is configured but never tested is an assumption. For a self-hosted Zitadel, the test plan should map one test to each control in the hardening baseline, state the expected result before running it, and record the actual result. Run the tests after the initial hardening, after every configuration change, and after every upgrade of Zitadel or PostgreSQL.
Start with the startup and transport controls. Restart the instance with the master key removed from its configuration source and confirm that it refuses to start, with an error that does not reveal the key or any fragment of it. Then search the process logs, container logs and log aggregation for the key value to confirm it was never written. Next, send a plaintext HTTP request to the external hostname and confirm it is refused or redirected to HTTPS, depending on the ingress design you chose. Check the redirect target as well, since a redirect to the wrong host is a common misconfiguration. Confirm the expected result with your own network team, because the exact behavior depends on your load balancer and ingress.
Next, test the database boundary from the database side. Connect as the Zitadel application role and attempt an owner-level action, such as dropping a table, altering a schema object, or granting privileges to another role. Each attempt should fail with a permission error. Confirm the application role can still perform the reads and writes Zitadel needs during normal operation, because an over-restricted role can break migrations or upgrades in a way that looks like a product fault. Run the migration step in staging with the least-privileged role where your upgrade plan allows it, and document which steps require a separate migration role.
Then test the access controls on the administrative surface. Send unauthenticated requests to the administrative APIs and open the Console in a private browser session. Both should fail and return no administrative data. Create a test administrator without MFA or a passkey, sign in, and confirm the policy blocks access or forces enrollment as your written policy states. Run password logins for a test user in each organization that should allow them, and for one that should refuse them, and check that the outcome matches the organization policy exactly. Record the policy version and the test user identifier with each result.
Finally, test failure of the credentials and the audit trail. Revoke or rotate the database password in staging and confirm that Zitadel fails with a clear connection or authentication error, not with cached data served to unauthenticated users or with a fallback to another account. Make one administrative change, such as altering a policy or creating a service user, and confirm it appears in the audit trail with the acting identity. Keep the evidence for each test: the date, the staging version, the commands or screenshots, the expected and actual results, and the reviewer's name. Staging should mirror production in configuration, ingress, database version and secret sources, or the results will not carry over. Store the evidence where your auditors can retrieve it, since it supports the control narrative for any compliance assessment.
What to review, rotate and document after go-live
Administrative changes are the events most likely to matter after an incident, so the audit trail review should answer three questions: who changed policies, who created administrators and which identity providers changed. Assign a named owner, and make sure that person is not the only one able to change the configuration. Set the review cadence in your own security policy. Before you rely on the trail, confirm which events your Zitadel version records and how long they are retained in your deployment, because retention depends on your configuration and storage.
- Policy changes: login, password, MFA and passkey policy edits, with the actor and the time of each change.
- Administrator grants: every new instance, organization or project administrator, and every removal.
- Identity provider changes: additions, edits and deletions of federated providers, since these alter who can sign in.
- Export and retention: whether events leave the cluster into your log platform and whether that copy outlives Zitadel's own retention.
- Review record: a dated sign-off that names the reviewer, the period covered and any follow-up actions.
Check that a deliberate test change in each category appears in the trail before you treat the review process as complete.
A self-hosted Zitadel depends on several secrets and certificates: the master key, database credentials, TLS certificates, signing keys, client secrets for integrated applications, and credentials used by federated identity providers or SCIM clients. Each needs a rotation procedure, an owner and a schedule recorded in the secret inventory. Rehearse each procedure in a non-production instance first, because some secrets protect data already stored in the database and cannot be changed casually.
- Master key: confirm in Zitadel's documentation how the master key can be changed safely, and never rotate it without a tested recovery copy.
- Database credentials: rotate the PostgreSQL users Zitadel connects with, and confirm that both the application and any migration job pick up the new values.
- TLS certificates: track expiry dates and renewal automation for every external and internal endpoint.
- Application and service secrets: client secrets, SCIM tokens and provider secrets, each with a named owner for the integration it supports.
- Signing and token keys: confirm how key rollover affects tokens already issued and how relying applications validate them.
Check that every rotation has a tested procedure, a recorded date and a verified sign-in afterward.
Hardening settings reduce risk only when someone notices attacks that reach them. Monitoring should cover failed administrative logins, spikes in failed user logins, sign-ins from unusual locations or devices, and successful sign-ins where MFA or passkey policy should have applied. Route Zitadel logs to the same platform your security team uses for other systems, and agree in advance which alerts page a responder and which are reviewed in batches.
- Failed administrative logins: alert on repeated failures against console and administrator accounts, since a few failures there may matter more than many user failures.
- Credential stuffing patterns: many failures across many accounts from one source, or many failures against one account from many sources.
- Unusual sign-in context: new countries, networks or client types for privileged accounts.
- Policy-sensitive sign-ins: successful sign-ins for accounts where the MFA or passkey requirement should have applied.
- Alert ownership: each alert has a named responder, a runbook step and a response expectation set by your own policy.
Check that a deliberate test failure against an administrator account reaches the responder through your alerting path.
The v4 release line receives new releases over time, and each one can change configuration defaults, database migrations or login behavior. Hardening that was correct on one version can drift after an upgrade, so each upgrade should be followed by a hardening regression test. Track releases on the official GitHub page, read the release notes for security-relevant changes, and test each upgrade in a staging environment that mirrors production configuration.
- Release tracking: subscribe the platform team to the release feed and assign someone to triage each v4 release.
- Staging first: apply the upgrade and database migration to a copy of production that uses the same policies and identity providers.
- Regression test: rerun the hardening checks for TLS, administrator access, MFA and passkey policy, and audit logging after every upgrade.
- Rollback plan: confirm how to roll back the application and whether the database migration can be reversed before you start.
- Version record: note the deployed version and the date of change in the configuration baseline.
Check that the regression test runs against the upgraded environment and that its results are stored with the change record.
Auditors, incident responders and your own future engineers will need a current picture of how Zitadel is configured. Four documents do most of the work: a configuration baseline, a secret inventory, an access matrix and a test evidence log. DeployOpen prepares systems, controls and evidence for compliance assessments, but independent auditors and certification bodies decide whether those controls meet a given standard.
- Configuration baseline: the approved settings for instances, organizations, policies, TLS and database connections, with the Zitadel version and the date.
- Secret inventory: each secret or certificate, where it is stored, who owns it and when it was last rotated. Record locations and owners, never secret values.
- Access matrix: which people and service accounts hold which administrative roles at each level, and who approved each grant.
- Test evidence: dated results of hardening tests, backup restores and upgrade regression runs, with the reviewer's name.
- Review cycle: the document owner, the date of the last review and the date of the next scheduled review.
Check that another engineer could rebuild the baseline from these documents alone and that none of them contains a secret value.
Zitadel security hardening questions buyers ask before hiring help
What does Zitadel security hardening cost and what drives the price?
The price follows from a written scope, so no fixed figure applies to every deployment. Cost components: the largest share is usually consultant time for design review and configuration of the master key, TLS, database credentials, admin access, MFA and passkey policies, and audit logging, plus testing and handover documentation. Recurring costs sit with your team or a retainer: certificate renewal, secret rotation, audit log review and applying Zitadel upgrades. Cost rises with the number of instances and organizations, the number of connected identity providers and the depth of compliance evidence required. When requesting a quote, ask for a line item per workstream, a list of assumptions about your environment, a clear split between one-time and recurring work, and the process for handling scope changes.
How long does a Zitadel security hardening project take?
Duration depends on scope, and the agreed scope sets the timeline. The main drivers are the number of Zitadel instances, the number of organizations inside them, how many identity provider integrations need review and how much compliance evidence you must collect. A single instance with a clear policy baseline moves faster than a multi-instance estate that must map controls to an external assessment. Access often matters more than the technical work: approvals for secret store, DNS, certificate and database changes can take longer than the configuration itself. Ask for a timeline with milestones tied to deliverables, a list of dependencies you must provide, and review points where your security team signs off. Confirm that a staging environment is ready before the schedule starts.
What does a Zitadel hardening engagement need from our team?
The work needs named people and access, and missing items are the most common cause of delay. Plan for: named administrators for Zitadel and the underlying platform who can make decisions during the engagement, access to your secret store so the master key and database credentials are handled there, control of certificates and DNS for public hostnames, database administration rights or a DBA who can review PostgreSQL roles, TLS and backups, a staging environment that mirrors production, and a decision-maker who can approve MFA, passkey and session policies. Also name a contact for each connected identity provider. Agree these responsibilities in writing so the scope reflects what your team actually supplies.
Can our own team harden a self-hosted Zitadel instance alone?
Yes. Your team can work from the official Zitadel documentation and internal security skills, and many teams do. The trade-off is time and review depth. Internal staff usually work on hardening alongside production duties, so configuration may take longer and is less likely to receive an independent second review. Outside help adds a structured review of master key handling, TLS, database credentials, admin access, MFA and audit trail settings, along with a written record of what changed. If you proceed in-house, assign an owner for each area, build a staging test plan, document every policy decision and schedule a peer review before go-live. Confirm with your auditors whether the baseline you produce meets your regulatory obligations, since that judgment belongs to your organization.
Does Zitadel's Enterprise plan change what hardening work we need?
Zitadel lists an Enterprise plan with custom pricing for self-hosted or cloud deployments. Zitadel states that this plan offers custom support agreements and technical account management, and it lists ISO 27001, SOC 2 Type II and OpenID certification on its pricing page. Those items concern the vendor's support relationship and its own certifications. They do not replace hardening of your instance, which covers your key handling, network exposure, database access and policy choices. Confirm current plan contents, support terms and certification status directly on Zitadel's pricing page before you decide, because these details can change. A support agreement can simplify vendor escalation, but your hardening scope and evidence still need to be defined in writing.
Does DeployOpen issue compliance certificates for our Zitadel setup?
No. DeployOpen prepares controls, configuration and evidence for compliance assessments, but it does not issue audit reports, attestations or certifications. Independent auditors and certification bodies perform those assessments. For a Zitadel deployment, the useful output is a documented baseline: how the master key is stored and rotated, how TLS and database credentials are managed, who holds admin roles, how MFA and passkey policies are set and how audit trail review is performed. Ask your auditor which control evidence they expect, then agree on those items in the written scope. Your organization remains responsible for its certifications and for deciding whether its Zitadel setup meets its obligations.
What should an engineer check first when hardening Zitadel?
Start with the items that protect the most sensitive material: the master key, the database connection and the admin accounts. Confirm the master key is generated with sufficient entropy, stored in a secret store and kept out of configuration files and images, and that you have a tested recovery procedure. Check that TLS terminates with valid certificates, that the database role follows least privilege and that credentials are rotated on a defined schedule. Verify that admin access requires MFA, that the console is not exposed more widely than needed and that policies enforce the MFA and passkey settings you intend. Finally, confirm audit events are collected centrally and that someone reviews them on a schedule. Verify each setting against the current Zitadel documentation for your version.
How DeployOpen scopes, hardens and hands over Zitadel security work
DeployOpen approaches Zitadel security hardening as a fixed-scope piece of work inside your own infrastructure, whether that is a Linux host, Docker Compose or a Kubernetes cluster. We agree in writing which settings, controls and evidence are in scope before any change is made, then work through them in your environment and hand over documentation your team can run.
How we scope
- We review your current deployment method, Zitadel version and PostgreSQL setup before agreeing what the written scope covers.
- We confirm which instances, organizations and projects exist, and which admin roles and identity providers must be hardened.
- We agree the handling of the master key, TLS, database credentials, MFA and passkey policies, and audit log review as named deliverables.
How we build
- We apply hardening changes in a non-production copy first, so each setting can be tested before it reaches production.
- We check TLS configuration, secret storage and database credential scope against your agreed baseline and record each result.
- We test MFA and passkey policies with representative user and admin sign-ins, including the password fallback path you choose to keep.
How we hand over
- You receive a written record of each hardened setting, the reason for it and how to verify it after future changes.
- We document the audit trail review steps, the events to monitor and who in your team owns each review.
- We walk your operators through the procedures for rotating the master key and database credentials without downtime planning gaps.
How we support
- Ongoing support, upgrades and continuous testing are available as a retainer, scoped separately from the hardening work.
- Retainer scope is agreed in writing, so you can decide which upgrade checks and periodic reviews your team will keep in-house.
- Before any Zitadel upgrade, we can re-run the agreed hardening checks against the new release to confirm settings still hold.

