Commit Graph
4100 Commits
Author SHA1 Message Date
MaximilianandGitHub 96fffd9829 docs: Update link to redirect url settings (#11100)
# Which Problems Are Solved

wrong link to the redirect url settings in console

# How the Problems Are Solved

updated link
2025-12-03 07:29:00 +00:00
6e747172e4 chore(console): explain that a project can contain multiple applications that would b… (#11103)
# Which Problems Are Solved

It's unclear to new users that a single web application might have more
than one Zitadel "application", like one for the frontend and one for
the backend.

# How the Problems Are Solved
Updates the text defining projects in the onboarding

# Additional Changes
None
# Additional Context
Working on general improvements to make onboarding easier.

---------

Co-authored-by: David Skewis <[email protected]>
Co-authored-by: Copilot <[email protected]>
2025-12-02 10:48:22 +00:00
FuzzbizzandGitHub 8180801641 chore(console): more natural phrasing for grant type warning message (#11111)
# Which Problems Are Solved
- The warning for redirect URIs is awkwardly phrased in the past tense.

# How the Problems Are Solved

- The present tense is used and keywords enclosed in quotation marks 
<img width="444" height="35" alt="image"
src="https://github.com/user-attachments/assets/d7593ced-d53a-4655-b34b-d1fd00d9db49"
/>


# Additional Changes
N/A

# Additional Context
N/A
2025-12-02 11:40:46 +01:00
911967c865 feat(settings_relational): adding settings table for relational db (#10769)
# Which Problems Are Solved

As part of https://github.com/zitadel/zitadel/issues/9599 to push to
move to a relational db table model, this is the migration of the
settings

# Additional Changes

I had to add 2 non source code files
`backend/v3/storage/database/events_testing/font.otf` and
`backend/v3/storage/database/events_testing/picture.png`, these are used
as part of the reduce tests, hence why they're sourced inside
`backend/v3/storage/database/events_testing/settings_instance_test.go`

- Closes https://github.com/zitadel/zitadel/issues/10207

---------

Co-authored-by: adlerhurst <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Tim Möhlmann <[email protected]>
Co-authored-by: Stefan Benz <[email protected]>
2025-12-02 08:16:21 +01:00
SilvanandGitHub 6c8619e2f0 fix(domain): add PasskeyTypeCondition to humanPasskeyConditions interface (#11113) 2025-12-01 17:42:18 +01:00
SilvanandGitHub 1c78604e21 fix(repo): prevent cascading products of aggregated objects (#11099)
This update prevents cascading products in aggregated object queries by
ensuring distinct values are used in JSON aggregations.
2025-12-01 08:44:23 +00:00
86cce629c7 chore(login): add unit tests for core business logic (#11083)
# Which Problems Are Solved

- Adds basic unit tests for core business logic
- Adds playwright tests for core flows

# How the Problems Are Solved

- Extends unit tests for session
- Adds unit tests for other core business logic (oidc, idp, auth etc)

# Additional Changes

- N/A

---------

Co-authored-by: Max Peintner <[email protected]>
2025-11-27 16:55:40 +00:00
207095f7c1 chore: fix README typo (#11072)
# Which Problems Are Solved
Just fixing a typo: onboaring -> onboarding


# How the Problems Are Solved
N/A

# Additional Changes

N/A.

# Additional Context

N/A

Co-authored-by: Florian Forster <[email protected]>
2025-11-26 00:21:28 +00:00
f5ce288ea5 feat(domain): define user repositories (#11059)
This pull request introduces a new set of domain models and repositories
for managing users within the new v3 structure. The goal is to establish
a clean, robust, and extensible foundation for user management.

### Summary

This PR accomplishes the following:

- **Polymorphic User Model**: Introduces a `User` model in user.go that
can represent either a `Human` or a `Machine` user. This provides a
unified way to handle different user types while allowing for specific
attributes and logic for each.
- **Repository Pattern**: Implements the repository pattern for
accessing and manipulating user data. This decouples the business logic
from the data storage implementation. The main repository interfaces
(`UserRepository`, `HumanUserRepository`, `MachineUserRepository`) are
now defined in `backend/v3/domain/user_repository.go`.
- **Comprehensive User Models**: The user.go file now also defines the
domain models for associated user data, including `UserMetadata`,
`IdentityProviderLink`, `Passkey`, `PersonalAccessToken`, and
`MachineKey`.
- **Generic Verification and Check System**: Introduces verification.go
and check.go to provide a standardized way of handling various
verification flows (e.g., email verification, OTP checks).
- **Generated Code**: Adds new generated files for enums
(`humangender_enumer.go`, `machinekeytype_enumer.go`,
`passkeytype_enumer.go`, `personalaccesstokentype_enumer.go`,
`userstate_enumer.go`, `usertype_enumer.go`) and mocks for the new
repositories.
- **Session Domain Refactoring**: Updates the session domain
(`backend/v3/domain/session*.go`) to align with the new user model
structure.

This foundational work paves the way for migrating user management logic
to the new `v3` backend, with a more maintainable and testable
architecture.

part of #10224

---------

Co-authored-by: Copilot <[email protected]>
Co-authored-by: Marco A. <[email protected]>
2025-11-25 11:54:32 +01:00
5beeb5738a feat: Add recovery code MFA support (#9954)
<!--
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.
-->

One-time recovery codes are a common multi-factor authentication (MFA)
backup method, letting users access their account if they lose other MFA
devices. Support for recovery codes can also reduce support burden for
users locked out of their accounts and provide a more secure and
reliable form of verification than security questions.

# Which Problems Are Solved

Zitadel currently lacks support for recovery codes.

# How the Problems Are Solved

This PR partially addresses recovery code support in Zitadel.
Importantly, it adds recovery codes as a new 2FA `Factor` and an
additional `Check` type for the Session API.

```
Example recovery code flow:

1. User generates N new recovery codes using `POST /v2/users/{user_id}/recovery_codes`
2. Zitadel hashes and stores these codes and returns the un-hashed codes in the response
3. User creates new session with an additional check: `recoveryCode`
4. Code is checked against hash and, if valid, cannot be used again
5. User attempts to adds N more codes using the same endpoint 
6. If `remaining_codes + N <= RecoveryCodes->MaxCount` config value, then recovery codes are added in addition to original codes
7. User can remove all recovery codes using `DEL /v2/users/:userId/recovery_codes` 
```
This PR adds: 
- [x] Session recovery_code check support on `POST+PATCH /v2/sessions`
endpoints
- [x] Adds `mfa_recovery_code_checked_at` column (default null) to
`projections.sessions8` table
- [x] Support for `SECOND_FACTOR_TYPE_RECOVERY_CODES` as available 2FA
method on login policy
- [x] Support for importing recovery codes in /import code

Missing, will _not_ implement in this PR:
- [ ] Admin console support for displaying Recovery Code settings for
user(s)
- [ ] Zitadel Typescript login support for recovery codes 

TODO: 
- [x] Additional unit and integration tests
- [x] Error translations

# Additional Changes

None

# Additional Context

- Closes #6898

---------

Co-authored-by: Livio Spring <[email protected]>
2025-11-24 06:44:48 +00:00
Mridang AgarwallaandGitHub afa92e55f7 docs: added the updated docs for the new react example (#11073)
# Which Problems Are Solved

The React example needed updates to align with current best practices
and improve documentation clarity for developers integrating Zitadel
authentication.

# How the Problems Are Solved

Updated the React example codebase with improved authentication flow
using react-oidc-context, enhanced error handling and TypeScript type
safety, and refined component structure for better maintainability.

# Additional Changes

Updated documentation to reflect implementation details, added
comprehensive environment variable configuration examples with exact
variable names from the codebase, improved inline code comments, and
updated dependencies to latest stable versions.

# Additional Context

- Related to React integration example improvements
- Enhances developer experience when implementing Zitadel PKCE
authentication in React applications
2025-11-17 20:22:51 +00:00
SilvanandGitHub 0f1b7c6eaa feat(database): add statement and CTE changes (#11069)
Read pull request "feat(database): add statement and CTE changes
(#11069)"

This pull request introduces new functionality for handling database
changes using statements and Common Table Expressions (CTEs).

### Summary

This PR accomplishes the following:

- **Statement and CTE Changes**: Adds new types and functions in
change.go for handling more complex database changes. This includes:
    -   `NewChangeToNull`: A change that sets a column to `NULL`.
- `NewChangeToColumn`: A change that sets a column's value to the value
of another column.
- `NewIncrementColumnChange`: A change that increments a column's value
by 1.
- `NewChangeToStatement`: A change that sets a column's value to the
result of a subquery.
- `NewCTEChange`: A change that uses a Common Table Expression (CTE) to
perform more complex updates.
- **Testing**: Adds comprehensive tests in change_test.go to cover the
new functionality and ensure the correctness of the generated SQL
statements and arguments.
- **Ignoring AI Files**: Updates the .gitignore to exclude files
generated by AI tools.

This work enhances the flexibility of the database layer, allowing for
more complex and efficient database operations.
2025-11-14 12:58:22 +00:00
9274e008fe feat(rt): project grants (#10951)
This pull request introduces a new feature that allows adding, updating,
and querying project grants The changes are primarily in the backend and
include new database tables, repositories, and domain logic to support
project grants.

## Changes

* New `project_grants` table: A new table `zitadel.project_grants` is
introduced to store project grants It includes columns for
`instance_id`, `id`, `state`, `project_id`, `granted_org_id` and
`granting_org_id`.
* New `ProjectGrantRepository`: A new repository
`ProjectGrantRepository` is created to handle all database operations
for project grants. It provides methods to `Get`, `List`, `Create`,
`Update`, and `Delete`.
* New `project_grant_roles` table: A new table
`zitadel.project_grant_roles` is introduced to store project grant roles
It includes columns for `instance_id`, `grant_id`, `key`, `project_id`
and `project_org_id`.
* New `ProjectGrantRoleRepository`: A new repository
`ProjectGrantRoleRepository` is created to handle all database
operations for project grant roles. It provides methods to `Get`,
`List`, `Add`, and `Delete`.
* New `project_grant_relational_projection`: A new projection
`project_grant_relational_projection` is added to update the
`zitadel.project_grants` and `zitadel.project_grant_roles` tables based
on events. It handles all project grant events.
* Updated `ProjectRepository`: The `ProjectRepository` is updated to
list granted projects.

# Additional Context

Closes https://github.com/zitadel/zitadel/issues/10766

---------

Co-authored-by: Stefan Benz <[email protected]>
Co-authored-by: Marco A. <[email protected]>
Co-authored-by: Silvan <[email protected]>
2025-11-14 11:04:16 +00:00
Livio SpringandGitHub 6051ce591d fix(deps): update saml and all other dependencies (#11067)
Updates saml and all other direct dependencies (which are possible) to
the latest version to include fixes and solve requested features:
- https://github.com/zitadel/saml/issues/103
- https://github.com/zitadel/saml/issues/104

(requires backport to v.4x at least for saml)
2025-11-13 07:14:25 +01:00
33c51deb20 Merge commit from fork
* validate IDP linking permissions

* fix: check policy before linking

* apply suggested review comments

---------

Co-authored-by: Max Peintner <[email protected]>
2025-11-12 13:48:40 +01:00
75791361f3 fix(login): Organization Discovery for Login Without Org Context (#10996)
# Which Problems Are Solved

When users accessed the login page without an organization context and
entered a login name with a domain suffix (e.g., [[email protected]], the
system would return "user not found" instead of performing organization
discovery.

# How the Problems Are Solved

Added organization discovery logic that triggers after a global user
search returns no results. When no organization context is provided:

- Extracts the domain suffix from the loginName (e.g., @company.com)
- Queries for organizations with that domain as their primary domain
- If exactly one organization is found with allowDomainDiscovery
enabled, uses it as the discovered organization
- Redirects users to the appropriate flow (IDP, registration, or
password) with the discovered organization context

---------

Co-authored-by: Ramon <[email protected]>
2025-11-12 13:14:09 +01:00
2953366b4c feat(relational): define session repository (#11054)
# Which Problems Are Solved

As part moving sessions to the relational table, the repository to be
able to manage session needs to be defined. This allows the business
logic / service-layer to implement the necessary commands and the
storage-layer to implement the underlying repository.

# How the Problems Are Solved

This PR defines the `SessionRepository` with all underlying object like
the user agent, metadata, factors (including. challenges).

# Additional Changes

None

# Additional Context

- relates to #10212

---------

Co-authored-by: Copilot <[email protected]>
2025-11-11 10:57:33 +00:00
e074668c6b feat(cmd): skip privileged database commands during initialization if objects already present (#11021)
This pull request addresses an issue where ZITADEL's initialization
process could fail in environments with restricted database permissions,
such as managed database services (e.g., Google Cloud SQL, Amazon RDS,
Azure PostgreSQL).

## Which problem is solved

Previously, `zitadel init` (and its sub commands) and `zitadel
start-from-init` commands would attempt to execute `CREATE DATABASE`,
`CREATE USER`, and `GRANT` statements. These commands often fail if the
provided database user lacks superuser privileges, which is a common
security practice in hosted database environments.

## How the problem is solved

With this change, Zitadel is now smarter during initialization. It
checks if the database and user specified in your configuration already
exist and are accessible. If they are, ZITADEL will skip the creation
and grant commands, allowing for a seamless setup even with a
less-privileged database user.

## Additional information

closes #10730
closes https://github.com/zitadel/zitadel/issues/8198

### How to leverage this feature (skip admin commands)

To have ZITADEL skip the database administration commands, you need to
configure it so that the initialization process can use the
already-existing database and user. This is achieved by pointing the
admin access in your ZITADEL configuration to the user and database that
ZITADEL will use for its operations.

In your ZITADEL configuration file (e.g., zitadel.yaml), configure the
Database section as follows:

```yaml
Database:
  Postgres:
    Database: existing_database
    # Admin credentials should be the same as the application user credentials
    Admin:
      User: zitadel-user
      ExistingDatabase: existing_database # this is used to connect the admin to the previously created database
    # Application user credentials
    User:
      User: zitadel-user
```

---------

Co-authored-by: Marco A. <[email protected]>
2025-11-11 10:28:06 +00:00
SilvanandGitHub fbdbd2d418 feat(database): add row locking options for queries (#10990)
Introduce options to lock rows returned by queries, allowing for more
controlled transaction handling. This includes support for different
lock modes such as "FOR UPDATE," "FOR NO KEY UPDATE," and "FOR SHARE."

## Additional information

- closes https://github.com/zitadel/zitadel/issues/10930
- closes https://github.com/zitadel/zitadel/issues/10675
2025-11-11 11:11:17 +01:00
a9846498a9 feat(group): add user groups to token claims (#11009)
# Which Problems Are Solved

If the groups of a user is requested through a scope, details related to
the user's groups are added in the token claims.

# How the Problems Are Solved
By querying the user groups that the user is a part of, and setting them
in the token claims.

This PR introduces two scopes to request user groups: `groups` and
`urn:zitadel:iam:user:groups`
* `groups` returns an array of group names in the token claims with the
same name
* `urn:zitadel:iam:user:groups` returns an array of JSON objects with
information about the user groups in the token claims with the same name

# Additional Changes

N/A

# Additional Context

- Closes #9702 
- Follow-up for PRs:
  * #10455 
  * #10853 
  * #10758 
  * #10940

---------

Co-authored-by: Livio Spring <[email protected]>
2025-11-11 09:06:45 +01:00
Livio SpringandGitHub e4a959c321 fix(authz): ignore unready auth methods for mfa requirement check (#11056)
# Which Problems Are Solved

The recent
[fix](https://github.com/zitadel/zitadel/commit/2a7db648817d95eaf6716b12345f958eecdff15d)
made sure the Zitadel API always requires MFA if a user has set up so
even though not required by the login policy. After the deployment,
multiple users reached out that also users without any MFA set up got
the corresponding `[permission_denied] mfa required (AUTHZ-KI3p0)`error.

# How the Problems Are Solved

- Only check the set up factors with are verified and ready to use.
Ignore all unready auth methods.

# Additional Changes

None

# Additional Context

- relates to
https://github.com/zitadel/zitadel/commit/2a7db648817d95eaf6716b12345f958eecdff15d
- closes https://github.com/zitadel/zitadel/issues/11055
- requires backport to v2.71.x, v3.x and v4.x
2025-11-11 05:55:59 +00:00
David SkewisandGitHub 449285fda3 fix(console): add config for missing frameworks in app creation (#11057)
# Which Problems Are Solved

- Solves the issue of app creation when selecting go, python, ruby, php,
java, spring and node

# How the Problems Are Solved

- Adds the appropriate configs for each app type


# Additional Context

- Closes #11052
2025-11-10 15:05:50 +01:00
d7e9eddb76 fix(user): Updating user info when authenticating with external IDP (#11046)
# Which Problems Are Solved

User profile updates were not propagated when using External OIDC IDP +
Login V2

# How the Problems Are Solved

* `UpdateHumanUserRequest` is added to
`RetrieveIdentityProviderIntentResponse`
* `UpdateHumanUserRequest` is returned in the
`RetrieveIdentityProviderIntentResponse` when the user already exists
during external IDP auth, which is then used in the frontend to update
the user info

# Additional Changes

* Moved integration tests related to user intent to a separate test file
* Fix redirection after external IDP user registration

# Additional Context
- Closes #10838 
- Follow up: https://github.com/zitadel/zitadel/issues/11053

---------

Co-authored-by: Max Peintner <[email protected]>
2025-11-10 09:50:36 +01:00
Stefan BenzandGitHub a3390a0adb fix: add additional binding for url with type (#11032)
# Which Problems Are Solved

Typo in URL.

# How the Problems Are Solved

Additional binding to fix typo.

# Additional Changes

None

# Additional Context

Closes #8710
2025-11-06 09:57:42 +00:00
Stefan BenzandGitHub ae216120bd fix: comment in feature flags so that they can be used in env variables (#11030)
# Which Problems Are Solved

Some configuration can not be set directly through environment
variables.

# How the Problems Are Solved

Comment in the attributes, so that Zitadel uses the environment
variables.

# Additional Changes

None

# Additional Context

Closes #10913
2025-11-05 13:29:44 +00:00
Gayathri VijayanandGitHub 14038716e3 fix(doc): update actions v2 examples (#11017)
# Which Problems Are Solved

This PR fixes the examples used in the actions v2 docs. 

# How the Problems Are Solved

* By fixing the actions v2 import path used in the example

# Additional Changes

* Use actions v2 instead of actions v2beta in the examples
* Use v2 `CreateUser` instead of v2beta `AddHumanUser` in
`request-manipulation` example

# Additional Context
- Follow up for https://github.com/zitadel/zitadel-go/issues/523
2025-11-04 15:18:30 +00:00
66e04b1dad fix(login): Add default organization fallback for IDP user creation #11025 (#11026)
# Which Problems Are Solved

When users authenticate via IDP (Identity Provider) without explicit
organization context, the flow could fail or create users without proper
organization assignment. This occurred when:

- No organization parameter was provided in the IDP callback
- Domain discovery didn't find a matching organization
- OIDC requests didn't include organization scopes

# How the Problems Are Solved

Implemented a fallback mechanism that ensures organization context is
always available:

- Centralized organization resolution in `resolveOrganizationForUser()`
  - First: Use explicitly provided organization
  - Second: Attempt domain discovery from username
  - Third: Fallback to default organization (NEW)
- Explicit error handling: Users are never created without organization
context. If no organization can be determined (including no default
org), the flow fails gracefully with a clear error message.
- Applied to both creation flows:
  - CASE 4: Auto-creation of users
  - CASE 5: Manual user registration

Co-authored-by: Ramon <[email protected]>
2025-11-04 08:58:41 +01:00
Mridang AgarwallaandGitHub ee17b7a074 docs: added the docs for the missing examples (#11005)
<!--
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

Replace this example text with a concise list of problems that this PR
solves.
For example:
- If the property XY is not given, the system crashes with a nil pointer
exception.

# How the Problems Are Solved

Replace this example text with a concise list of changes that this PR
introduces.
For example:
- Validates if property XY is given and throws an error if not

# Additional Changes

Replace this example text with a concise list of additional changes that
this PR introduces, that are not directly solving the initial problem
but are related.
For example:
- The docs explicitly describe that the property XY is mandatory
- Adds missing translations for validations.

# Additional Context

Replace this example with links to related issues, discussions, discord
threads, or other sources with more context.
Use the Closing #issue syntax for issues that are resolved with this PR.
- Closes #xxx
- Discussion #xxx
- Follow-up for PR #xxx
- https://discord.com/channels/xxx/xxx
2025-11-04 09:50:38 +05:30
02499f5fc4 chore(adopters): Update ADOPTERS.md (adds D1V.AI as a new customer case) (#11011)
<!--
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 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

This PR adds D1V.AI as a new customer case study to Zitadel's public
documentation, which addresses the following:

- Showcases real-world adoption of Zitadel Cloud by an innovative AI
development platform.
- Provides social proof and a specific use case for potential customers
evaluating Zitadel.
- Documents how Zitadel serves as the identity foundation for
cutting-edge "vibe coding" platforms.

# How the Problems Are Solved

By adding D1V.AI to the list of users/customers:

- The community can see a novel application of Zitadel in the AI-powered
development space.
- D1V.AI gains visibility and recognition as part of the Zitadel
ecosystem.

# Additional Changes

- None. This is a straightforward documentation addition.

# Additional Context

- D1V.AI is an actual company using Zitadel Cloud in production.
- D1V.AI leverages Zitadel as the identity backbone for its platform,
enabling the fastest way from prompt to profit through secure and
scalable user authentication.

---------

Co-authored-by: Maximilian <[email protected]>
2025-10-31 22:24:35 +00:00
SilvanandGitHub 345480faeb fix(projection): locking behavior based on configuration (#11014)
Ensure projections await running status if configured, improving
synchronization during event processing.
2025-10-31 13:10:02 +02:00
Max PeintnerandGitHub c913904df3 fix(login): idp success url (#10997)
# Which Problems Are Solved

An IDP Intent could not be completed due to a missing change of
successUrl property in a recent PR.

# How the Problems Are Solved

The /success page has been replaced by /process to finish the IDP flow
in all occurences.
2025-10-29 10:54:28 +01:00
Livio SpringandGitHub b284f8474e Merge commit from fork 2025-10-29 10:12:50 +01:00
Livio SpringandGitHub b8db8cdf9c Merge commit from fork
* fix: respect lockout policy on password change (with old password)

* add tarpitting

* cleanup
2025-10-29 10:07:35 +01:00
Livio SpringandGitHub 72a5c33e6a Merge commit from fork
* fix: sanitize host headers before use

* add additional test
2025-10-29 10:05:37 +01:00
f4503e07cd feat(api): integrates drupal7 hash verifier from passwap (#10918)
# Which Problems Are Solved

- Integrates the Drupal 7 hash verifier from passwap

# Additional Changes

- The docs inform about the option to use the Drupal 7 hash verifier
- Updates passwap to version v0.10.0

# Additional Context

- Follow-up for PR
[#passwap/pull/70](https://github.com/zitadel/passwap/pull/70)

Co-authored-by: Marco A. <[email protected]>
2025-10-28 16:26:48 +00:00
Marco A.andGitHub 39a29f534a feat(domain): Instance APIs with relational tables (#10953)
# Which Problems Are Solved

This PR implements the endpoints listed in
https://github.com/zitadel/zitadel/issues/10443 .

# How the Problems Are Solved

The implementation follows the same pattern as the Organization one.
There are no peculiarities to this PR. The `Update`, `Delete` are
implementing the `Commander` interface, while `Get` and `List`
instance(s) endpoints are implementing the `Querier` interace.

# Additional Context

- Closes #10443
- Depends on #10445
2025-10-28 14:17:19 +00:00
Gayathri VijayanandGitHub ad8e8bf61f feat(group): manage users in user groups (#10940)
# Which Problems Are Solved

1. Adding users to user groups and removing users from user groups.
2. Searching for users in user groups by group IDs or user IDs

# How the Problems Are Solved

By adding:
1. The API definitions to manage users in users groups
3. The command-layer implementation of adding users/removing users
to/from user groups.
4. The projection table group_users1
5. Query-side implementation to search for users in user groups

# Additional Changes

1. Remove debug statements from unit tests.
2. Fix removal of groups when orgs are removed
3. Add unit tests for groups projection

# Additional Context

* Related to #9702 
* Follow-up for PRs 
  * https://github.com/zitadel/zitadel/pull/10455
  * https://github.com/zitadel/zitadel/pull/10758
  * https://github.com/zitadel/zitadel/pull/10853
2025-10-28 13:23:54 +00:00
Livio SpringandGitHub c2a0b9d187 feat(api): move instance service to v2 (#10919)
# Which Problems Are Solved

As part of our efforts to simplify the structure and versions of our
APIs, were moving all existing v2beta endpoints to v2 and deprecate
them. They will be removed in Zitadel V5.

# How the Problems Are Solved

- This PR moves instance v2beta service and its endpoints to a
corresponding v2 version. The v2beta service and endpoints are
deprecated.
- The docs are moved to the new GA service and its endpoints. The v2beta
is not displayed anymore.
- The comments and have been improved and, where not already done, moved
from swagger annotations to proto.
- All required fields have been marked with (google.api.field_behavior)
= REQUIRED and validation rules have been added where missing
- `Domain` has been renamed to `CustomDomain` to align with naming
conventions
- `..Query` has been renamed to `..Filter` to align with other services
- The `instance_id` parameter can now passed on all endpoints and is
properly used, but requires `system` permissions. It can be omitted to
use the own instance (identified by context as any other service).
  - The following endpoints are affected:
    - GetInstance
    - UpdateInstance
    - ListCustomDomains
    - AddTrustedDomain
    - RemoveTrustedDomain
    - ListTrustedDomains
- InstanceService has been added the InstanceInterceptor's
`explicitInstanceIdServices` to allow passing the id
- If the instance is not found by id, the error is not directly returned
to prevent enumeration.
- Permissions are checked in the API instead of the interceptor for
these calls.
- Setting the same instance name in the update no longer returns an
error, but the previous change date.
 
# Additional Changes

none

# Additional Context

- part of https://github.com/zitadel/zitadel/issues/10772
- requires backport to v4.x
2025-10-28 14:01:14 +01:00
Max PeintnerandGitHub fa524e3b05 fix(login): Return promise from passkey authentication to fix automatic prompt (#10991)
# Which Problems Are Solved

The passkey login page was not rendering properly in production (Cloud
Run) deployments, with the submit button and component content not
appearing. Additionally, the automatic passkey prompt was not triggering
correctly.

# How the Problems Are Solved

Added the missing return statement before navigator.credentials.get() in
the submitLoginAndContinue function. This ensures the promise is
properly returned and chained in the useEffect hook, fixing the
automatic passkey prompt flow.

Removes the recently introduces guides to passkeys that could result in
a hydration error due to the <a> tag being rendered differently on
server / client environement

# Additional Changes

This issue was most probably introduced in PR #10971. The component uses
promise chaining (.then().catch().finally()) which requires the promise
to be returned, unlike the RegisterPasskey component which uses
async/await and works correctly without an explicit return.
2025-10-28 12:35:47 +00:00
Livio SpringandGitHub 32500e3b0c feat(api): move project service v2beta to GA (and deprecate v2beta) (#10844)
# Which Problems Are Solved

As part of our efforts to simplify the structure and versions of our
APIs, were moving all existing v2beta endpoints to v2 and deprecate
them. They will be removed in Zitadel V5.

# How the Problems Are Solved

- This PR moves project v2beta service and its endpoints to a
corresponding v2 version. The v2beta service and endpoints are
deprecated.
- The comments and have been improved and, where not already done, moved
from swagger annotations to proto.
- All required fields have been marked with `(google.api.field_behavior)
= REQUIRED` and validation rules have been added where missing.
- Name ID of the project always `project_id`
- `UpdateProjectRequest` has been updated to align with the creation and
retrieval of a project:
  - `project_role_check` has been renamed to `authorization_required`
  - `has_project_check` has been renamed to `project_access_required`
- `ListProjectRequest` has been changed:
- `project_grant_resource_owner_filter`,
`project_grant_resource_owner_filter` and
`project_organization_id_filter` have been removed and merged into a
single `organization_id_filter` where a `type` can optionally be
specified to select `owned`, `granted` or both project types within a
specified organization.
- `ListProjectGrantReques` has been changed:
- `project_resource_owner_filter` has been renamed to
`project_organization_id_filter`
- `grant_resource_owner_filter` has been renamed to
`granted_organization_id_filter`

# Additional Changes

Replaced deprecated `intergration.WithAuthorization` with
`integration.WithAuthorizationToken` in integration tests.

# Additional Context

- part of #10772 
- requires backport to v4.x
2025-10-28 12:28:45 +00:00
Livio SpringandGitHub c9ac1ce344 feat(api): move authorization service to v2 (#10914)
# Which Problems Are Solved

As part of our efforts to simplify the structure and versions of our
APIs, were moving all existing v2beta endpoints to v2 and deprecate
them. They will be removed in Zitadel V5.

# How the Problems Are Solved

- This PR moves the authorization v2beta service and its endpoints to a
corresponding v2 version. The v2beta service and endpoints are
deprecated.
- The docs are moved to the new GA service and its endpoints. The v2beta
is not displayed anymore.
- The comments and have been improved and, where not already done, moved
from swagger annotations to proto.
- All required fields have been marked with (google.api.field_behavior)
= REQUIRED and validation rules have been added where missing.
- The `organization_id` to create an authorization is now required to be
always passed. There's no implicit fallback to the project's
organization anymore.
- The `user_id` filter has been removed in favor of the recently added
`in_user_ids` filter.
- The returned `Authorization` object has been reworked to return
`project`, `organization` and `roles` as objects like the granted `user`
already was.
- Additionally the `roles` now not only contain the granted `role_keys`,
but also the `display_name` and `group`. To implement this the query has
been updated internally. Existing APIs are unchanged and still return
just the keys.

# Additional Changes

None

# Additional Context

- part of https://github.com/zitadel/zitadel/issues/10772
- closes #10746 
- requires backport to v4.x
2025-10-28 12:11:12 +00:00
196eaa84d2 fix(user): auth option while listing user metadata (#10968)
# Which Problems Are Solved

A user from `org A` with `ORG_USER_MANAGER` role in `org B` is unable to
list user metadata for a user in `org B`.

# How the Problems Are Solved

The `auth.option` is set to a specific permission (`user.read`) in the
API definition of `ListUserMetadata`, which causes the interceptors to
check for this specific permission. In this case, there is no specific
check for org membership of a user (from org A) in a target organization
(org B), and hence the call fails even though the user has the necessary
permissions.

This has been fixed by setting the `auth.option` to `authenticated`, and
the necessary [permission checks are handled in the
query-layer](https://github.com/zitadel/zitadel/blob/main/internal/query/user_metadata.go#L173).

# Additional Changes
N/A

# Additional Context
- Closes #10925

---------

Co-authored-by: Marco A. <[email protected]>
2025-10-28 11:24:50 +00:00
Gayathri VijayanandGitHub da63abd1ad fix(metrics): incorrect mapping of grpc status codes in the grpc_server_grpc_status_code_total metric (#10989)
# Which Problems Are Solved

Requests without errors were mapped being mapped to GRPC status code
`Unknown`, which were then being mapped as HTTP `500` status code.

# How the Problems Are Solved

By deriving the grpc status codes from the error only when there's an
error.
When the error is `nil`, the grpc status code is set to 0 (`OK`).

# Additional Changes

N/A

# Additional Context
- Closes #10884
2025-10-28 11:36:18 +01:00
Max PeintnerandGitHub d5d68aed4b fix(login): Improve Passkey Authentication Error Handling & Testing (#10971)
# Which Problems Are Solved

This PR enhances the passkey authentication flow with comprehensive
error handling, full internationalization support, and extensive test
coverage.

# How the Problems Are Solved

I18n:
- Replaced all hard-coded error messages with i18n translation keys
- Consistent error messaging throughout the passkey flow
- Added specific error handling for passkey cancellation
(NotAllowedError)
- Implemented fallback errors for undefined/missing responses
- Better error messages for:
  - Session retrieval failures
  - Challenge request failures
  - User verification errors
  - Redirect determination issues

Tests:
- Added `login-passkey.test.tsx` with 100+ test cases covering:
  - Successful verification flows
  - Error scenarios and edge cases
  - Props handling
  - Component lifecycle
- Added passkeys.test.ts with server-side function tests:
  - Session cookie retrieval
  - User validation
  - Custom lifetime handling
  - Critical fallback error paths
  
Try-catch blocks around critical user retrieval operations
Defensive checks for undefined responses from completeFlowOrGetUrl
Support for custom lifetime parameters
Cleaner error propagation
2025-10-27 14:38:04 +00:00
c4221a9c0f refactor: invoker implementations and clean up code (#10962)
This pull request refactors the command execution and transaction
handling logic within the `domain` package. The primary goal is to
simplify the invoker chain, clarify transaction management, and improve
the overall structure for better maintainability and readability.

### Key Changes:

- **Simplified Invoker Chain**: The previous chain of invokers has been
refactored. A new `transactionInvoker` is introduced to explicitly
manage database transactions for commands that require them. This
responsibility is no longer spread across different parts of the
invocation flow.
- **`Transactional` Interface**: A new `Transactional` interface has
been introduced. Commands that need to run within a database transaction
now implement this interface. This provides a clear and explicit
contract for transactional operations.
- **Consolidated Transaction Logic**: The logic for starting,
committing, and rolling back transactions is now centralized within the
`transactionInvoker` and the `eventStoreInvoker`. The `EnsureTx` method
on `InvokeOpts` has been removed, and transaction handling is now
managed automatically by the invocation framework.
- **Improved Event Handling**: The `eventStoreInvoker` and its
`eventCollector` have been rewritten to be more robust and to correctly
handle nested and batched commands, ensuring that all events are
collected and published within the same transaction.
- **Code Cleanup**: A significant amount of now-unused code, including
the old `invoker_test.go`, has been removed. Various comments and
variable declarations have also been cleaned up.
- **Updated Command Implementations**: All commands in the `domain`
package (e.g., `ActivateOrgCommand`, `DeactivateOrgCommand`,
`DeleteOrgCommand`, `UpdateOrgCommand`) have been updated to use the new
`Transactional` interface where appropriate, removing manual transaction
management.
- **Enhanced Testing**: Tests have been added and updated to cover the
new transaction and event handling logic, ensuring the refactoring is
sound.
- **Use `PrimaryKeyCondition`**: Use the
`repository.PrimaryKeyCondition(...)` method instead of using
`database.And(...)` where possible.

These changes lead to a cleaner, more decoupled architecture for command
handling in ZITADEL.

---------

Co-authored-by: Marco A. <[email protected]>
2025-10-27 14:04:06 +00:00
9dc127ddb5 fix(login): Prevent double execution of IDP callback token and improve architecture (#10948)
Closes #10828 

# Which Problems Are Solved

The IDP callback flow was calling retrieveIDPIntent() twice, causing
single-use token failures with error: "Intent Token is invalid". This
occurred due to Next.js 15's dynamicIO feature triggering double renders

# How the Problems Are Solved

Completely refactored the IDP callback architecture to ensure single-use
tokens are consumed exactly once:

- Centralized Business Logic: Moved all IDP callback logic into a single
server action (processIDPCallback) that:
   - Consumes the token once
- Handles all 6 business scenarios (login, linking, auto-linking,
auto-creation, manual registration, account not found)
   - Integrates session creation in the same action
- Returns `{ redirect?: string; error?: string }` for client-side
navigation
- Client Component Invocation: Created `IdpProcessHandler` client
component that:
- Calls the server action from browser context (enables cookie
modification)
   - Prevents double execution with useRef
   - Handles loading states and error display
- Clean Architecture:
   - Removed 403-line success page with complex logic
   - Removed component files from `/components/idps/pages/` folder
   - Moved all UI directly into server pages
   - Created dedicated result pages with minimal params

# Additional Changes

- Added translations to all 8 supported languages

---------

Co-authored-by: Ramon <[email protected]>
2025-10-27 14:34:39 +01:00
Max PeintnerandGitHub 5d75e41d00 fix(login): generate code for passkey (#10966)
# Which Problems Are Solved

When the passkey registration page (/passkey/set) is accessed externally
with only a loginName parameter, users encounter a "Missing code in
response" error. This occurs because the registration code is only
generated for invalid sessions, but external calls typically have valid
sessions.

# How the Problems Are Solved

- Moved registration code generation outside the session validity check
in `registerPasskeyLink()`
- Code is now generated for both valid and invalid sessions when not
provided
- Simplified logic: use provided code if available, otherwise generate a
new one
2025-10-27 09:17:01 +00:00
e7ec430dbc feat(i18n): add Turkish translation file (#10922)
Add complete Turkish (tr.json) translation for authentication UI,
including login, registration, password management, MFA setup

# Which Problems Are Solved
- Turkish language support is missing in the authentication UI
- Turkish-speaking users cannot use the application in their native
language

# How the Problems Are Solved
- Added complete Turkish (tr.json) translation file for the
authentication UI
- Translated all authentication-related strings including login,
registration, password management, MFA setup, error messages, and user
verification flows
- Technical terms (Passkey, SSO, LDAP, IDP, etc.) are kept in English
for consistency

# Additional Changes
- None

# Additional Context
- Closes #10851
- This translation follows the same structure as the existing en.json
file
- All user-facing strings in the authentication flow are now available
in Turkish

Co-authored-by: Max Peintner <[email protected]>
Co-authored-by: Gayathri Vijayan <[email protected]>
2025-10-27 08:11:01 +00:00
16b21569db fix(login): improve duration undefined check (#10949)
# Which Problems Are Solved
In the login we often check if a GRPC Duration is not defined however it
can also be set to 0. Using the API it's possible to set the password
check lifetime to zero which broke the login v2.

# How the Problems Are Solved
Also check if the GRPC Duration seconds field is not 0

# Additional Context
- May help if the issue here is actually accidentally setting password
lifetime check to 0 using the API #10865

Co-authored-by: Max Peintner <[email protected]>
2025-10-27 09:03:32 +01:00
Federico CoppedeandGitHub 44b7f1013f docs: built in smtp provider warning (#10958)
Added a warning to mention that the built in SMTP provider is for
testing only, not production.

**Context:** Customers often complain about email delivery delays while
using the built in SMTP provider, and they should configure their own.
2025-10-25 10:03:56 +00:00