Link the YouTube walkthrough at the end of the quickstart page for users
who prefer watching over reading.
Co-authored-by: Rajat Singh <rajat@zitadel.com>
The changelog page on zitadel.com was removed for being unmaintained,
leaving the docs sidebar link 404ing.
Co-authored-by: Rajat Singh <rajat@zitadel.com>
# Which Problems Are Solved
- The **Harden secrets** section of the Docker Compose guide lists
commands for the masterkey and the two database passwords, but never
mentions the **initial admin user password**.
- Setting `ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD` to a value that
does not meet the default password complexity policy fails the initial
setup with a `_password_complexity_model` error, and the requirements
were not documented anywhere near the other secrets.
# How the Problems Are Solved
- Adds a short note directly below the secret-generation commands
documenting the initial admin password: the default (`Password1!` /
`zitadel-admin@zitadel.localhost`), how to override it via
`ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORD`, and the default complexity
requirements (min 8 chars, upper + lower + number + symbol).
- Links to the [Password
Complexity](/guides/manage/console/default-settings#password-complexity)
policy docs and notes that the variable only applies during initial
setup.
# Additional Changes
None.
# Additional Context
- Reported by a self-hosting user (TrueNAS + Ansible) who hit repeated
setup errors because the initial admin password complexity requirement
was not documented alongside the masterkey/DB password commands.
## Summary
- Add a new guide documenting how to let users delete their own account
via the User v2 API's `DeleteUser` endpoint, gated by the
`user.self.delete` permission (granted via `ORG_USER_SELF_MANAGER`)
- Link the new guide from the self-service concepts page and sidebar
- Add the `ORG_USER_SELF_MANAGER` role to the administrators reference
table
## Test plan
- [x] Verified the new and updated pages render correctly in local dev
(`pnpm dev`)
replaces #12455 and #12457 (branch got renamed from
`docs/human-pat-clarification`, which auto-closed #12457).
Co-authored-by: Rajat Singh <rajat@zitadel.com>
# Which Problems Are Solved
In Zitadel's append-only event-sourced architecture, the
`eventstore.events2` table grows indefinitely. PostgreSQL's default
autovacuum uses a percentage-based scale factor, so as the table grows,
the number of changed rows required to trigger a `VACUUM` or `ANALYZE`
drifts towards infinity. Without regular vacuums, the table's Visibility
Map becomes stale, disabling fast Index-Only Scans and forcing expensive
heap reads. Without regular analyzes, query planner statistics become
stale, leading to suboptimal execution plans.
This causes eventstore operations to progressively degrade as `events2`
grows, even without CPU, memory, or I/O saturation. A manual `VACUUM
ANALYZE` immediately restores performance, confirming the root cause.
- If `Eventstore.Autovacuum` is left at its default, `events2` keeps
using PostgreSQL's default, percentage-based autovacuum/autoanalyze
scale factors, which become impractically infrequent on large tables.
- There was previously no supported way to apply static, table-level
autovacuum tuning to `events2` through Zitadel's own configuration/setup
process.
# How the Problems Are Solved
- Added an `Eventstore.Autovacuum` runtime configuration block to
`cmd/defaults.yaml` (disabled by default):
```yaml
Eventstore:
Autovacuum:
Enabled: false # ZITADEL_EVENTSTORE_AUTOVACUUM_ENABLED
VacuumThreshold: 50000 # ZITADEL_EVENTSTORE_AUTOVACUUM_VACUUMTHRESHOLD
AnalyzeThreshold: 50000 # ZITADEL_EVENTSTORE_AUTOVACUUM_ANALYZETHRESHOLD
```
- Added a repeatable `zitadel setup` migration step
(`cmd/setup/eventstore_autovacuum.go`) that:
- When `Enabled: true`, disables the percentage-based
`autovacuum_vacuum_scale_factor`, `autovacuum_analyze_scale_factor`, and
`autovacuum_vacuum_insert_scale_factor` on `eventstore.events2`, and
applies static thresholds (`autovacuum_vacuum_insert_threshold`,
`autovacuum_vacuum_threshold`, `autovacuum_analyze_threshold`) from the
config instead.
- When `Enabled: false`, resets those storage parameters on
`eventstore.events2` back to the cluster defaults.
- Implements `Repeatable.Check()` so the step only re-runs when the
configuration actually changed since the last `zitadel setup` run.
- Added documentation in the new "Performance tuning" page.
# Additional Changes
- Move the projection documentation into performance tuning page
- Expand and update the projection documentation to the latest state in
zitadel. (contained some stale information)
# Additional Context
Several other issues describe read-performance symptoms consistent with
this same root cause (stale `events2` visibility map / planner
statistics at scale, without resource saturation). Since this PR
addresses the shared root cause:
- Closes#12448
- Closes#10754
- Closes#10260
- Closes#8585
- Closes#9239
---
_Generated by [Claude
Code](https://claude.ai/code/session_01HoKvEY7niCVgLCz7CajBwW)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Closes#11369
# Which Problems Are Solved
During SSO login with an external IdP, Actions v2 lets you manipulate
the `RetrieveIdentityProviderIntent` response to shape the user that
ZITADEL creates or updates. There was an inconsistency between the two
flows:
- **First login (user does not exist):** the response carried an
`addHumanUser` object (mirroring the deprecated `AddHumanUser` API),
which **does** allow setting user `metadata`.
- **Subsequent logins (user exists):** the response carried an
`updateHumanUser` object (mirroring the deprecated `UpdateHumanUser`
API), which does **not** support metadata.
As a result, actions could set metadata when creating a user but not
when updating one. Customers doing SSO attribute mapping had to make a
separate `SetUserMetadata` call on every subsequent login — extra
latency and a non-atomic update. The proto/backend already gained a
non-deprecated `user_action` oneof (`create_user` → `CreateUserRequest`,
`update_user` → `UpdateUserRequest`, both supporting metadata), but the
login app was still reading the deprecated flat fields, so the new
capability was unreachable from the frontend.
# How the Problems Are Solved
Migrate the login app's IDP intent handler to consume the new
`user_action` oneof, with a fallback to the deprecated fields so older
API responses keep working during the transition.
- **`zitadel.ts`** — added `createUser` / `updateUser` client wrappers
calling the non-deprecated `UserService.CreateUser` /
`UserService.UpdateUser` endpoints.
- **`idp-intent.ts`** — added three helpers, each preferring
`user_action` and falling back to `add_human_user` /
`update_human_user`:
- `resolveCreateUser` — flat read view for org resolution,
required-field checks, and registration-form pre-fill.
- `buildCreateUserRequest` — passes the action's `CreateUserRequest`
through and injects the resolved `organizationId`; maps the deprecated
flat payload into the nested shape on fallback.
- `buildUpdateUserRequest` — builds an `UpdateUserRequest` **including
metadata** (the fix); deliberately syncs only
profile/email/phone/metadata (not username) to preserve existing
auto-update behavior and avoid invalidating sessions.
- Rewired all handlers (`handleUserExists`, `handleAutoLinking`,
`handleAutoCreation`, `handleManualCreation`,
`resolveOrganizationForUser`) to use these, and switched auto-create to
read `CreateUserResponse.id`.
- **Tests** — updated mocks/assertions to the new request shapes and
added two cases exercising the `user_action` oneof with metadata (create
+ update). 817/817 login unit tests pass; no new type errors.
# Additional Changes
Updated the Actions v2 guide
`guides/integrate/actions/testing-response-manipulation.mdx` (the
unreleased/`latest` docs) to reflect the new response shape:
- Go handler example now manipulates `resp.GetCreateUser()` /
`resp.GetUpdateUser()` and appends `user.Metadata`, demonstrating
metadata on both flows.
- Both JSON payloads switched from `addHumanUser` to the nested
`createUser` shape (`human.profile`, `human.email`, `human.idpLinks`,
top-level `metadata`).
- Added a Callout explaining first-login → `createUser` vs.
existing-user → `updateUser`, that both support metadata, and that
`addHumanUser`/`updateHumanUser` are deprecated.
- Updated the claim-mapping debugging section to the new
`createUser.human.profile.givenName` path.
Versioned snapshots (`v4.12`/`v4.13`/`v4.14`) were intentionally left
unchanged, as they document releases where the old API was correct.
---------
Co-authored-by: gayathri <66356931+grvijayan@users.noreply.github.com>
<!--
Please inform yourself about the contribution guidelines on submitting a
PR here:
https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr.
Take note of how PR/commit titles should be written and replace the
template texts in the sections below. Don't remove any of the sections.
It is important that the commit history clearly shows what is changed
and why.
Important: By submitting a contribution you agree to the terms from our
Licensing Policy as described here:
https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions.
-->
# Which Problems Are Solved
- Operators upgrading from ZITADEL v3 to v4 lacked a clear, docs-backed
upgrade path covering web keys (A-10017), Login V1 vs Login V2
expectations, and post-upgrade options.
- There was no standalone guide for adopting Login V2 after already
running on v4.
- Related ops/docs pages did not consistently point readers to the
upgrade and Login V2 adoption material.
- Kubernetes/Helm operators upgrading to a chart that ships ZITADEL v4
had no ops-page section linking the advisory, upgrade guide, optional
Login V2 deferral (`login.enabled: false`), and chart README upgrade
notes.
# How the Problems Are Solved
- Adds technical advisory **A-10017** documenting OIDC web key staging
requirements before upgrading to v4.
- Adds an **upgrade-v3-to-v4** guide with the recommended upgrade path
(Login V1 remains supported; Login V2 is optional at upgrade time).
- Adds a **v4-only adopt-login-v2** guide for teams adopting Login V2
later, with steps and caveats separate from the version upgrade.
- Adds an **Upgrading to ZITADEL v4** subsection under
`self-hosting/deploy/kubernetes/operations.mdx` that links to A-10017,
the upgrade guide, Adopt Login V2, notes `login.enabled: false` when not
adopting Login V2 yet, and points to the [Helm chart
README](https://github.com/zitadel/zitadel-charts/blob/main/charts/zitadel/README.md)
for chart-specific breaking changes.
# Additional Changes
- Registers new docs in the sidebar and wires Related / cross-links from
upgrade and ops pages so the advisory and guides are discoverable
together.
- Aligns language so upgrade vs. Login V2 adoption are clearly separated
concerns.
- Light cross-link updates on troubleshooting / updating-scaling /
login-client pages where related.
# Additional Context
- Related: A-10017 (web keys advisory)
- Docs paths introduced/updated:
- `apps/docs/content/support/advisory/a10017.mdx`
- `apps/docs/content/self-hosting/manage/upgrade-v3-to-v4.mdx`
- `apps/docs/content/self-hosting/manage/adopt-login-v2.mdx`
- `apps/docs/content/self-hosting/deploy/kubernetes/operations.mdx` (new
"Upgrading to ZITADEL v4" section)
- Sidebar and Related / cross-links
- Companion Helm chart README PR:
https://github.com/zitadel/zitadel-charts/pull/608
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
## Summary
- V2 has already reached end of support; the roadmap page previously
implied end-of-support timelines for V2 and V3 were both still
forthcoming.
- Updated copy to state V2's end-of-support status plainly and note that
V3's timeline and migration guidance will be published soon.
## Test plan
- [x] Verified the updated sentence renders correctly in
`apps/docs/content/product/roadmap.mdx`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Elina Sokolovska <elinasokolovska@Elinas-MacBook-Air.local>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
## Which Problems Are Solved
There is currently a knowledge gap in the documentation where users are
unclear on if or why human accounts cannot have Personal Access Tokens
(PATs), which has led to confusion in community channels like Discord
and GitHub.
## How the Problems Are Solved
Clarified that human PATs are currently not supported in the Personal
Access Token documentation and added a direct link to GitHub Issue
#10915 so users can track and upvote this capability.
## Additional Changes
None
## Additional Context
None
---------
Signed-off-by: Rajat Singh <rajat@zitadel.com>
Co-authored-by: Rajat Singh <rajat@zitadel.com>
## Which Problems Are Solved
The callout added in #12335 included a link to a GitHub discussion which
will become outdated and difficult to maintain.
## How the Problems Are Solved
Removes the discussion link from the ZITADEL Cloud bullet point in the
TOTP issuer callout, keeping the rest of the callout intact.
Co-authored-by: Rajat Singh <rajat@zitadel.com>
# Which Problems Are Solved
- No documentation explained that the TOTP issuer name defaults to
"ZITADEL" and is not derived from the domain
- No documentation clarified how to change it on self-hosted (env var
only, Helm values don't work)
- No documentation communicated that it is not configurable on ZITADEL
Cloud
# How the Problems Are Solved
- Adds a callout in the MFA section of the default settings page
covering both self-hosted
(ZITADEL_SYSTEMDEFAULTS_MULTIFACTORS_OTP_ISSUER) and cloud (not
configurable, discussion link)
# Additional Changes
None
# Additional Context
- https://github.com/zitadel/zitadel/discussions/5453
Signed-off-by: Rajat Singh <rajat@zitadel.com>
Co-authored-by: Rajat Singh <rajat@zitadel.com>
## Summary
- Update the description frontmatter and reword "next generation" to
"next iteration" throughout
- Add a "What this means for existing customers" subsection after the
disclaimer, before the Strategic Roadmap section
- Convert `### **Strategic Investments**` / `### **Customer Outcomes**`
subheadings to bold text so they no longer appear in the TOC
- Rename the closing section to "Migration and Adoption" with updated
content
## Test plan
- [x] Diffed against source content to confirm all requested sections
match
- [x] Verified no remaining "next generation" occurrences
---------
Co-authored-by: Elina Sokolovska <elinasokolovska@Elinas-MacBook-Air.local>
Co-authored-by: Florian Forster <florian@zitadel.com>
Automatically generated PR resolving Knowledge Gap ID 34.
**Thread ID:** manual-1783339162398
**Action:** CREATE
**New File:** `content/docs/drafts/gap-manual-1783339162398.mdx`
### AI Summary
> Add a user migration guide for firebase to Zitadel
### Human Reviewer Instructions
> Firebase to Zitadel Migration Summary
> The Blocker: Incompatible Password Hashes
>
> Firebase uses a proprietary, modified scrypt algorithm requiring
project-specific keys.
>
> Zitadel supports standard algorithms but lacks a verifier for
Firebase's custom format.
>
> Result: Passwords cannot be directly imported. Firebase hashes must be
discarded.
>
> Strategy 1: Bulk Import & Password Reset (Standard)
> Requires users to set a new password on their first login.
>
> Export: Run firebase auth:export users.json --format=json.
>
> Map: Convert Firebase fields (e.g., localId) to Zitadel's schema.
>
> Import to Zitadel: Call the Zitadel import API.
>
> Action: Omit the hashedPassword object entirely.
>
> Action: Include "passwordChangeRequired": true in the JSON payload to
trigger a reset flow via email or login prompt.
>
> Strategy 2: Just-In-Time (JIT) Migration (Seamless)
> Migrates users transparently behind the scenes during an active grace
period.
>
> Intercept Login: Your backend captures the plain-text password during
login.
>
> Verify: Backend POSTs credentials to Firebase Auth REST API:
>
>
https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=[WEB_API_KEY]
>
> Migrate to Zitadel:
>
> If Valid (200 OK): Create the user in Zitadel immediately using the
plain-text password (Zitadel will natively hash it).
>
> If Invalid (400): Reject login or check if the user is already in
Zitadel.
>
> Sunset: After the grace period ends, migrate remaining inactive users
using Strategy 1.
> (Note: Do not log plain-text passwords and strictly enforce HTTPS
during this phase).
---
🤖 **Need adjustments?**
Leave a comment below and tag **@zitadel-knowledge-bot** with your
requested changes, and I will automatically update the files and push a
new commit!
---------
Co-authored-by: zitadel-knowledge-bot[bot] <296006658+zitadel-knowledge-bot[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
# Which Problems Are Solved
- npm dependencies across the monorepo are behind current patch/minor
releases.
- Transitive dependencies are pinned to older versions by parent
packages (karma, nx, @changesets/cli, etc.).
- Console build fails after the Angular toolchain update because
`angular.json` references assets outside the workspace root.
# How the Problems Are Solved
- Bumps `@angular/*` to `^21.2.17` in console.
- Bumps `js-yaml` to `^4.2.0` in docs.
- Bumps `concurrently` to `^10.0.3` in login.
- Adds pnpm overrides for transitive deps that cannot be bumped directly
(ws, undici, minimatch, esbuild, dompurify, qs, and others).
# Additional Changes
- Removes 10 overrides that are no longer needed after parent packages
resolve to newer versions.
- Updates 4 existing overrides (`tar`, `js-yaml`, `dompurify`,
`brace-expansion`) to match current upstream ranges.
- 2 low-severity findings remain via the abandoned `raw-loader` package
in docs (peer dep resolution; no upstream fix without replacing
`raw-loader`).
- Fixes console build: replaced the `angular.json` asset glob
`../apps/docs/public/img/tech` with a `prebuild` script that copies tech
images into `src/assets/docs/img/tech`. **Verify at runtime that tech
images on project grant / integration pages still load.**
# Additional Context
- Overrides remain where parent packages still pin older transitive
versions.
- The `angular.json` asset path issue predates this PR (not introduced
by the Angular bump).
---------
Co-authored-by: Livio Spring <9405495+livio-a@users.noreply.github.com>
Removes the release cycle page and sidebar entry. Replaces the roadmap
page with updated strategic roadmap content and renames its sidebar
label to Roadmap.
---------
Co-authored-by: Elina Sokolovska <elinasokolovska@Elinas-MacBook-Air.local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Fabienne Bühler <fabienne@zitadel.com>
# Which Problems Are Solved
- The documentation had no guidance for debugging auto-user-creation
failures caused by unexpected or missing claims from an external IdP,
leaving users without a path forward when they see a
`SetHumanProfile.GivenName` validation error during OIDC login.
# How the Problems Are Solved
- Adds a troubleshooting section to the Actions V2 response manipulation
guide explaining how to use the `RetrieveIdentityProviderIntent` webhook
to inspect `rawInformation` and identify claim key mismatches from the
external IdP.
# Additional Changes
- None
Signed-off-by: Rajat Singh <rajat@zitadel.com>
Co-authored-by: Rajat Singh <rajat@zitadel.com>
# Which Problems Are Solved
Zitadel exposes the secrets generator configuration through its admin
api. This allows instance admins to manage them on their own and they
can create overwrite the system / runtime defaults (incl. expiration).
This very much needed in multi-instance scenarios such as zitadel.cloud.
Currently the invite code configuration was not manageable through the
API, but only runtime config.
# How the Problems Are Solved
- added the `invite_code` type to the API allowing it to be set and
retrieved.
- added the type to console's management list
- added the type to be stored on instance setup
- change the `GetSecretGenerator` endpoint to fall back to the runtime
config if no config is stored on the instance itself
- ensure the `length` and at least one charset is enabled, return an
error otherwise
- expiry is not enforced, so 0 allows codes with no expiry (current
state)
# Additional Changes
None
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/10474
Automatically generated PR targeting 1 files.
**Thread ID:** 1517531035175354430
**Action:** UPDATE
**AI Summary:**
> Documentation does not explain what happens when users bookmark the
login page or access ZITADEL without an OIDC flow, particularly
regarding redirect behavior and the purpose of organization Default
Redirect URI settings.
Co-authored-by: zitadel-knowledge-bot[bot] <296006658+zitadel-knowledge-bot[bot]@users.noreply.github.com>
Automatically generated PR targeting 1 files.
**Thread ID:** 1512031509387673610
**Action:** UPDATE
**AI Summary:**
> The documentation lacks clear explanation of how the 'Use new login
UI' checkbox and 'Custom base URL for the new Login UI' field work
together, including step-by-step configuration and troubleshooting
guidance.
---------
Co-authored-by: zitadel-knowledge-bot[bot] <296006658+zitadel-knowledge-bot[bot]@users.noreply.github.com>
Co-authored-by: fcoppede <fcoppede@gmail.com>
Automatically generated PR targeting 1 files.
**Thread ID:** manual-1782237446658
**Action:** UPDATE
**AI Summary:**
> Need to add a note on this page to encourage users with active
subscriptions to link their github and Discord account because that will
help github issues get higher priority and discord threads as well
Co-authored-by: zitadel-knowledge-bot[bot] <296006658+zitadel-knowledge-bot[bot]@users.noreply.github.com>
<!--
Please inform yourself about the contribution guidelines on submitting a
PR here:
https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr.
Take note of how PR/commit titles should be written and replace the
template texts in the sections below. Don't remove any of the sections.
It is important that the commit history clearly shows what is changed
and why.
Important: By submitting a contribution you agree to the terms from our
Licensing Policy as described here:
https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions.
-->
# Which Problems Are Solved
The projects setting texts and sceenshot where outdated.
# How the Problems Are Solved
Update the text and screenshot.
# Additional Changes
* Rewording
* Lockout warning component
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
# Which Problems Are Solved
Pages in `apps/docs` that embed source from GitHub via the Docusaurus
convention
````
```js reference
https://github.com/zitadel/actions/blob/main/examples/org_metadata_claim.js
```
````
stopped working after the migration from Docusaurus to fumadocs. The old
`docusaurus-theme-github-codeblock` plugin used to fetch the file and
render it; fumadocs has no support for that meta, so the page rendered
the raw URL as plain code-block text. Visible at
`/docs/apis/actions/code-examples` and 16 other pages.
# How the Problems Are Solved
- Converted every ```` ```<lang> reference\n<URL>\n``` ```` block (46
total across 17 `.mdx` files) to the native fumadocs JSX form:
`<GithubCodeBlock url="<URL>" />`. The existing `<details>`/`<summary>`
collapsibles around blocks are kept — they're an authoring choice, not
part of the rendering bug.
- Updated `apps/docs/components/github-code-block.tsx` to render via
`DynamicCodeBlock` from `fumadocs-ui/components/dynamic-codeblock`
(proper shiki highlighting) instead of raw `CodeBlock` + `Pre` (which
produced unhighlighted output). Also fixed language detection so a URL
hash like `#L10-L20` no longer pollutes the language token.
- Registered `GithubCodeBlock` globally in
`apps/docs/mdx-components.tsx`, matching how every other shared
component (`APIPage`, `Callout`, `Tab/Tabs`, `Step/Steps`, `Admonition`,
`TerminologyUpdate`) is exposed. MDX files no longer need a local
`import`.
# Additional Changes
- Normalized the two MDX files that were already using the JSX form
(`examples/secure-api/python-django.mdx`,
`examples/secure-api/java-spring.mdx`): removed their now-redundant
local `import { GithubCodeBlock }` and rewrote 9 long-form
`<GithubCodeBlock url="..."></GithubCodeBlock>` tags to self-closing for
consistency.
# Additional Context
Verified locally with `pnpm --filter @zitadel/docs dev`:
- `/docs/apis/actions/code-examples` — 20 shiki-highlighted code blocks
rendered inside the `<details>` collapsibles (was 0).
- `/docs/apis/openidoauth/claims` — line-range hashes (`#L9-L11`)
honored.
- `/docs/examples/login/flutter` — mixed languages (xml/dart/html)
detected and highlighted.
- `/docs/guides/integrate/external-audit-log` — edge case of fenced
reference indented inside a numbered list also converted and rendered.
Greps:
- `^[ \t]*\`\`\`[a-zA-Z0-9]+ reference` in `apps/docs/content/**/*.mdx`
→ 0 matches.
- `<GithubCodeBlock url="` in `apps/docs/content/**/*.mdx` → 55 matches.
- `from '@/components/github-code-block'` in
`apps/docs/content/**/*.mdx` → 0 matches.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Description
This PR updates the Kubernetes deployment documentation to address user
feedback regarding our routing instructions. A user noted that standard
`Ingress` is becoming outdated and requested configuration examples for
the modern Gateway API.
To support both existing and modern clusters, I have updated the guide
to provide two clear pathways for exposing ZITADEL.
## Changes Included
* **Prerequisites updated:** Mentioned Gateway API controllers alongside
standard Ingress controllers.
* **Refactored Stage 2 (Production):** Split the routing configuration
into "Option A: Standard Ingress" and "Option B: Gateway API".
* **Added YAML example:** Provided a sample `HTTPRoute` resource to
route traffic to the `zitadel` and `zitadel-login` backend services.
* **Terminology updates:** Broadened terms like "Ingress" to "Routing"
or "Routing controller" where applicable.
<!--
Please inform yourself about the contribution guidelines on submitting a
PR here:
https://github.com/zitadel/zitadel/blob/main/CONTRIBUTING.md#submit-a-pull-request-pr.
Take note of how PR/commit titles should be written and replace the
template texts in the sections below. Don't remove any of the sections.
It is important that the commit history clearly shows what is changed
and why.
Important: By submitting a contribution you agree to the terms from our
Licensing Policy as described here:
https://github.com/zitadel/zitadel/blob/main/LICENSING.md#community-contributions.
-->
# Which Problems Are Solved
Outdated depdencies
# How the Problems Are Solved
This PR mostly just updates our NPM depdencies to the newest feature
releases.
The UUID package was update to version 14, the changelog only includes
changes to the supported node version.
# Additional Changes
Replace tsx for some scripts in the docs.
---------
Co-authored-by: Livio Spring <9405495+livio-a@users.noreply.github.com>
Co-authored-by: Max Peintner <max@caos.ch>
## Summary
- Switch the docs catch-all route to full static generation and prebuild
both latest and versioned docs paths.
- Prebuild OG images for all docs pages, make sitemap and LLM export
static, and remove nondeterministic sitemap timestamps.
- Reduce build-time overhead by memoizing docs sidebar trees and
skipping processed markdown generation for versioned docs.
## Testing
- `pnpm nx run @zitadel/docs:build`
- `pnpm nx run @zitadel/docs:lint`
- `pnpm nx run @zitadel/docs:check-types`
- Verified the prerender manifest contains 8,816 prerendered routes,
3,293 versioned docs routes, 4,406 OG routes, and zero revalidating docs
routes.
This PR updates the "Private Key JWT Auth for Service Accounts"
documentation to explicitly clarify the relationship between the exp
(expiration) and iat (issued at) claims.
Previously, the documentation didn't make it clear what happens if a
developer sets an exp claim far into the future. This update clarifies
that while the exp value is strictly enforced, the iat claim takes
precedence if the exp is set to more than 1 hour in the future (i.e.,
ZITADEL will reject the JWT once the iat is older than 1 hour,
regardless of the exp time).
**Changes included:**
Updated the description of the exp claim in the JWT payload section to
highlight the 1-hour iat limit enforcement.
# Which Problems Are Solved
The Vercel `docs` project generated ~64M ISR writes over 30 days (99.5%
of ISR writes across all projects, ~\$258/month).
Root causes in the Next.js 16 docs app:
- `apps/docs/app/[[...slug]]/page.tsx` had `dynamicParams = true` +
`revalidate = 3600`. Bot traffic hitting unknown URLs (`/docs/wp-admin`,
`/docs/.env`, fuzzed paths) got rendered via \`notFound()\`, and the 404
response was cached as an ISR entry — 1 write per unique bad URL. Known
pages were also rewritten hourly for no reason since content only
changes on deploy.
- `apps/docs/app/og/docs/[...slug]/route.tsx` had `revalidate = false` +
empty `generateStaticParams()` + implicit `dynamicParams = true`. Every
unique OG URL (including bot probes) was cached forever — writes
accumulated permanently.
# How the Problems Are Solved
Switch the docs routes to pure SSG (content is static and only changes
on deploy, so ISR provides no value):
- `app/[[...slug]]/page.tsx`: `dynamicParams = false`, `revalidate =
false`, `dynamic = 'force-static'`. Unknown URLs now return a static 404
at the CDN — no function invocation, no ISR write. All 390 pages from
`source.generateParams()` are still pre-rendered.
- `app/og/docs/[...slug]/route.tsx`: `generateStaticParams()` now
returns all 390 pages via the existing `getPageImage(page).segments`
helper, so every OG image is pre-built as a static asset. `dynamicParams
= false` + `dynamic = 'force-static'` locks it down.
- `app/llms-full.txt/route.ts`: added `dynamic = 'force-static'` as a
safety net (already `revalidate = false`, single URL).
The tradeoff is longer CI builds (~40s–2min for 390 OG image
generations, paid on every preview deploy) in exchange for eliminating
~\$258/month in ISR writes plus associated function invocations and CPU
time.
# Additional Changes
None.
# Additional Context
- No changes to `next.config.mjs`, `vercel.json`, or redirects.
- Existing `apps/docs/redirects.json` (3,261 entries) covers legacy URLs
so `dynamicParams = false` won't 404 moved pages linked from elsewhere.
- Versioned routes: `content/versions.json` and `v*/` folders don't
exist yet. When versioning is activated, `generateStaticParams()` in
both files must also include `versionSource.generateParams()` —
otherwise versioned URLs will 404 under `dynamicParams = false`.
## Test plan
- [ ] CI build succeeds (expect modest build-time increase for OG
pre-generation)
- [ ] Inspect `apps/docs/.next/prerender-manifest.json` — all 390 doc
routes + 390 OG routes listed with `initialRevalidateSeconds: false`
- [ ] Local smoke: `/docs` → 200, `/docs/wp-admin` → 404 (static, no
function), `/docs/og/docs/guides/start/image.png` → PNG,
`/docs/og/docs/bogus/image.png` → 404
- [ ] Post-deploy: Vercel **ISR Writes** metric drops to near-zero
within 24h
- [ ] Post-deploy: Vercel **Function Invocations** for `/og/docs/*` drop
to zero
- [ ] Verify no legitimate docs pages 404 (cross-check logs against
`apps/docs/app/sitemap.ts`)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Which Problems Are Solved
As part of https://github.com/zitadel/zitadel/issues/11917 we want to
introduce error slugs so (API) clients can rely on stable,
machine-readable errors and act accordingly.
# How the Problems Are Solved
- Added a `NewSlug` helper function in the domain package.
- Added `ErrorDetails` to the `ZitadelError`
- Added an `zitadel.error.v2.ErrorDetail` proto message
- Updated the connectRPC error interceptor to map new slug based errors
to the new `ErrorDetail`
- Defined some common slugs and error functions like internal errors
- Defined (session) specific slugs used in the `DeleteSession` and
`CheckUser` functions and replaced old implementations
- Updated integration tests to check specific errors if the relation
database feature is enabled
- Updated doc and guideline to reflect the latest changes and decisions
- Updated DeleteSession endpoint API to list possible slugs
# Additional Changes
None
# Additional Context
- closes#11957
---------
Co-authored-by: Wim Van Laer <wim+github@zitadel.com>
# Which Problems Are Solved
After merging #11968 and rechecking the dependabot alerts there are
still some issues leftover.
# How the Problems Are Solved
This pr makes overrides for vulnerable transitive depdencies to force
update to safe versions.
It also upgrades the next.js version in the docs and I also ran `pnpm
update` once more.
# Additional Changes
Removed the mochaawesome dependency is this is not really needed and
seems unmaintained.
# Additional Context
- Precursor: #11968
# Which Problems Are Solved
This pr updates major and minor dependencies and is the first step on
getting our dependabot alerts cut down.
# How the Problems Are Solved
Depedency updates across the board eg:
- Upgrade Angular to v21
- Upgrade next.js to v16.2
- Upgrade tailwind to v4 in the login
- Upgrade vitest to v4 in the login
This is an uncompleted list refer to the changed files for a full
overview of all the updates.
# Additional Changes
Migrated all control flow in the console to the modern control flow
syntax.
Fixed the dependsOn setting for the @zitadel/login:test-unit nx target.
# Additional Context
- Closes https://github.com/zitadel/zitadel/issues/11274
---------
Co-authored-by: Max Peintner <peintnerm@gmail.com>
# Which Problems Are Solved
The documentation did not reflect the difference between login v1 and v2
for configuring a JWT-idp
# How the Problems Are Solved
Added a warning in the docs which highlight that difference.
# Additional Changes
- Restructured the docs to reflect a more generic approach.
- Fixed indentation inside the `<Callout type="warning">` block so the
content renders as formatted text instead of a code block.
- Fixed inconsistent acronym casing in the use-case section: "jwt" →
"JWT" and "idp" → "IdP" to match the rest of the page and UI terms.
# Additional Context
- Closes: #11589
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
## Problem statement
- `<Tabs>` were not rendered in docs
- Missing steps in README for local dev
## How it was solved
- Enhance the README to better describe local development setup and
clean up formatting.
- Standardize the use of tabs across various components for consistency.
## Additional info
To not cause merge conflicts with
https://github.com/zitadel/zitadel/pull/11729 changes in
`/self-hosting/manage/configure/configure.mdx` were skipped
# Which Problems Are Solved
System API users currently authenticate using raw RSA public keys
configured via Path or KeyData. This approach doesn't integrate well
with Kubernetes tooling.
# How the Problems Are Solved
Allow for the `path`/`keyData` to be an X.509 certificate.
The `NotBefore` and `NotAfter` fields of the certificate are beeing
respected when validating the JWT.
# Additional Changes
# Additional Context
- Closes#11442
---------
Co-authored-by: Livio Spring <livio@zitadel.com>
# Which Problems Are Solved
For switching v4.x releases to a corresponding maintenance branch, we
had to trick semantic release and create a `5.0.0-base` tag on main.
This now breaks the docs build, which tries to fetch all tags and build
a corresponding version.
# How the Problems Are Solved
- Ignore pre-released tags/releases for the moment.
# Additional Changes
None
# Additional Context
- requires backport to v4.x
# Which Problems Are Solved
API Requests in the docs, still had old naming
# How the Problems Are Solved
Updated Authorization Reuqest naming in docs with role assignments
Added a callout to the Kubernetes deployment guide (`Deploy ZITADEL on
Kubernetes`) explicitly stating that PostgreSQL 18 is not currently
supported, ensuring users deploy with a compatible version (14-17).
This PR updates the "Hosted Login UI" documentation to clarify how text
customization works for the new Hosted Login V2.
**Changes:**
1. Adds a warning callout to the "Customization options" section.
2. Clarifies that Login V2 interface texts currently cannot be modified
via the ZITADEL Console UI.
3. Provides the required workaround, directing users to use the Settings
V2 API to patch translation keys using the en.json locale file as a
reference.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
# Which Problems Are Solved
For existing customers it could be hard to understand the new aligned
terms we have defined, if they are already used to the "old term"
# How the Problems Are Solved
Adding notes at the top of docs pages to state clearliy new and old
terms.