Commit Graph

3976 Commits

Author SHA1 Message Date
Tim Möhlmann
5ba016e123 fix(rt): release client after migration (#10788)
#  Which Problems Are Solved

Relation table migrations do not release the client after migrations are
done.

# How the Problems Are Solved

Defer releasing of the client after acquire.

# Additional Changes

- rename two filenames with typos.

# Additional Context

- none
2025-09-25 07:46:06 +00:00
Silvan
4900ac477a fix(test): increase retry tick duration in tests (#10787)
Adjust the retry tick duration in various tests to one minute to improve
reliability and reduce the frequency of retries.
2025-09-25 08:47:29 +02:00
Iraq
08f41e034e feat(idp_table_relational): adding inital idp tables for relational repository (#10334) 2025-09-24 13:19:09 +00:00
Silvan
cccfc816f6 refactor: database interaction and error handling (#10762)
This pull request introduces a significant refactoring of the database
interaction layer, focusing on improving explicitness, transactional
control, and error handling. The core change is the removal of the
stateful `QueryExecutor` from repository instances. Instead, it is now
passed as an argument to each method that interacts with the database.

This change makes transaction management more explicit and flexible, as
the same repository instance can be used with a database pool or a
specific transaction without needing to be re-instantiated.

### Key Changes

- **Explicit `QueryExecutor` Passing:**
- All repository methods (`Get`, `List`, `Create`, `Update`, `Delete`,
etc.) in `InstanceRepository`, `OrganizationRepository`,
`UserRepository`, and their sub-repositories now require a
`database.QueryExecutor` (e.g., a `*pgxpool.Pool` or `pgx.Tx`) as the
first argument.
- Repository constructors no longer accept a `QueryExecutor`. For
example, `repository.InstanceRepository(pool)` is now
`repository.InstanceRepository()`.

- **Enhanced Error Handling:**
- A new `database.MissingConditionError` is introduced to enforce
required query conditions, such as ensuring an `instance_id` is always
present in `UPDATE` and `DELETE` operations.
- The database error wrapper in the `postgres` package now correctly
identifies and wraps `pgx.ErrTooManyRows` and similar errors from the
`scany` library into a `database.MultipleRowsFoundError`.

- **Improved Database Conditions:**
- The `database.Condition` interface now includes a
`ContainsColumn(Column) bool` method. This allows for runtime checks to
ensure that critical filters (like `instance_id`) are included in a
query, preventing accidental cross-tenant data modification.
- A new `database.Exists()` condition has been added to support `EXISTS`
subqueries, enabling more complex filtering logic, such as finding an
organization that has a specific domain.

- **Repository and Interface Refactoring:**
- The method for loading related entities (e.g., domains for an
organization) has been changed from a boolean flag (`Domains(true)`) to
a more explicit, chainable method (`LoadDomains()`). This returns a new
repository instance configured to load the sub-resource, promoting
immutability.
- The custom `OrgIdentifierCondition` has been removed in favor of using
the standard `database.Condition` interface, simplifying the API.

- **Code Cleanup and Test Updates:**
  - Unnecessary struct embeddings and metadata have been removed.
- All integration and repository tests have been updated to reflect the
new method signatures, passing the database pool or transaction object
explicitly.
- New tests have been added to cover the new `ExistsDomain`
functionality and other enhancements.

These changes make the data access layer more robust, predictable, and
easier to work with, especially in the context of database transactions.
2025-09-24 10:12:31 +00:00
Max Peintner
09d09ab337 fix(login): host utility to provide correct host behind proxies (#10770)
<!--
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

When deploying the login application behind proxies or using Vercel
rewrites (e.g., `zitadel.com/login` → `login-zitadel-qa.vercel.app`),
the application was using the internal rewritten host instead of the
original user-facing host. This caused several issues:

1. **Broken Password Reset Emails**: Email links contained internal
hosts like `login-zitadel-qa.vercel.app` instead of `zitadel.com`
2. **Inconsistent User Experience**: Users would see different domains
in various parts of the flow
3. **Security Concerns**: Internal infrastructure details were exposed
to end users
4. **Scattered Logic**: Host detection logic was duplicated across
multiple files with inconsistent error handling

# How the Problems Are Solved

Created comprehensive host detection utilities in `/lib/server/host.ts`
and `/lib/client/host.ts`:

**Server-side utilities:**
- `getOriginalHost()` - Returns the original user-facing host
- `getOriginalHostWithProtocol()` - Returns host with proper protocol
(http/https)
2025-09-23 16:21:01 +00:00
Livio Spring
16906d2c2c fix(export): add sorting when searching users to prevent error (#10777)
# Which Problems Are Solved

When exporting users, an error `QUERY-AG4gs` was returned. This was due
to #10750, where the orderBy column was added to the query to prevent
the exact same error. In case there was no sorting column specified,
such as the export, the query would fail.

# How the Problems Are Solved

- Added a default sorting on `id` as we already have for the other APIs.

# Additional Changes

None

# Additional Context

- reported through support
- relates to #10750, #10415
- backport to v4.x
2025-09-23 11:39:05 +02:00
Max Peintner
637b370c17 chore(login): Extract auth flow utilities and eliminate RSC request interference (#10644)
The /login route was experiencing issues with React Server Component
(RSC) requests interfering with one-time authentication callbacks. When
users navigated to /login via client-side routing (router.push()),
Next.js automatically triggered _rsc requests that could consume
single-use createCallback tokens, breaking OIDC and SAML authentication
flows.

# Which Problems Are Solved

When users attempt to log in, Next.js automatically makes requests with
the `_rsc=1` query parameter for React Server Components. The current
implementation treats these as server errors:

```typescript
// Before
if (_rsc) {
  return NextResponse.json({ error: "No _rsc supported" }, { status: 500 });
}
```

This results in:
- Spurious 500 error logs polluting monitoring systems
- False alerts for server failures 
- Difficulty distinguishing real issues from benign RSC requests

# How the Problems Are Solved

This PR implements a comprehensive refactoring that:

- Eliminates RSC interference by providing server actions for internal
auth flow completion
- Separates concerns between external flow initiation and internal flow
completion
- Extracts shared utilities to improve code maintainability and
reusability
- Maintains full backward compatibility for external applications

# Additional Context

## New Architecture
- auth-flow.ts: Shared utilities for auth flow completion with RSC
protection
- flow-initiation.ts: Extracted OIDC/SAML flow initiation logic (~400
lines)
- auth.ts: Server actions for internal components

## Route Handler Simplification
- route.ts: Reduced from ~350 lines to ~75 lines
- External-only focus: Now handles only flow initiation for external
applications
- Removed completion logic: External apps use their own callback URLs
- Enhanced validation: Early RSC blocking and parameter validation

## Flow Logic Improvements
- Early return patterns: Guard clauses eliminate deep nesting
- Better error handling: Specific error messages for different failure
modes
- Fixed SAML flow: Addressed incomplete logic
- Consistent session handling: Unified approach across OIDC and SAML
2025-09-22 16:09:20 +00:00
Max Peintner
0a31f4ba2b fix(login): remove image optimization entirely (#10702)
This PR completely removes Next.js image optimization from the login app
by replacing all next/image components with standard HTML <img> tags and
removing the image optimization configuration.

Closes https://github.com/zitadel/zitadel-charts/issues/381

# Which Problems Are Solved

Users were encountering issue when loading images in dedicated
environments. These happened due to nextjs imaging optimizations
creating different paths for images.

# How the Problems Are Solved

- Removed Next.js Image Optimization Config
- Removed images: { unoptimized: true } configuration from
[next.config.mjs](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html)
This config was redundant since we no longer use next/image components
- Replaced next/image with standard <img> tags
2025-09-22 11:49:21 +00:00
Federico Coppede
44902e11b7 docs: update release cycle and support states URL to point to KBAs (#10602)
The page located here was split into 2 different KBAs:
- https://zitadel.com/docs/support/software-release-cycles-support

**Software release cycles:** 
- https://help.zitadel.com/zitadel-software-release-cycle

**Support states KBA:** 
- https://help.zitadel.com/zitadel-support-states

And the corresponding URLs were updated in the docs site
2025-09-22 11:29:34 +00:00
masum-msphere
295584648d feat(oidc): Added new claim in userinfo response to return all requested audience roles (#9861)
# Which Problems Are Solved

The /userinfo endpoint only returns roles for the current project, even
if the access token includes multiple project aud scopes.

This prevents clients from retrieving all user roles across multiple
projects, making multi-project access control ineffective.

# How the Problems Are Solved

Modified the /userinfo handler logic to resolve roles across all valid
project audience scopes provided in the token, not just the current
project.
Ensured that if **urn:zitadel:iam:org:projects:roles is in the scopes**,
roles from all declared project audiences are collected and included in
the response in **urn:zitadel:iam:org:projects:roles claim**.

# Additional Changes

# Additional Context

This change enables service-to-service authorization workflows and SPA
role resolution across multiple project contexts with a single token.
- Closes #9831

---------

Co-authored-by: Masum Patel <patelmasum98@gmail.com>
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
2025-09-22 09:55:21 +00:00
Iraq
e5575d6042 chore(removing dead code): removing LabelPolicyAssetsRemovedEventType event is never made (#10742)
# Which Problems Are Solved

The event `LabelPolicyAssetsRemovedEventType` is never actually made
anywhere, this is dead code, this PR will remove it
2025-09-22 06:19:34 +00:00
Stefan Benz
b6ff4ff16c fix: generated project grant id (#10747)
# Which Problems Are Solved

Project Grant ID would have needed to be unique to be handled properly
on the projections, but was defined as the organization ID the project
was granted to, so could be non-unique.

# How the Problems Are Solved

Generate the Project Grant ID even in the v2 APIs, which also includes
fixes in the integration tests.
Additionally to that, the logic for some functionality had to be
extended as the Project Grant ID is not provided anymore in the API, so
had to be queried before creating events for Project Grants.

# Additional Changes

Included fix for authorizations, when an authorization was intended to
be created for a project, without providing any organization
information, which also showed some faulty integration tests.

# Additional Context

Partially closes #10745

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-09-21 14:04:25 +00:00
Tim Möhlmann
adc8fb2013 feat(repository): add permission check option (#10756) 2025-09-19 15:08:58 +00:00
Livio Spring
2c0ee0008f fix(api): sorting on list users endpoints (#10750)
# Which Problems Are Solved

#10415 added the possibility to filter users based on metadata. To
prevent duplicate results an sql `DISTINCT` was added. This resulted in
issues if the list was sorted on string columns like `username` or
`displayname`, since they are sorted using `lower`. Using `DISTINCT`
requires the `order by` column to be part of the `SELECT` statement.

# How the Problems Are Solved

Added the order by column to the statement.

# Additional Changes

None

# Additional Context

- relates to #10415 
- backport to v4.x

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-09-18 10:17:23 +00:00
Livio Spring
57e8033b6e fix: use hash to compare user metadata value (#10749)
# Which Problems Are Solved

Depending on the metadata values (already existing), the newly created
index (#10415) cannot be created or error in the future.

# How the Problems Are Solved

- Create the index using `sha256` and change the query to use sha256 as
well when comparing bytes values such as user_metadata.
- Added a setup step to cleanup potentially created index on
`projections.user_metadata5`

# Additional Changes

None

# Additional Context

- relates to #10415 
- requires backport to v4.x
2025-09-18 09:50:56 +00:00
Silvan
22ef817d5c fix(eventstore): Make Eventstore Compatible with Relational Table Package (#10687)
Improves compatibility of eventstore and related database components
with the new relational table package.

## Which problems are solved

1. **Incompatible Database Interfaces**: The existing eventstore was
tightly coupled to the database package, which is incompatible with the
new, more abstract relational table package in v3. This prevented the
new command-side logic from pushing events to the legacy eventstore.
2. **Missing Health Checks**: The database interfaces in the new package
lacked a Ping method, making it impossible to perform health checks on
database connections.
3. **Event Publishing Logic**: The command handling logic in domain
needed a way to collect and push events to the legacy eventstore after a
command was successfully executed.

## How the problems are solved

1. **`LegacyEventstore` Interface**:
* A new `LegacyEventstore` interface is introduced in the new
`database/eventstore` . This interface exposes a `PushWithNewClient`
method that accepts the new `database.QueryExecutor` interface,
decoupling the v3 domain from the legacy implementation.
* The `internal/eventstore.Eventstore` now implements this interface. A
wrapper, PushWithClient, is added to convert the old database client
types (`*sql.DB`, `*sql.Tx`) into the new `QueryExecutor` types before
calling `PushWithNewClient`.
2. **Database Interface Updates**:
* The `database.Pool` and `database.Client` interfaces in
`storage/eventstore` have been updated to include a Ping method,
allowing for consistent health checks across different database
dialects.
* The `postgres` and `sql` dialect implementations have been updated to
support this new method.
3. **Command and Invoker Refactoring**:
* The `Commander` interface in domain now includes an `Events()
[]legacy_es.Command` method. This allows commands to declare which
events they will generate.
* The `eventCollector` in the invoker logic has been redesigned. It now
ensures a database transaction is started before executing a command.
After successful execution, it calls the `Events()` method on the
command to collect the generated events and appends them to a list.
* The `eventStoreInvoker` then pushes all collected events to the legacy
eventstore using the new `LegacyEventstore` interface, ensuring that
events are only pushed if the entire command (and any sub-commands)
executes successfully within the transaction.
4. **Testing**:
* New unit tests have been added for the invoker to verify that events
are correctly collected from single commands, batched commands, and
nested commands.

These changes create a clean bridge between the new v3 command-side
logic and the existing v1 eventstore, allowing for incremental adoption
of the new architecture while maintaining full functionality.

## Additional Information

closes https://github.com/zitadel/zitadel/issues/10442
2025-09-16 18:58:49 +02:00
Federico Coppede
41d04ffa65 docs: fix typo in default settings domain discovery description (#10743)
fixed typo:
If this setting is enabled, the user **does't not** mandatory -> If this
setting is enabled, the user doesn't have to...
2025-09-16 15:33:40 +00:00
Livio Spring
5329d50509 fix: correct user self management on metadata and delete (#10666)
# Which Problems Are Solved

This PR fixes the self-management of users for metadata and own removal
and improves the corresponding permission checks.
While looking into the problems, I also noticed that there's a bug in
the metadata mapping when using `api.metadata.push` in actions v1 and
that re-adding a previously existing key after its removal was not
possible.

# How the Problems Are Solved

- Added a parameter `allowSelfManagement` to checkPermissionOnUser to
not require a permission if a user is changing its own data.
- Updated use of `NewPermissionCheckUserWrite` including prevention of
self-management for metadata.
- Pass permission check to the command side (for metadata functions) to
allow it implicitly for login v1 and actions v1.
- Use of json.Marshal for the metadata mapping (as with
`AppendMetadata`)
- Check the metadata state when comparing the value.

# Additional Changes

- added a variadic `roles` parameter to the `CreateOrgMembership`
integration test helper function to allow defining specific roles.

# Additional Context

- noted internally while testing v4.1.x
- requires backport to v4.x
- closes https://github.com/zitadel/zitadel/issues/10470
- relates to https://github.com/zitadel/zitadel/pull/10426
2025-09-16 12:26:21 +00:00
Stefan Benz
edb227f066 fix: user grant query with user organization instead of organization … (#10732)
…of project grant

# Which Problems Are Solved

On Management API the fields for `GrantedOrgId`, `GrantedOrgName` and
`GrantedOrgDomain` were only filled if it was a usergrant for a granted
project.

# How the Problems Are Solved

Correctly query the Organization of the User again to the Organization
the Project is granted to.
Then fill in the information about the Organization of the User in the
fields `GrantedOrgId`, `GrantedOrgName` and `GrantedOrgDomain`.

# Additional Changes

Additionally query the information about the Organization the Project is
granted to, to have it available for the Authorization v2beta API.

# Additional Context

Closes #10723

---------

Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
2025-09-16 10:04:53 +00:00
Stefan Benz
b0642a5898 chore: correct org integration tests (#10708)
# Which Problems Are Solved

Eventual consistency issues.

# How the Problems Are Solved

Correctly handle timeouts and change queries to domains instead of using
the organization name.

# Additional Changes

None

# Additional Context

None

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-09-16 07:26:19 +00:00
Livio Spring
bc471b4f78 fix(service ping): log body size of reports (#10686)
# Which Problems Are Solved

The current service ping reports can run into body size limit errors and
there's no way of knowing how big the current size is.

# How the Problems Are Solved

Log the current size to have at least some insights and possibly change
bulk size.

# Additional Changes

None

# Additional Context

- noticed internally
- backport to v4.x
2025-09-16 07:04:17 +00:00
Oskar
99b43037af docs: fix import in response manipulation example (#10503)
# Which Problems Are Solved

Fixes one of the two issues mentioned in:
https://github.com/zitadel/zitadel/issues/10502

The response manipulation example has the wrong import in the Golang
code.

https://zitadel.com/docs/guides/integrate/actions/testing-response-manipulation

# How the Problems Are Solved

Changes the example document to use the right import address.

# Additional Changes

None.

# 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.
- Partially resolves #10502
- https://discord.com/channels/927474939156643850/1405813424901984380
2025-09-16 05:32:22 +00:00
Livio Spring
ee92560f32 fix(projections): handle reduce error by updating failed events (#10726)
# Which Problems Are Solved

I noticed that a failure in the projections handlers `reduce` function
(e.g. creating the statement or checking preconditions for the
statement) would not update the `failed_events2` table.
This was due to a wrong error handling, where as long as the
`maxFailureCount` was not reached, the error was returned after updating
the `failed_events2` table, which causes the transaction to be rolled
back and thus losing the update.

# How the Problems Are Solved

Wrap the error into an `executionError`, so the transaction is not
rolled back.

# Additional Changes

none

# Additional Context

- noticed internally
- requires backport to v3.x and v4.x
2025-09-15 18:32:28 +02:00
Tim Möhlmann
f6f37d3a31 fix(cache): use key versioning (#10657)
# Which Problems Are Solved

Cached object may have a different schema between Zitadel versions.

# How the Problems Are Solved

Use the curent build version in DB based cache connectors PostgreSQL and
Redis.

# Additional Changes

- Cleanup the ZitadelVersion field from the authz Instance
- Solve potential race condition on global variables in build package.

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/10648
- Obsoletes https://github.com/zitadel/zitadel/pull/10646
- Needs to be back-ported to v4 over
https://github.com/zitadel/zitadel/pull/10645
2025-09-15 09:51:54 +00:00
Rajat Singh
d2d9a2e651 docs: add guide to setup webhook.site for actions v2 (#10665)
<!--
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

Added guide to setup webhook.site

# How the Problems Are Solved

Users can now learn how to setup listener over the internet

# Additional Changes
none

# Additional Context
none

---------

Signed-off-by: Rajat Singh <rajat@zitadel.com>
Co-authored-by: Rajat Singh <rajat@zitadel.com>
2025-09-12 16:41:37 -03:00
Silvan
25ab6b2397 fix(projection): prevent skipped events written within the same microsecond (#10710)
This PR fixes a bug where projections could skip events if they were
written within the same microsecond, which can occur during high load on
different transactions.

## Problem

The event query ordering was not fully deterministic. Events created at
the exact same time (same `position`) and in the same transaction
(`in_tx_order`) were not guaranteed to be returned in the same order on
subsequent queries. This could lead to some events being skipped by the
projection logic.

## Solution

To solve this, the `ORDER BY` clause for event queries has been extended
to include `instance_id`, `aggregate_type`, and `aggregate_id`. This
ensures a stable and deterministic ordering for all events, even if they
share the same timestamp.

## Additionally changes:

* Replaced a manual slice search with the more idiomatic
`slices.Contains` to skip already projected instances.
* Changed the handling of already locked projections to log a debug
message and skip execution instead of returning an error.
* Ensures the database transaction is explicitly committed.
2025-09-12 14:26:03 +03:00
Livio Spring
25d921b20c fix: remove unnecessary details from import errors (#10703)
# Which Problems Are Solved

During the implementation of #10687, it was noticed that the import
endpoint might provide unnecessary error details.

# How the Problems Are Solved

Remove the underlying (parent) error from the error message.

# Additional Changes

none

# Additional Context

relates to #10687

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-09-12 07:50:57 +02:00
Max Peintner
a9cd3ff9c0 fix(login): Safari Cookie Issues in Development Mode (#10594)
Safari was not creating session cookies during local development,
causing authentication failures. This was due to nextjs default setting
of SameSite cookie property.
We explicitly set "strict" for session cookies now.

Closes #10473 

# Which Problems Are Solved

Authentication Issues with Safari in local development

# How the Problems Are Solved

- Cleaner API: Replaced confusing sameSite boolean/string parameters
with iFrameEnabled boolean
- Better logic flow:

iFrameEnabled: true → sameSite: "none" (for iframe embedding)
Production → sameSite: "strict" (maximum security)
2025-09-11 15:01:24 +00:00
Max Peintner
1a42e99329 chore(login): Remove Vercel Analytics from login application (#10701)
This PR removes the Vercel Analytics integration from the login
application to reduce external dependencies and improve privacy.

# Which Problems Are Solved

cleaner csp

# How the Problems Are Solved

- Removed dependency: Uninstalled @vercel/analytics package from
package.json
- Updated layout component: Removed Analytics import and component usage
from layout.tsx
- Updated Content Security Policy: Removed Vercel domains
(https://va.vercel-scripts.com and https://vercel.com) from CSP
configuration in csp.js
2025-09-11 12:10:09 +00:00
Max Peintner
b6cbb68428 fix(login): MFA session validation to support multiple authentication methods (#10610)
Fixed an issue in `isSessionValid()` where users with multiple
configured MFA methods (e.g., TOTP and U2F) would have their sessions
incorrectly invalidated. The function previously used exclusive if-else
logic that only checked the first matching method, causing validation to
fail even when other configured methods were successfully verified.

Closes #10529 

# Which Problems Are Solved

[#10529](https://github.com/zitadel/zitadel/issues/10529)

# How the Problems Are Solved

- Replaced exclusive if-else if chain with inclusive validation logic
- Session is now considered valid if ANY configured MFA method has been
verified
- Improved error logging to show all configured methods and their
verification status

Example: A user with both TOTP and U2F configured can now successfully
authenticate using either method, whereas previously the session would
be invalid if they used U2F but TOTP was checked first.
2025-09-11 10:36:39 +02:00
Silvan
136363deda fix(projection): Prevent race condition with event push (#10676)
A timing issue (a race condition) was identified in our event processing
system. Under specific circumstances, it was possible for the system to
skip processing certain events, leading to potential data
inconsistencies.

## Which problems are solved

The system tracks its progress through the event log using timestamps.
The issue occurred because we were using the timestamp from the start of
a database transaction. If a query to read new events began after the
transaction started but before the new event was committed, the query
would not see the new event and would fail to process it.

## How the problems are solved

The fix is to change which timestamp is used for tracking. We now use
the precise timestamp of when the event is actually written to the
database. This ensures that the event's timestamp is always correctly
ordered, closing the timing gap and preventing the race condition.

This change enhances the reliability and integrity of our event
processing pipeline. It guarantees that all events are processed in the
correct order and eliminates the risk of skipped events, ensuring data
is always consistent across the system.

## Additional information

original fix: https://github.com/zitadel/zitadel/pull/10560
2025-09-10 10:06:51 +00:00
Tim Möhlmann
54554b8fb9 perf: drop instance position index (#10626)
# Which Problems Are Solved

There was an left-behind index introduced to optimize the old and
removed event execution handler. The index confuses prostgres and it
sometimes picks this index in favor of the projection specific index.
This sometimes leads to bad query performance in the projectio handlers.

# How the Problems Are Solved

Drop the index

# Additional Changes

- none

# Additional Context

- Forgotten in https://github.com/zitadel/zitadel/pull/10564
2025-09-10 09:26:22 +00:00
Ramon
b694b25cdf fix(console): improve actions creation dropdowns #10596 (#10677)
# Which Problems Are Solved
Actions V2 Method names got cut off in the creation dropdown
<img width="668" height="717" alt="old modal"
src="https://github.com/user-attachments/assets/e3dda16d-5326-464e-abc7-67a8b146037c"
/>

# How the Problems Are Solved
The modal now first requires a Service to be set and only afterwards are
users allowed set Methods. This way we can cut out the Service-Names
from the Method-Name leading to cleaner and shorter names.
<img width="796" height="988" alt="new modal"
src="https://github.com/user-attachments/assets/5002afdf-b639-44ef-954a-5482cca12f96"
/>


# Additional Changes
Changed the Modal dataloading to use Tanstack Query

# Additional Context
- Closes #10596
2025-09-10 09:04:45 +00:00
Ramon
5cde52148f fix(console): Add login v2 url to identity providers (#10583)
# Which Problems Are Solved

When using login V2 the Callback URL for an Identity Provider is
different. When following the guideance in the console and using Login
V2 users will use the wrong callback url.

<img width="1234" height="323" alt="grafik"
src="https://github.com/user-attachments/assets/8632ecf2-d9e4-4e3b-8940-2bf80baab8df"
/>


# How the Problems Are Solved
I have added the correct Login V2 url to the identity providers and
updated our docs.

<img width="628" height="388" alt="grafik"
src="https://github.com/user-attachments/assets/2dd4f4f9-d68f-4605-a52e-2e51069da10e"
/>

# Additional Changes
Small refactorings and porting some components over to ChangeDetection
OnPush

# 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 #10461

---------

Co-authored-by: Max Peintner <max@caos.ch>
2025-09-10 07:05:55 +00:00
Livio Spring
e158f9447e fix(oidc): ignore invalid id_token_hints (#10682)
# Which Problems Are Solved

Invalid id_tokens used as `id_token_hint` on the authorization endpoints
currently return an error, resp. get display on the endpoint itself.

# How the Problems Are Solved

Ignore invalid id_token_hint errors and just log them.

# Additional Changes

None

# Additional Context

- closes https://github.com/zitadel/zitadel/issues/10673
- backport to v4.x
2025-09-10 06:25:25 +00:00
Stefan Benz
492f1826ee chore: move gofakeit integration testing calls (#10684)
# Which Problems Are Solved

Flakiness and conflicts in value from gofakeit.

# How the Problems Are Solved

Move Gofakeit calls to the integration package, to guarantee proper
usage and values for integration testing.

# Additional Changes

None

# Additional Context

None
2025-09-10 09:00:31 +03:00
Max Peintner
b9b9baf67f fix: Registration Form Legal Checkbox Logic (#10597)
Closes #10498

The registration form's legal checkboxes had incorrect validation logic
that prevented users from completing registration when only one legal
document (ToS or Privacy Policy) was configured, or when no legal
documents were required.

additionally removes a duplicate description for "or use Identity
Provider"

# Which Problems Are Solved

Having only partial legal documents was blocking users to register. The
logic now conditionally renders checkboxes and checks if all provided
documents are accepted.

# How the Problems Are Solved

- Fixed checkbox validation: Now properly validates based on which legal
documents are actually available
- acceptance logic: Only requires acceptance of checkboxes that are
shown
- No legal docs support: Users can proceed when no legal documents are
configured
- Proper state management: Fixed checkbox state tracking and mixed-up
test IDs

---------

Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
2025-09-09 07:37:32 +00:00
Livio Spring
a0c3ccecf7 fix: use a single translator for middleware (#10633)
# Which Problems Are Solved

Comparing the v3 and v4 deployments we noticed an increase in memory
usage. A first analysis revealed that it might be related to the
(multiple) initialization of the `i18n.Translator`, partially related

# How the Problems Are Solved

Initialize the tranlator once (apart from the translator interceptor,
which uses context / request specific information) and pass it to all
necessary middleware.

# Additional Changes

Removed unnecessary error return parameter from the translator
initialization.

# Additional Context

- noticed internally
- backport to v4.x
2025-09-09 06:34:59 +00:00
Livio Spring
79809d0199 fix(actions v2): send event_payload on event executions again (#10651)
# Which Problems Are Solved

It was noticed that on actions v2 when subscribing to events, the
webhook would always receive an empty `event_payload`:
```
{
    "aggregateID": "336494809936035843",
    "aggregateType": "user",
    "resourceOwner": "336392597046099971",
    "instanceID": "336392597046034435",
    "version": "v2",
    "sequence": 1,
    "event_type": "user.human.added",
    "created_at": "2025-09-05T08:55:36.156333Z",
    "userID": "336392597046755331",
    "event_payload":
    {}
}
```

The problem was due to using `json.Marshal` on the `Event` interface,
where the underlying `BaseEvent` prevents the data to be marshalled:

131f70db34/internal/eventstore/event_base.go (L38)

# How the Problems Are Solved

The `Event`s `Unmarshal` function is used with a `json.RawMessage`.

# Additional Changes

none

# Additional Context

- closes https://github.com/zitadel/zitadel/issues/10650
- requires backport to v4.x
2025-09-09 05:28:29 +00:00
Livio Spring
2dbe21fb30 feat(service ping): add additional resource counts (#10621)
# Which Problems Are Solved

Using the service ping, we want to have some additional insights to how
zitadel is configured. The current resource count report contains
already some amount of configured policies, such as the login_policy.
But we do not know if for example MFA is enforced.

# How the Problems Are Solved

- Added the following counts to the report:
  - service users per organization
  - MFA enforcements (though login policy)
  - Notification policies with password change option enabled
  - SCIM provisioned users (using user metadata)
- Since all of the above are conditional based on at least a column
inside a projection, a new `migration.CountTriggerConditional` has been
added, where a condition (column values) and an option to track updates
on that column should be considered for the count.
- For this to be possible, the following changes had to be made to the
existing sql resources:
- the `resource_name` has been added to unique constraint on the
`projection.resource_counts` table
- triggers have been added / changed to individually track `INSERT`,
`UPDATE`(s) and `DELETE` and be able to handle conditions
- an optional argument has been added to the
`projections.count_resource()` function to allow providing the
information to `UP` or `DOWN` count the resource on an update.

# Additional Changes

None

# Additional Context

- partially solves #10244 (reporting audit log retention limit will be
handled in #10245 directly)
- backport to v4.x
2025-09-08 16:30:03 +00:00
Stefan Benz
ef058c8de6 fix: org remove taken into account during username changes (#10617)
# Which Problems Are Solved

For instance settings related to username changes, already removed
organizations were still processed.

# How the Problems Are Solved

Do no process already removed organizations.

# Additional Changes

None

# Additional Context

None

---------

Co-authored-by: Marco A. <marco@zitadel.com>
2025-09-08 13:58:14 +00:00
Stefan Benz
75774eb64c chore: fix org v2beta integration tests (#10655)
# Which Problems Are Solved

Flakiness in integration tests for organization v2beta service.

# How the Problems Are Solved

Fix eventual consistent handling of integration tests.

# Additional Changes

None

# Additional Context

None

---------

Co-authored-by: Marco A. <marco@zitadel.com>
2025-09-08 11:43:16 +00:00
Stefan Benz
8909b9a2a6 feat: http provider signing key addition (#10641)
# Which Problems Are Solved

HTTP Request to HTTP providers for Email or SMS are not signed.

# How the Problems Are Solved

Add a Signing Key to the HTTP Provider resources, which is then used to
generate a header to sign the payload.

# Additional Changes

Additional tests for query side of the SMTP provider.

# Additional Context

Closes #10067

---------

Co-authored-by: Marco A. <marco@zitadel.com>
2025-09-08 11:00:04 +00:00
Tim Möhlmann
4440579f0a chore(deps): update to latest 1.24 go toolchain (#10667)
# Which Problems Are Solved

Update the Go toolchain to the latest bugfix release, so we include
latest security fixes in the standard library.

# How the Problems Are Solved

Set the toolchain directive to 1.24.7

# Additional Changes

- go mod tidy

# Additional Context

- https://go.dev/doc/devel/release#go1.24.0

Co-authored-by: Marco A. <marco@zitadel.com>
2025-09-08 09:32:36 +00:00
Gayathri Vijayan
51e12e224d feat(actionsv2): Propagate request headers in actions v2 (#10632)
# Which Problems Are Solved

This PR adds functionality to propagate request headers in actions v2. 

# How the Problems Are Solved
The new functionality is added to the`ExecutionHandler` interceptors,
where the incoming request headers (from a list of allowed headers to be
forwarded) are set in the payload of the request before calling the
target.

# Additional Changes
This PR also contains minor fixes to the Actions V2 example docs. 

# Additional Context
- Closes #9941

---------

Co-authored-by: Marco A. <marco@zitadel.com>
2025-09-08 08:50:52 +00:00
Tim Möhlmann
a06ae2c835 perf(cache): use redis unlink for key deletion (#10658)
# Which Problems Are Solved

The usage of the Redis `DEL` command showed blocking and slowdowns
during load-tests.

# How the Problems Are Solved

Use [`UNLINK`](https://redis.io/docs/latest/commands/UNLINK/) instead.

# Additional Changes

- none

# Additional Context

- closes https://github.com/zitadel/zitadel/issues/8930
2025-09-08 08:21:32 +00:00
Silvan
869282ca49 fix(repo): correct mapping for domains (#10653)
This pull request fixes an issue where the repository would fail to scan
organization or instance structs if the `domains` column was `NULL`.

## Which problems are solved

If the `domains` column of `orgs` or `instances` was `NULL`, the
repository failed scanning into the structs. This happened because the
scanning mechanism did not correctly handle `NULL` JSONB columns.

## How the problems are solved

A new generic type `JSONArray[T]` is introduced, which implements the
`sql.Scanner` interface. This type can correctly scan JSON arrays from
the database, including handling `NULL` values gracefully.

The repositories for instances and organizations have been updated to
use this new type for the domains field. The SQL queries have also been
improved to use `FILTER` with `jsonb_agg` for better readability and
performance when aggregating domains.

## Additional changes
* An unnecessary cleanup step in the organization domain tests for
already removed domains has been removed.
* The `pgxscan` library has been replaced with `sqlscan` for scanning
`database/sql`.Rows.
* Minor cleanups in integration tests.
2025-09-08 09:35:31 +02:00
Silvan
69be6b9416 fix(makefile): revert wrong integration test settings (#10649)
[This
PR](61cab8878e)
introduced wrong parameters to the integration tests of the backend.
This PR reverts these changes
2025-09-05 09:52:17 +00:00
Silvan
61cab8878e feat(backend): state persisted objects (#9870)
This PR initiates the rework of Zitadel's backend to state-persisted
objects. This change is a step towards a more scalable and maintainable
architecture.

## Changes

* **New `/backend/v3` package**: A new package structure has been
introduced to house the reworked backend logic. This includes:
* `domain`: Contains the core business logic, commands, and repository
interfaces.
* `storage`: Implements the repository interfaces for database
interactions with new transactional tables.
  * `telemetry`: Provides logging and tracing capabilities.
* **Transactional Tables**: New database tables have been defined for
`instances`, `instance_domains`, `organizations`, and `org_domains`.
* **Projections**: New projections have been created to populate the new
relational tables from the existing event store, ensuring data
consistency during the migration.
* **Repositories**: New repositories provide an abstraction layer for
accessing and manipulating the data in the new tables.
* **Setup**: A new setup step for `TransactionalTables` has been added
to manage the database migrations for the new tables.

This PR lays the foundation for future work to fully transition to
state-persisted objects for these components, which will improve
performance and simplify data access patterns.

This PR initiates the rework of ZITADEL's backend to state-persisted
objects. This is a foundational step towards a new architecture that
will improve performance and maintainability.

The following objects are migrated from event-sourced aggregates to
state-persisted objects:

* Instances
  * incl. Domains
* Orgs
  * incl. Domains

The structure of the new backend implementation follows the software
architecture defined in this [wiki
page](https://github.com/zitadel/zitadel/wiki/Software-Architecturel).

This PR includes:

* The initial implementation of the new transactional repositories for
the objects listed above.
* Projections to populate the new relational tables from the existing
event store.
* Adjustments to the build and test process to accommodate the new
backend structure.

This is a work in progress and further changes will be made to complete
the migration.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Iraq Jaber <iraq+github@zitadel.com>
Co-authored-by: Iraq <66622793+kkrime@users.noreply.github.com>
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
2025-09-05 09:54:34 +01:00
Marco A.
8cc79c1376 chore(dep): update zitadel SAML library (#10640)
# Which Problems Are Solved

The change partially addresses
https://github.com/zitadel/zitadel/issues/5630 , specifically the part
about "Order of SAML attributes are non-compliant".

# How the Problems Are Solved

  - Upgrade of the zitadel SAML library

# Additional Context

- Partially addresses #5630
- Depends on https://github.com/zitadel/saml/pull/106
2025-09-04 10:47:21 +02:00