Adds a temporary redirect for all /api/group/* routes to a new "Under
Development" page while the API is being built.
---------
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Automatically generated PR resolving Knowledge Gap ID 43.
**Thread ID:** mixpanel-cmvvwsc2uwvlkujw
**Action:** UPDATE
**Target Files:** 1
### AI Summary
> *Negative Docs Feedback*
*Path:* `/sdk-examples/react`
*Comment:* "ai generator went crazy it seems, with so many repeated &
unfinished sentences"
---
🤖 **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>
# Which Problems Are Solved
Expose impersonating actor to `preAccessToken` and `preUserinfo`
actions.
# How the Problems Are Solved
Provide the `actor` information already present in the OIDC session
model of JWT token to the relevant actions. Both goja-based actions "v1"
and webhook based execution targets carry the actor information now.
Actor remains null in case of non-impersonated tokens. Actor may contain
nested actors to display a delegation chain of impersonators.
# Additional Changes
- dba6261c8e: refactor `userinfoFlows` to
reduce complexity, add test coverage and solve a couple of potential
bugs.
- `getClientId` in actions was previously undocumented. Added to
documentation.
- A skill that reproduces manual testing using webhook.site or a local
sink.
# Additional Context
- Closes https://github.com/zitadel/zitadel/issues/12097
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Wim Van Laer <wim+github@zitadel.com>
# Which Problems Are Solved
- Native iOS/Android passkeys need OS trust files on the ZITADEL domain;
without them, Associated Domains / App Links verification fails.
- Operators could not configure iOS Team ID + Bundle ID or Android
package name + SHA-256 fingerprints on OIDC apps.
- `/.well-known/apple-app-site-association` and
`/.well-known/assetlinks.json` were not served from application config.
# How the Problems Are Solved
- Add iOS/Android app-link fields on OIDC app create/update (Application
API v2 + Management), with validation.
- Persist and project those fields; query active app-link configs
instance-wide.
- Serve AASA (`webcredentials`) and Digital Asset Links
(`get_login_creds`) from well-known paths, with configurable
`Cache-Control` and fingerprint normalization at serve time.
- Console UI to edit the fields, with links to the well-known endpoints.
- Operator docs for configuration, endpoints, caching, and verification.
# Additional Changes
- Document on API fields that well-known responses may be HTTP-cached
and platform verifiers may delay propagation.
- Runtime config: `WellKnown.AppLinksCacheControlMaxAge` (default `5m`;
`0` → `no-store`).
# Additional Context
- Closes#12497
- Implemented and reviewed as stack:
- #12531 API contract
- #12532 storage wiring
- #12536 well-known endpoints
- #12537 console
- #12547 docs
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
# Which Problems Are Solved
Since #10666 (v4.1+, backported to v4.x), metadata values set through
actions v1 (`api.metadata.push` and `api.v1.user.appendMetadata`) are
always JSON-encoded via `json.Marshal`. This made the write path
consistent with the JSON-based read path, but removed the ability to
store raw (unencoded) metadata values:
- A scalar string is now always stored quoted (`"de"` instead of `de`).
- The previous byte-array convention (mapping a string to an integer
array in the script, handled by `mapBytesToByteArray` introduced in
#5526) now stores the literal integer-array text (e.g. `[100,101]`)
instead of the raw bytes.
Customers migrating from v3.x whose downstream systems base64-decode
metadata values from tokens and expect raw bytes have no way to produce
them anymore — changing the consuming system is not always possible.
Reverting the default is not an option either, as clients that adopted
actions v1 on v4.x now rely on the JSON encoding.
# How the Problems Are Solved
- Adds a new, opt-in function `api.v1.user.appendMetadataRaw(key,
value)` to the actions v1 login flows (external / internal
authentication post authentication and pre creation), next to the
existing `appendMetadata`.
- The value is stored as raw bytes without JSON encoding:
- a string is stored as its plain UTF-8 bytes (`de`, not `"de"`)
- byte arrays (`Uint8Array` or a plain array of integers 0-255, the old
convention) are stored as-is, so existing v3 scripts using a
string-to-byte-array helper only need to switch the function name
- other types (and empty values) throw an error
- The existing `appendMetadata` and `api.metadata.push` behavior remains
byte-for-byte unchanged.
# Additional Changes
- Documented `appendMetadataRaw` (and the JSON encoding behavior of
`appendMetadata`) in the external and internal authentication actions
docs.
- Added unit tests for the new function (through a real goja runtime)
and a test locking in the existing `appendMetadata` JSON-encoding
behavior.
# Additional Context
- Regression introduced as a side effect of #10666 (which fixed#10470);
the raw byte handling was originally introduced in #5526.
- Reported by a customer upgrading from v3.4.x to v4.16.x, whose
PostAuthentication action maps token payload claims into user metadata.
- Requires backport to v4.x.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
# Which Problems Are Solved
#12313 lets clients register themselves as OIDC applications (RFC 7591),
but a dynamically registered client has no way to manage itself
afterwards:
- The registration response returns no `registration_access_token` and
no `registration_client_uri`, which RFC 7591 and 7592 clients (including
the MCP SDKs) expect in order to manage their own registration.
- There is no way to read back, update or delete a registration without
an operator acting on the client's behalf through the Console or the
Management API. A client that needs to rotate a redirect URI has to ask
a human.
# How the Problems Are Solved
Implement the [OAuth 2.0 Dynamic Client Registration Management Protocol
(RFC 7592)](https://datatracker.ietf.org/doc/html/rfc7592): `GET`, `PUT`
and `DELETE` on `/oauth/v2/register/{client_id}`, wired through the same
`op.WithSetRouter` hook as the registration endpoint.
## Control plane: the same security settings, no new switch
The management endpoints are gated on the
`DynamicClientRegistrationSettings.enabled` introduced in #12313. No new
setting, no feature flag: a client that may register may manage what it
registered. When registration is disabled the endpoints answer `404`,
exactly as `POST /oauth/v2/register` does.
`allow_unauthenticated` selects the registration mode and does not apply
here, because the registration access token authorizes these endpoints
in both modes.
## Authorization: the registration access token, and nothing else
RFC 7592 §3 defines the credential as the registration access token
issued at registration and bound to a single client, not a user
credential. So a client manages only itself, proving it with the token
it was handed:
| | Registration (`POST`) | Management (`GET` / `PUT` / `DELETE`) |
| --- | --- | --- |
| Credential | Access token, or none in open mode | Registration access
token |
| Permission | `project.app.register_dynamic` in token mode | None |
Neither `project.app.register_dynamic`, which governs who may *create*
clients, nor `project.app.write` applies to the management endpoints.
One authorization path per endpoint is easier to reason about than two,
and there is no user identity to check against in the first place.
Operators keep managing dynamically registered clients through the
Management API and the Console, like any other application; they cannot
obtain a client's registration access token, by design.
Status codes: a missing, malformed or non matching token is `401`; a
client that no longer exists is `404`. The token's `client_id` is
checked against the path before any lookup, so a token bound to another
client is rejected without touching the database.
## The token itself
- **Stored like a client secret.** Only its passwap hash is persisted,
through a new
`project.application.config.oidc.registration_token.changed` event; the
plain token leaves the server exactly once, in the response that issues
it.
- **Bound to its client and organization** through authenticated
encryption with the instance key, the same mechanism as refresh tokens.
The opaque token handed to the client encrypts
`client_id:org_id:secret`, so the endpoint recovers the binding before
checking the secret against the stored hash.
- **Verified in O(1)** against the hash on the projection, folded into
the client lookup the handler already does, with a strongly consistent
fallback to the eventstore so a token that was just rotated is accepted
before it is projected.
- **Rotated on update** (RFC 7592 §4.4) and invalidated implicitly when
the client is deleted. A read does not rotate it. Every update rotates,
including one that changes no metadata, so a client always gets a usable
token back.
## Reusing the existing persistence
A small refactor extracts the shared OIDC application creation and
update logic (`pushOIDCApplication` gains a variadic `extraEvents`, and
`oidcApplicationChangeEvent` is lifted out of `UpdateOIDCApplication`),
so the dynamic commands reuse it without the permission check. The
registration token event is pushed atomically with the application, so a
registered client is never left unmanageable.
# Additional Changes
- Setup step **74** adds the `registration_token` column to the
`apps7_oidc_configs` projection, with a reducer for the new event
modelled on the client secret. Applications are not part of the
relational storage projection, so there is no second write path to keep
in sync.
- The registration response (`POST`) now also carries
`registration_access_token` and `registration_client_uri`.
- Docs: a "Manage a registration" section in the dynamic client
registration guide covering the three operations, the authorization
model, token rotation and the new limitations, plus the management
endpoints on the OIDC endpoints page.
- Unit tests for the command layer (issue, verify, rotate, update,
delete), the projection reducer, and the token binding and response
mapping. An integration test covers the full lifecycle (register, read,
update with rotation, delete, read again with `404`), a token bound to
another client, and the endpoints not being served when registration is
disabled. None of the integration calls carries a user access token,
which pins down that the management endpoints require no permission of
their own.
# Additional Context
- Part of the MCP authorization effort in #9810. Follow-up to #12313
(RFC 7591), which is now merged; this branch has been rebased on `main`
and carries the settings and authorization model agreed there.
- **Open question for the review**: the authorization model above
(registration access token only, no operator path through these
endpoints) is the one I proposed when #12313 was reviewed, but it was
never explicitly confirmed. If you would rather have `project.app.write`
also grant access to a client in the operator's own organization, that
is a contained change in `authorizeClientManagement`.
- Rotation is eventually consistent: right after an update the previous
token may keep working for a brief moment until the rotation is
projected, while the new token works immediately through the eventstore
fallback. This matches how ZITADEL validates access tokens, where
revocation is likewise eventually consistent. It is documented in the
guide and asserted as such in the integration test.
- A database migration is introduced for the new projection column. No
proto change and no new feature flag.
- Verified locally: full build, `go vet` including `-tags integration`,
`golangci-lint` with 0 issues, and the unit suites for every touched
package. As before, I cannot run the integration suite here, so CI
remains the check on it.
# Which Problems Are Solved
ZITADEL cannot currently be used as an OAuth 2.0 Authorization Server by
clients that need to register themselves at runtime:
- There is no [OAuth 2.0 Dynamic Client Registration (RFC
7591)](https://datatracker.ietf.org/doc/html/rfc7591) endpoint, and no
`registration_endpoint` is advertised in the discovery document.
- This blocks [Model Context Protocol
(MCP)](https://modelcontextprotocol.io) clients (Claude Desktop,
claude.ai, Cursor, the MCP SDKs), whose OAuth 2.1 authorization profile
expects an Authorization Server that supports dynamic client
registration. They self-register before any user context exists and only
then start the authorization code + PKCE flow.
# How the Problems Are Solved
## Control plane: instance security settings
No feature flag and no runtime config. A
`DynamicClientRegistrationSettings` message is nested under the instance
`SecuritySettings` in `settings/v2`, next to `embedded_iframe` and
`enable_impersonation`:
| `enabled` | `allow_unauthenticated` | Behaviour |
| --- | --- | --- |
| `false` (default) | — | `POST /oauth/v2/register` returns `404`,
`registration_endpoint` absent from discovery |
| `true` | `false` (default) | Token-gated registration, client homed in
the token's organization |
| `true` | `true` | Open registration for MCP hosts, client homed in the
instance default organization |
Both values are carried on `authz.Instance` and loaded with the
instance, exactly like `EnableImpersonation`, so the discovery document
and the endpoint read them per request without an extra query.
`allow_unauthenticated` implies `enabled` in both implementations, so a
single setting closes the endpoint.
Adding the two columns bumps the projection table to
`projections.security_policies3`, following what the impersonation
setting did for `security_policies2`.
## Authorization: a dedicated permission, not `project.app.write`
- New org-scoped permission **`project.app.register_dynamic`**, granted
by default to `ORG_OWNER`, `IAM_OWNER` and `IAM_ORG_MANAGER` — in both
`InternalAuthZ` and `SystemAuthZ`, mirroring where `project.app.write`
already lives.
- New built-in role **`ORG_DYNAMIC_CLIENT_REGISTRAR`** carrying only
that permission, so a service user can self-register clients without
gaining write access to the organization's existing applications.
- Open mode (`allow_unauthenticated = true`) requires no token and no
permission: that is the MCP self-register path.
- A valid token whose user lacks the permission is answered with **`403
insufficient_scope`** (RFC 6750 §3.1) rather than `401 invalid_token`,
so a caller can tell "your token is bad" from "your token may not do
this". `verifyAccessToken` also reports invalid tokens as permission
denied, so the authorization failure is marked explicitly to keep the
two apart.
The check runs once, at the endpoint, right after the token is verified
and before any state is created, so it also gates the auto-provisioning
of the organization's DCR project. The permission itself lives in the
command layer next to the others
(`Commands.CheckPermissionRegisterDynamicClient`). As the OIDC endpoints
are not behind the authorization interceptor, the caller identity is
derived from the verified token, the way token exchange does for the
impersonating actor.
## Registration itself
- **Registered clients are ordinary OIDC applications.** The endpoint
reuses the existing application-creation events
(`NewApplicationAddedEvent` and `NewOIDCConfigAddedEvent`), so the whole
token, authorization and introspection flow keeps working unchanged.
They are stored in a dedicated, auto-provisioned project named `ZITADEL
DCR` per organization (name lookup), so they do not pollute the
`IAMProject` or other projects.
- Input is validated with the existing `GetOIDCV1Compliance` rules;
`private_key_jwt` and `jwks`/`jwks_uri` are rejected with
`invalid_client_metadata`.
- **Endpoint wiring without forking the library.** `NewServer` calls
`op.RegisterServer` instead of `op.RegisterLegacyServer`, so the new
route can be added through the same `op.WithSetRouter` hook as the
authorize callback. `op.RegisterLegacyServer` appends a middleware after
the caller options, which chi forbids once a route has been registered;
`op.NewIssuerInterceptor` reproduces the issuer middleware it would
otherwise add. The `/oauth/v2` routing prefix is unchanged.
# Additional Changes
- **`application_type` inference for custom-scheme redirects** (last
commit, isolated). `application_type` is an OpenID Connect member; RFC
7591 does not define it, so clients that only implement RFC 7591 omit
it. Native MCP hosts doing so register custom-scheme redirect URIs,
which ZITADEL reserves for native applications, and the OIDC default of
`web` rejected them with `invalid_redirect_uri`. Inference is limited to
custom schemes and to an absent `application_type`, so every request
accepted today keeps its current application type and auth method — an
`http` loopback redirect still yields a web application. Happy to drop
this commit if you would rather keep it out of this PR.
- **Docs**: a Dynamic Client Registration integration guide, a
`registration_endpoint` section on the OpenID Connect endpoints page,
and the new role in the administrators table (plus its description in
the Console translations).
# Additional Context
- Part of #9810. This is **Phase 1 (DCR)**; #12315 adds RFC 7592 and
#12316 adds CIMD, both stacked on this branch and rebased once this
lands.
- Implements the control-plane and authorization model requested in the
review of this PR, itself a refinement of the direction in
https://github.com/zitadel/zitadel/issues/9810#issuecomment-4891176997.
- **Out of scope (deliberately)**: RFC 7592, CIMD, persisting free-form
metadata (`logo_uri`, `contacts`, and similar), and `private_key_jwt` /
`jwks_uri` (rejected cleanly). No new event types.
- Follow-ups explicitly left out, per the review: DCR client lifecycle
and richer audit, consent and custom scopes, JWT / `aud` (RFC 8707), and
RFC 8414 AS metadata (currently absent from both ZITADEL and
`zitadel/oidc`).
# Which Problems Are Solved
- Generated V1 API reference docs are missing their base path prefixes
(e.g. `/admin/v1`, `/auth/v1`, `/management/v1`, `/system/v1`).
- Endpoint pages show routes like `/healthz` instead of
`/admin/v1/healthz`.
This happens because V1 protos still define `base_path` via legacy
OpenAPI v2 swagger annotations, while docs generation uses
`protoc-gen-connect-openapi`, which ignores those annotations and emits
the bare `google.api.http` paths.
# How the Problems Are Solved
- After OpenAPI generation in
`apps/docs/scripts/generate-proto-docs.mjs`, apply a small hardcoded map
of the four legacy V1 services and prepend the correct prefix to each
path in the generated specs.
- The rewrite is idempotent (`startsWith(prefix)`), so already-prefixed
paths are left alone.
- Because the prefixes are written into the generated OpenAPI files,
Fumadocs MDX generation and runtime page rendering stay in sync.
# Additional Changes
- None.
# Additional Context
- V1 APIs are legacy and frozen; hardcoding the four known prefixes is
simpler and more reliable than dynamically scraping `.proto` files.
- Changing the protos or dual-generating with `openapiv2` would be much
more invasive for a docs-only issue.
- Verified locally for Admin, Auth, Management, and System pages (e.g.
`/admin/v1/healthz`, `/management/v1/users/{id}`).
---------
Co-authored-by: Livio Spring <9405495+livio-a@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
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>
2026-04-02 15:53:08 +02:00
Wim Van LaerCopilotcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.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>