Next Zitadel preview: ship login changes like code
Changing a login is risky. One wrong setting and real users can't sign in, and often you find out from them. In the Zitadel preview, a login change now ships like any other change to your app: open a pull request, try it on a preview URL, check what it does to your existing users, deploy it, and undo it with one command if it breaks. Your schemas, login flows, branding and policies live in .zitadel/ in your repo, and zitadel deploy is the one way they reach your users.
Earlier posts in the series are under nextgen on the blog.
How do I see what a login change will do before I ship it?
Say you switch sign-in from username to email. Some of your users never added an email, and after the deploy they can't sign in. Run a dry run first:
npx @zitadel/cli@latest deploy --dry-run
It builds .zitadel/ into a release and shows exactly what would change, without touching anything. Then it does something a code review can't: it checks your actual users. In the email example, it names the schema and tells you how many users have no email, before any of them is locked out. It warns the same way when:
- a flow drops a sign-in method that some users rely on, such as passkeys for users who signed up with only a passkey,
- users with an SSO link would end up on a schema no flow uses any more.
Can I try a login change on a pull request first?
Yes. Every pull request can get its own login, so you test the real flow before any user sees it. Run zitadel preview in a Vercel or Netlify preview build, and it makes the same release deploy would build live only on that pull request's preview URLs, for as long as you set with --ttl. Click through the new flow, share the link with a teammate, and leave production alone until you merge and run zitadel deploy.
Variables hold a separate preview value, so a preview can point at a test identity provider while production keeps the real one.
How do I undo a bad deploy?
One command:
npx @zitadel/cli@latest deployment rollback
Without an ID, it undoes the last deploy by bringing back the previous release, with the variable values it used. Your users keep their data and their schema revision, because a rollback only changes configuration. That makes undo something you can reach for without a second thought. Got a release with a broken flow you never want to see again? zitadel release revoke <id> makes sure it can't come back.
Coding agents run these commands too, so every command that deletes, revokes or rolls back now asks first. An agent in a non-interactive shell gets the question back instead of a surprise, and only goes ahead with --force.
Why did that sign-in fail, and who changed the flow?
When a user can't sign in, or a flow changed and nobody knows who changed it, open Logs in the console. It shows everything your project did, newest first: sign-ins, sessions, user and configuration changes, and every API request. Choose a view for audit events, API requests or both, then zoom in:
- By time, from the last 30 minutes to 14 days, or a custom range.
- By type, with Only failures for failed events and Only failed requests for API calls that answered with a 4xx or 5xx.
- By what you paste into the search: an ID, an operation such as
createUser, or a filter likeactor:orresource:. Each one becomes a chip you can remove. - By you: My activity shows only what you did.
Open an event to see its details in a drawer, and step through the list with the arrow keys or j and k. An API request lists the events it caused, in the order they happened. Turn on Live and watch events arrive as they happen, which is the best way to watch a deploy land. Export copies the events or downloads them as JSON or CSV.
The same events are available through GET /events in the API and zitadel events list in the CLI, so a script or a coding agent can ask the same questions.
What else is new?
- Any OpenID Connect provider for sign-in, not only Google.
zitadel auth-method sso enableasks for a custom provider's settings. - A console you can work in. Manage users through forms built from your schema, move a user to a newer schema revision, and see deployments, releases and the policy each one pins.
- Password policies as code, with
zitadel policies testto run test cases against a policy before you deploy it. zitadel upgrademoves your project's@zitadel/*packages to the latest release and shows the breaking changes on the way.zitadel skills addgives Claude Code, Cursor, Copilot, Codex and other coding agents the skills that match your CLI version.
Every change is in the changelog.
What isn't there yet?
This is still a preview, so a release can include breaking changes.
Zitadel can't yet act as the OpenID Connect and OAuth provider for your own applications. That's what we're building next. Until then, the login is built into your app: the components render sign-in and sign-up directly in your own pages, and your app uses Zitadel's sessions through the SDKs.
The preview also doesn't have every feature of Zitadel v4 yet, such as SAML and SCIM. If you rely on them, you can keep using Zitadel v4.
Try it
Three commands in a new folder, with Node.js 24 or newer, and you have an app with a working login:
npx @zitadel/cli@latest start
npx @zitadel/cli@latest setup --framework next --server local
npm run dev
Then change something in .zitadel/, try to lock yourself out on purpose, and run deploy --dry-run to see it catch you. The deploy guide covers the rest.
Tell us where it still hurts. Open an issue or a discussion on GitHub, or show us what you're building in the nextgen channel on Discord.
