Commit Graph

489 Commits

Author SHA1 Message Date
Silvan
19d1ab9c94 fix(projections): overhaul the event projection system (#10560)
This PR overhauls our event projection system to make it more robust and
prevent skipped events under high load. The core change replaces our
custom, transaction-based locking with standard PostgreSQL advisory
locks. We also introduce a worker pool to manage concurrency and prevent
database connection exhaustion.

### Key Changes

* **Advisory Locks for Projections:** Replaces exclusive row locks and
inspection of `pg_stat_activity` with PostgreSQL advisory locks for
managing projection state. This is a more reliable and standard approach
to distributed locking.
* **Simplified Await Logic:** Removes the complex logic for awaiting
open transactions, simplifying it to a more straightforward time-based
filtering of events.
* **Projection Worker Pool:** Implements a worker pool to limit
concurrent projection triggers, preventing connection exhaustion and
improving stability under load. A new `MaxParallelTriggers`
configuration option is introduced.

### Problem Solved

Under high throughput, a race condition could cause projections to miss
events from the eventstore. This led to inconsistent data in projection
tables (e.g., a user grant might be missing). This PR fixes the
underlying locking and concurrency issues to ensure all events are
processed reliably.

### How it Works

1. **Event Writing:** When writing events, a *shared* advisory lock is
taken. This signals that a write is in progress.
2.  **Event Handling (Projections):**
* A projection worker attempts to acquire an *exclusive* advisory lock
for that specific projection. If the lock is already held, it means
another worker is on the job, so the current one backs off.
* Once the lock is acquired, the worker briefly acquires and releases
the same *shared* lock used by event writers. This acts as a barrier,
ensuring it waits for any in-flight writes to complete.
* Finally, it processes all events that occurred before its transaction
began.

### Additional Information

* ZITADEL no longer modifies the `application_name` PostgreSQL variable
during event writes.
*   The lock on the `current_states` table is now `FOR NO KEY UPDATE`.
*   Fixes https://github.com/zitadel/zitadel/issues/8509

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
(cherry picked from commit 0575f67e94)
2025-09-15 09:41:49 +02:00
Max Peintner
462e266604 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>
(cherry picked from commit b9b9baf67f)
2025-09-15 08:30:09 +02:00
Stefan Benz
1a7cd6e1af 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>
(cherry picked from commit 8909b9a2a6)
2025-09-15 08:26:41 +02:00
Marco A.
8cf623d5b5 feat: List users by metadata (#10415)
# Which Problems Are Solved

Some users have reported the need of retrieving users given a metadata
key, metadata value or both. This change introduces metadata search
filter on the `ListUsers()` endpoint to allow Zitadel users to search
for user records by metadata.

The changes affect only v2 APIs.

# How the Problems Are Solved

- Add new search filter to `ListUserRequest`: `MetaKey` and `MetaValue`
  - Add SQL indices on metadata key and metadata value
  - Update query to left join `user_metadata` table

# Additional Context

  - Closes #9053
  - Depends on https://github.com/zitadel/zitadel/pull/10567

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>

(cherry picked from commit 8df402fb4f)
2025-09-15 08:22:53 +02:00
Tim Möhlmann
a306c3db0f fix(cache): set version in instance by host (#10645)
# Which Problems Are Solved

We noticed a rapid growth of Redis memory usage. Instance By host did
not set the zitadel version, so instance entries got set on every
request again.

# How the Problems Are Solved

Set the version

# Additional Changes

- none

# Additional Context

- internal incident
2025-09-05 05:52:27 +00:00
Tim Möhlmann
2727fa719d perf(actionsv2): execution target router (#10564)
# Which Problems Are Solved

The event execution system currently uses a projection handler that
subscribes to and processes all events for all instances. This creates a
high static cost because the system over-fetches event data, handling
many events that are not needed by most instances. This inefficiency is
also reflected in high "rows returned" metrics in the database.

# How the Problems Are Solved

Eliminate the use of a project handler. Instead, events for which
"execution targets" are defined, are directly pushed to the queue by the
eventstore. A Router is populated in the Instance object in the authz
middleware.

- By joining the execution targets to the instance, no additional
queries are needed anymore.
- As part of the instance object, execution targets are now cached as
well.
- Events are queued within the same transaction, giving transactional
guarantees on delivery.
- Uses the "insert many fast` variant of River. Multiple jobs are queued
in a single round-trip to the database.
- Fix compatibility with PostgreSQL 15

# Additional Changes

- The signing key was stored as plain-text in the river job payload in
the DB. This violated our [Secrets
Storage](https://zitadel.com/docs/concepts/architecture/secrets#secrets-storage)
principle. This change removed the field and only uses the encrypted
version of the signing key.
- Fixed the target ordering from descending to ascending.
- Some minor linter warnings on the use of `io.WriteString()`.

# Additional Context

- Introduced in https://github.com/zitadel/zitadel/pull/9249
- Closes https://github.com/zitadel/zitadel/issues/10553
- Closes https://github.com/zitadel/zitadel/issues/9832
- Closes https://github.com/zitadel/zitadel/issues/10372
- Closes https://github.com/zitadel/zitadel/issues/10492

---------

Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
(cherry picked from commit a9ebc06c77)
2025-09-01 08:16:52 +02:00
Adam Kida
678f9ad448 feat(typescript): add i18n for input labels in Login V2 (#10233)
# Which Problems Are Solved

- Most inputs have hardcoded label

# How the Problems Are Solved

- add usage of i18n library for every label
- add labels to i18n translation files

# Additional Changes

- fixed key used in `device-code-form.tsx` by submit button
- `v2-default.json` was update and contains all values from login app
not only newly added key for labels.

# Additional Context

N.A

---------

Co-authored-by: David Skewis <david@zitadel.com>
Co-authored-by: Max Peintner <max@caos.ch>
(cherry picked from commit 832e78f9bc)
2025-08-29 13:18:05 +02:00
Marco A.
df0f033880 chore: move converter methods users v2 to separate converter package + add tests (#10567)
# Which Problems Are Solved

As requested by @adlerhurst in
https://github.com/zitadel/zitadel/pull/10415#discussion_r2298087711 , I
am moving the refactoring of v2 user converter methods to a separate PR

# How the Problems Are Solved

Cherry-pick 648c234caf

# Additional Context

Parent of https://github.com/zitadel/zitadel/pull/10415

(cherry picked from commit b604615cab)
2025-08-28 09:23:04 +02:00
Gayathri Vijayan
a3dac4d5cd feat(saml): add SignatureMethod config for SAML IDP (#10520)
# Which Problems Are Solved
When a SAML IDP is created, the signing algorithm defaults to
`RSA-SHA1`.
This PR adds the functionality to configure the signing algorithm while
creating or updating a SAML IDP. When nothing is specified, `RSA-SHA1`
is the default.

Available options:
* RSA_SHA1
* RSA_SHA256
* RSA_SHA512

# How the Problems Are Solved

By introducing a new optional config to specify the Signing Algorithm.

# Additional Changes
N/A

# Additional Context
- Closes #9842

An existing bug in the UpdateSAMLProvider API will be fixed as a
followup in a different
[PR](https://github.com/zitadel/zitadel/pull/10557).

---------

Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
(cherry picked from commit 255d42da65)
2025-08-28 09:22:59 +02:00
Livio Spring
95848219d5 fix: correctly escape backslash in queries (#10522)
# Which Problems Are Solved

While investigating a support ticket, it was discovered that some
queries using equals or not equals without case matching were not
correctly escaping the value to compare. If a value contained a
backslash (`\`) the row would not match.

# How the Problems Are Solved

- Fixed the escaping for backslash for `like` operations.
- Changed equals and not equals comparison without case matching to `=`
instead of `like`.

# Additional Changes

None

# Additional Context

- related to a support request
- requires backport to v.3 and v4.x

(cherry picked from commit 6c8d027e72)
2025-08-21 09:25:28 +02:00
Copilot
e9bf92e987 perf(oidc): introspection endpoint query optimization (#10392)
The `/introspect` endpoint showed poor performance during v4 load
testing due to an inefficient database query in
`internal/query/introspection_client_by_id.sql`. This PR optimizes the
query structure to significantly improve performance.

## Query Optimizations

**UNION → UNION ALL**: Changed expensive `UNION` to `UNION ALL` since
`client_id` is unique across both API and OIDC config tables,
eliminating unnecessary deduplication overhead (30-50% improvement
expected).

**Simplified Keys CTE**: Optimized the keys lookup logic by using
`$2::text as client_id` instead of `identifier as client_id` with `group
by`, and added explicit `$3 = true` condition to the LEFT JOIN for
better query planning.

**Enhanced Readability**: Added consistent table aliases (c, a, p, o, k)
for better maintainability.

## Benefits

- **Zero-downtime deployment**: Uses existing database indexes, no
schema changes required
- **Secondary performance gains**: Other similar queries
(`oidc_client_by_id.sql`, `userinfo_client_by_id.sql`) will also benefit
from the optimizations
- **Minimal code changes**: Only 13 lines added, 9 lines removed in the
SQL query
- **Backward compatible**: Same result set and API behavior

The optimized query maintains the same functionality while providing
significant performance improvements for the introspection endpoint
under high concurrent load.

Fixes #10389.

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 Share your feedback on Copilot coding agent for the chance to win a
$200 gift card! Click
[here](https://survey.alchemer.com/s3/8343779/Copilot-Coding-agent) to
start the survey.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: muhlemmer <5411563+muhlemmer@users.noreply.github.com>
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
(cherry picked from commit a28950661c)
2025-08-21 09:25:25 +02:00
Marco A.
db7096628a fix: remove legacy events (#10464)
# Which Problems Are Solved

Some events that are now unused are clogging the event queue from time
to time.

# How the Problems Are Solved

Remove the events described in #10458

# Additional Changes

- Updated `stringer` and `enumer` in Makefile target `core_generate_all`
to resolve generated files compilation issues

# Notes
It looks like there are a lot of changes, but most of it is fixing
translation files. I suggest doing a review per-commit

# Additional Context

- Closes #10458
- Depends on https://github.com/zitadel/zitadel/pull/10513

(cherry picked from commit e8a9cd6964)
2025-08-21 09:24:03 +02:00
Iraq
dbe0bdbe73 fix(api): fix for ListAppKeys() not returning app keys (#10465)
# Which Problems Are Solved

`ListAppKeys()` does not work properly, in that it does not return any
app keys.

# How the Problems Are Solved

The issue stems from a mistake SQL query not joining the
`projections.authn_keys2` table to `projections.projects4` instead of
joining to `projections.apps7`

# Additional Changes

`ListAppKeys()` returns the app key IDs in order of their creation

- Closes https://github.com/zitadel/zitadel/issues/10420
- backport to v4.x

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
(cherry picked from commit a637ae5aa5)
2025-08-15 15:20:40 +02:00
Silvan
4efa59d61a fix(projections): pass context to statement execution method (#10328)
## Which problems are solved

The execution of statements of projections did not have the context
present.

## How the problems were solved

Pass the context to the execute function

## Additional info

This change is required to use the repositories of the relational tables
in projections.

(cherry picked from commit 20e7807ee5)
2025-08-15 14:47:44 +02:00
kkrime
0194a68b3e fix(projections): added check to make sure there cannot be 2 projections for the same table (#10439)
# Which Problems Are Solved

It should not be possible to start 2 projections with the same name.

If this happens, it can cause issues with the event store such as events
being skipped/unprocessed and can be very hard/time-consuming to
diagnose.

# How the Problems Are Solved

A check was added to make sure no 2 projections have the same table

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

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
(cherry picked from commit 10bd747105)
2025-08-15 14:46:17 +02:00
Livio Spring
00f2bde91f fix(idp): make external id check case insensitive (#10460)
# Which Problems Are Solved

When searching for an existing external userID from an IdP response, the
comparison is case sensitive. This can lead to issues esp. when using
SAML, since the `NameID`'s value case could change. The existing user
would not be found and the login would try to create a new one, but fail
since the uniqueness check of IdP ID and external userID is not case
insensitive.

# How the Problems Are Solved

Search case insensitive for external useriDs.

# Additional Changes

None

# Additional Context

- closes #10457, #10387
- backport to v3.x

(cherry picked from commit 4630b53313)
2025-08-15 14:45:40 +02:00
Gayathri Vijayan
55dbc74cb3 fix: use correct the userID column name in permissions v2 check (#10467)
# Which Problems Are Solved

When `Permission Check V2` is enabled, calls to the `ListPasskeys` and
`ListAuthenticationFactors` APIs fail with the following error:
```
ERROR:  missing FROM-clause entry for table "users14"
```

# How the Problems Are Solved
By using the right UserID column
(`projections.user_auth_methods5.user_id`) in the permission clause in
the `userAuthMethod` query

# Additional Changes
N/A

# Additional Context
- Closes #10386

(cherry picked from commit 45cc6e9bb1)
2025-08-15 14:45:38 +02:00
Livio Spring
1873ae0190 fix: allow disabling projections for specific instances (#10421)
# Which Problems Are Solved

The current handling of event subscriptions for actions is bad, esp. on
instances with a lot of events
(https://github.com/zitadel/zitadel/issues/9832#issuecomment-2866236414).
This led to severe problems on zitadel.cloud for such instances.

# How the Problems Are Solved

As a workaround until the handling can be improved, we introduce an
option for projections to be disabled completely for specific instances:
`SkipInstanceIDs`

# Additional Changes

None

# Additional Context

- relates to https://github.com/zitadel/zitadel/issues/9832

(cherry picked from commit 67efddcbc6)
2025-08-12 14:04:35 +02:00
Silvan
1470ae08fc fix: query organization directly from event store (#10463)
Querying an organization by id allowed to trigger the org projection.
This could lead to performance impacts if the projection gets triggered
too often.

Instead of executing the trigger the organization by id query is now
always executed on the eventstore and reduces all event types required
of the organization requested.

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-08-12 11:47:00 +02:00
Gayathri Vijayan
5df28465a4 fix(sessions): add an expiration date filter to list sessions api (#10384)
# Which Problems Are Solved

The deletion of expired sessions does not go through even though a
success response is returned to the user. These expired and supposedly
deleted (to the user) sessions are then returned when the `ListSessions`
API is called.

This PR fixes this issue by:
1. Allowing deletion of expired sessions
2. Providing an `expiration_date` filter in `ListSession` API to filter
sessions by expiration date

# How the Problems Are Solved

1. Remove expired session check during deletion
2. Add an `expiration_date` filter to the  `ListSession` API

# Additional Changes
N/A

# Additional Context
- Closes #10045

---------

Co-authored-by: Marco A. <marco@zitadel.com>
2025-08-08 09:53:51 +02:00
Stefan Benz
ec1289356f fix: project grant permissions v2 remove (#10337)
# Which Problems Are Solved

[Permissions v2](https://github.com/zitadel/zitadel/issues/9972) is not
possible in the current implementation.

# How the Problems Are Solved

We remove Permissions v2 from project grants related API calls, to
alleviate this problems.
Resulting in some removals of testing, implementations and performance
impact

# Additional Changes

None

# Additional Context

None
2025-07-29 18:17:16 +02:00
Recep YILDIZ
25adfd91a2 feat: add Turkish language support (#10198)
- Turkish language support is added. 
- Updated other language files to add Turkish selection.

# Which Problems Are Solved

- Zitadel was not supporting Turkish language. Now supporting. 

# How the Problems Are Solved

- Turkish language files are added and updated other language files in
below paths to add Turkish support;
    -  /console/src/assets/i18n/
    - /internal/api/ui/login/static/i18n
    - /internal/notification/static/i18n
    - /internal/static/i18n

# Additional Changes

- Made changes below files for codes/docs changes;
    - /console/src/app/utils/language.ts
    - /console/src/app/app.module.ts
    - /docs/docs/guides/manage/customize/texts.md
- /internal/api/ui/login/static/templates/external_not_found_option.html
    - /internal/query/v2-default.json
    - /login/apps/login/src/lib/i18n.ts

---------

Co-authored-by: Marco A. <marco@zitadel.com>
2025-07-18 14:18:22 +02:00
Livio Spring
fefeaea56a perf: improve org and org domain creation (#10232)
# Which Problems Are Solved

When an organization domain is verified, e.g. also when creating a new
organization (incl. generated domain), existing usernames are checked if
the domain has been claimed.
The query was not optimized for instances with many users and
organizations.

# How the Problems Are Solved

- Replace the query, which was searching over the users projection with
(computed loginnames) with a dedicated query checking the loginnames
projection directly.
-  All occurrences have been updated to use the new query.

# Additional Changes

None

# Additional Context

- reported through support
- requires backport to v3.x
2025-07-10 15:17:49 +00:00
Stefan Benz
5403be7c4b feat: user profile requests in resource APIs (#10151)
# Which Problems Are Solved

The commands for the resource based v2beta AuthorizationService API are
added.
Authorizations, previously knows as user grants, give a user in a
specific organization and project context roles.
The project can be owned or granted.
The given roles can be used to restrict access within the projects
applications.

The commands for the resource based v2beta InteralPermissionService API
are added.
Administrators, previously knows as memberships, give a user in a
specific organization and project context roles.
The project can be owned or granted.
The give roles give the user permissions to manage different resources
in Zitadel.

API definitions from https://github.com/zitadel/zitadel/issues/9165 are
implemented.

Contains endpoints for user metadata.

# How the Problems Are Solved

### New Methods

- CreateAuthorization
- UpdateAuthorization
- DeleteAuthorization
- ActivateAuthorization
- DeactivateAuthorization
- ListAuthorizations
- CreateAdministrator
- UpdateAdministrator
- DeleteAdministrator
- ListAdministrators
- SetUserMetadata to set metadata on a user
- DeleteUserMetadata to delete metadata on a user
- ListUserMetadata to query for metadata of a user

## Deprecated Methods

### v1.ManagementService
- GetUserGrantByID
- ListUserGrants
- AddUserGrant
- UpdateUserGrant
- DeactivateUserGrant
- ReactivateUserGrant
- RemoveUserGrant
- BulkRemoveUserGrant

### v1.AuthService
- ListMyUserGrants
- ListMyProjectPermissions

# Additional Changes

- Permission checks for metadata functionality on query and command side
- correct existence checks for resources, for example you can only be an
administrator on an existing project
- combined all member tables to singular query for the administrators
- add permission checks for command an query side functionality
- combined functions on command side where necessary for easier
maintainability

# Additional Context

Closes #9165

---------

Co-authored-by: Elio Bischof <elio@zitadel.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-07-04 18:12:59 +02:00
Marco A.
fce9e770ac feat: App Keys API v2 (#10140)
# Which Problems Are Solved

This PR *partially* addresses #9450 . Specifically, it implements the
resource based API for app keys.

This PR, together with https://github.com/zitadel/zitadel/pull/10077
completes #9450 .

# How the Problems Are Solved

- Implementation of the following endpoints: `CreateApplicationKey`,
`DeleteApplicationKey`, `GetApplicationKey`, `ListApplicationKeys`
- `ListApplicationKeys` can filter by project, app or organization ID.
Sorting is also possible according to some criteria.
  - All endpoints use permissions V2

# TODO

 - [x] Deprecate old endpoints

# Additional Context

Closes #9450
2025-07-02 07:34:19 +00:00
Tim Möhlmann
4cd52f33eb chore(oidc): remove feature flag for introspection triggers (#10132)
# Which Problems Are Solved

Remove the feature flag that allowed triggers in introspection. This
option was a fallback in case introspection would not function properly
without triggers. The API documentation asked for anyone using this flag
to raise an issue. No such issue was received, hence we concluded it is
safe to remove it.

# How the Problems Are Solved

- Remove flags from the system and instance level feature APIs.
- Remove trigger functions that are no longer used
- Adjust tests that used the flag.

# Additional Changes

- none

# Additional Context

- Closes #10026 
- Flag was introduced in #7356

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-06-30 05:48:04 +00:00
Marco A.
2691dae2b6 feat: App API v2 (#10077)
# Which Problems Are Solved

This PR *partially* addresses #9450 . Specifically, it implements the
resource based API for the apps. APIs for app keys ARE not part of this
PR.

# How the Problems Are Solved

- `CreateApplication`, `PatchApplication` (update) and
`RegenerateClientSecret` endpoints are now unique for all app types:
API, SAML and OIDC apps.
  - All new endpoints have integration tests
  - All new endpoints are using permission checks V2

# Additional Changes

- The `ListApplications` endpoint allows to do sorting (see protobuf for
details) and filtering by app type (see protobuf).
- SAML and OIDC update endpoint can now receive requests for partial
updates

# Additional Context

Partially addresses #9450
2025-06-27 17:25:44 +02:00
Tim Möhlmann
016676e1dc chore(oidc): graduate webkey to stable (#10122)
# Which Problems Are Solved

Stabilize the usage of webkeys.

# How the Problems Are Solved

- Remove all legacy signing key code from the OIDC API
- Remove the webkey feature flag from proto
- Remove the webkey feature flag from console
- Cleanup documentation

# Additional Changes

- Resolved some canonical header linter errors in OIDC
- Use the constant for `projections.lock` in the saml package.

# Additional Context

- Closes #10029
- After #10105
- After #10061
2025-06-26 19:17:45 +03:00
Tim Möhlmann
1ebbe275b9 chore(oidc): remove legacy storage methods (#10061)
# Which Problems Are Solved

Stabilize the optimized introspection code and cleanup unused code.

# How the Problems Are Solved

- `oidc_legacy_introspection` feature flag is removed and reserved.
- `OPStorage` which are no longer needed have their bodies removed.
- The method definitions need to remain in place so the interface
remains implemented.
  - A panic is thrown in case any such method is still called

# Additional Changes

- A number of `OPStorage` methods related to token creation were already
unused. These are also cleaned up.

# Additional Context

- Closes #10027 
- #7822

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-06-26 08:08:37 +00:00
Marco A.
28f7218ea1 feat: Hosted login translation API (#10011)
# Which Problems Are Solved

This PR implements https://github.com/zitadel/zitadel/issues/9850

# How the Problems Are Solved

  - New protobuf definition
  - Implementation of retrieval of system translations
- Implementation of retrieval and persistence of organization and
instance level translations

# Additional Context

- Closes #9850

# TODO

- [x] Integration tests for Get and Set hosted login translation
endpoints
- [x] DB migration test
- [x] Command function tests
- [x] Command util functions tests
- [x] Query function test
- [x] Query util functions tests
2025-06-18 13:24:39 +02:00
Silvan
4df138286b perf(query): reduce user query duration (#10037)
# Which Problems Are Solved

The resource usage to query user(s) on the database was high and
therefore could have performance impact.

# How the Problems Are Solved

Database queries involving the users and loginnames table were improved
and an index was added for user by email query.

# Additional Changes

- spellchecks
- updated apis on load tests

# additional info

needs cherry pick to v3
2025-06-06 08:48:29 +00:00
Stefan Benz
85e3b7449c fix: correct permissions for projects on v2 api (#9973)
# Which Problems Are Solved

Permission checks in project v2beta API did not cover projects and
granted projects correctly.

# How the Problems Are Solved

Add permission checks v1 correctly to the list queries, add correct
permission checks v2 for projects.

# Additional Changes

Correct Pre-Checks for project grants that the right resource owner is
used.

# Additional Context

Permission checks v2 for project grants is still outstanding under
#9972.
2025-06-04 11:46:10 +00:00
Elio Bischof
8fc11a7366 feat: user api requests to resource API (#9794)
# Which Problems Are Solved

This pull request addresses a significant gap in the user service v2
API, which currently lacks methods for managing machine users.

# How the Problems Are Solved

This PR adds new API endpoints to the user service v2 to manage machine
users including their secret, keys and personal access tokens.
Additionally, there's now a CreateUser and UpdateUser endpoints which
allow to create either a human or machine user and update them. The
existing `CreateHumanUser` endpoint has been deprecated along the
corresponding management service endpoints. For details check the
additional context section.

# Additional Context

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

## More details
- API changes: https://github.com/zitadel/zitadel/pull/9680
- Implementation: https://github.com/zitadel/zitadel/pull/9763
- Tests: https://github.com/zitadel/zitadel/pull/9771

## Follow-ups

- Metadata: support managing user metadata using resource API
https://github.com/zitadel/zitadel/pull/10005
- Machine token type: support managing the machine token type (migrate
to new enum with zero value unspecified?)

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-06-04 07:17:23 +00:00
Tim Möhlmann
b9c1cdf4ad feat(projections): resource counters (#9979)
# Which Problems Are Solved

Add the ability to keep track of the current counts of projection
resources. We want to prevent calling `SELECT COUNT(*)` on tables, as
that forces a full scan and sudden spikes of DB resource uses.

# How the Problems Are Solved

- A resource_counts table is added
- Triggers that increment and decrement the counted values on inserts
and deletes
- Triggers that delete all counts of a table when the source table is
TRUNCATEd. This is not in the business logic, but prevents wrong counts
in case someone want to force a re-projection.
- Triggers that delete all counts if the parent resource is deleted
- Script to pre-populate the resource_counts table when a new source
table is added.

The triggers are reusable for any type of resource, in case we choose to
add more in the future.
Counts are aggregated by a given parent. Currently only `instance` and
`organization` are defined as possible parent. This can later be
extended to other types, such as `project`, should the need arise.

I deliberately chose to use `parent_id` to distinguish from the
de-factor `resource_owner` which is usually an organization ID. For
example:

- For users the parent is an organization and the `parent_id` matches
`resource_owner`.
- For organizations the parent is an instance, but the `resource_owner`
is the `org_id`. In this case the `parent_id` is the `instance_id`.
- Applications would have a similar problem, where the parent is a
project, but the `resource_owner` is the `org_id`


# Additional Context

Closes https://github.com/zitadel/zitadel/issues/9957
2025-06-03 14:15:30 +00:00
Livio Spring
15902f5bc7 fix(cache): prevent org cache overwrite by other instances (#10012)
# Which Problems Are Solved

A customer reported that randomly certain login flows, such as automatic
redirect to the only configured IdP would not work. During the
investigation it was discovered that they used that same primary domain
on two different instances. As they used the domain for preselecting the
organization, one would always overwrite the other in the cache. Since
The organization and especially it's policies could not be retrieved on
the other instance, it would fallback to the default organization
settings, where the external login and the corresponding IdP were not
configured.

# How the Problems Are Solved

Include the instance id in the cache key for organizations to prevent
overwrites.

# Additional Changes

None

# Additional Context

- found because of a support request
- requires backport to 2.70.x, 2.71.x and 3.x
2025-06-03 14:48:15 +02:00
Iraq
ae1a2e93c1 feat(api): moving organization API resourced based (#9943) 2025-06-02 16:27:53 +00:00
Silvan
131f70db34 fix(eventstore): use decimal, correct mirror (#9914)
# Eventstore fixes

- `event.Position` used float64 before which can lead to [precision
loss](https://github.com/golang/go/issues/47300). The type got replaced
by [a type without precision
loss](https://github.com/jackc/pgx-shopspring-decimal)
- the handler reported the wrong error if the current state was updated
and therefore took longer to retry failed events.

# Mirror fixes

- max age of auth requests can be configured to speed up copying data
from `auth.auth_requests` table. Auth requests last updated before the
set age will be ignored. Default is 1 month
- notification projections are skipped because notifications should be
sent by the source system. The projections are set to the latest
position
- ensure that mirror can be executed multiple times

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-05-28 21:54:18 +00:00
Silvan
eb0eed21fa fix(api): correct mapping of user state queries (#9956)
# Which Problems Are Solved

the mapping of `ListUsers` was wrong for user states.

# How the Problems Are Solved

mapping of user state introduced to correctly map it

# Additional Changes

mapping of user type introduced to prevent same issue

# Additional Context

Requires backport to 2.x and 3.x

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-05-26 13:23:38 +02:00
Livio Spring
2cf3ef4de4 feat: federated logout for SAML IdPs (#9931)
# Which Problems Are Solved

Currently if a user signs in using an IdP, once they sign out of
Zitadel, the corresponding IdP session is not terminated. This can be
the desired behavior. In some cases, e.g. when using a shared computer
it results in a potential security risk, since a follower user might be
able to sign in as the previous using the still open IdP session.

# How the Problems Are Solved

- Admins can enabled a federated logout option on SAML IdPs through the
Admin and Management APIs.
- During the termination of a login V1 session using OIDC end_session
endpoint, Zitadel will check if an IdP was used to authenticate that
session.
- In case there was a SAML IdP used with Federated Logout enabled, it
will intercept the logout process, store the information into the shared
cache and redirect to the federated logout endpoint in the V1 login.
- The V1 login federated logout endpoint checks every request on an
existing cache entry. On success it will create a SAML logout request
for the used IdP and either redirect or POST to the configured SLO
endpoint. The cache entry is updated with a `redirected` state.
- A SLO endpoint is added to the `/idp` handlers, which will handle the
SAML logout responses. At the moment it will check again for an existing
federated logout entry (with state `redirected`) in the cache. On
success, the user is redirected to the initially provided
`post_logout_redirect_uri` from the end_session request.

# Additional Changes

None

# Additional Context

- This PR merges the https://github.com/zitadel/zitadel/pull/9841 and
https://github.com/zitadel/zitadel/pull/9854 to main, additionally
updating the docs on Entra ID SAML.
- closes #9228 
- backport to 3.x

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
Co-authored-by: Zach Hirschtritt <zachary.hirschtritt@klaviyo.com>
2025-05-23 13:52:25 +02:00
Stefan Benz
7eb45c6cfd feat: project v2beta resource API (#9742)
# Which Problems Are Solved

Resource management of projects and sub-resources was before limited by
the context provided by the management API, which would mean you could
only manage resources belonging to a specific organization.

# How the Problems Are Solved

With the addition of a resource-based API, it is now possible to manage
projects and sub-resources on the basis of the resources themselves,
which means that as long as you have the permission for the resource,
you can create, read, update and delete it.

- CreateProject to create a project under an organization
- UpdateProject to update an existing project
- DeleteProject to delete an existing project
- DeactivateProject and ActivateProject to change the status of a
project
- GetProject to query for a specific project with an identifier
- ListProject to query for projects and granted projects
- CreateProjectGrant to create a project grant with project and granted
organization
- UpdateProjectGrant to update the roles of a project grant
- DeactivateProjectGrant and ActivateProjectGrant to change the status
of a project grant
- DeleteProjectGrant to delete an existing project grant
- ListProjectGrants to query for project grants
- AddProjectRole to add a role to an existing project
- UpdateProjectRole to change texts of an existing role
- RemoveProjectRole to remove an existing role
- ListProjectRoles to query for project roles

# Additional Changes

- Changes to ListProjects, which now contains granted projects as well
- Changes to messages as defined in the
[API_DESIGN](https://github.com/zitadel/zitadel/blob/main/API_DESIGN.md)
- Permission checks for project functionality on query and command side
- Added testing to unit tests on command side
- Change update endpoints to no error returns if nothing changes in the
resource
- Changed all integration test utility to the new service
- ListProjects now also correctly lists `granted projects`
- Permission checks for project grant and project role functionality on
query and command side
- Change existing pre checks so that they also work resource specific
without resourceowner
- Added the resourceowner to the grant and role if no resourceowner is
provided
- Corrected import tests with project grants and roles
- Added testing to unit tests on command side
- Change update endpoints to no error returns if nothing changes in the
resource
- Changed all integration test utility to the new service
- Corrected some naming in the proto files to adhere to the API_DESIGN

# Additional Context

Closes #9177

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-05-21 14:40:47 +02:00
Marco A.
490e4bd623 feat: instance requests implementation for resource API (#9830)
<!--
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

These changes introduce resource-based API endpoints for managing
instances and custom domains.

There are 4 types of changes:

- Endpoint implementation: consisting of the protobuf interface and the
implementation of the endpoint. E.g:
606439a172
- (Integration) Tests: testing the implemented endpoint. E.g:
cdfe1f0372
- Fixes: Bugs found during development that are being fixed. E.g:
acbbeedd32
- Miscellaneous: code needed to put everything together or that doesn't
fit any of the above categories. E.g:
529df92abc or
6802cb5468

# How the Problems Are Solved

_Ticked checkboxes indicate that the functionality is complete_

- [x] Instance
  - [x] Create endpoint
  - [x] Create endpoint tests
  - [x] Update endpoint
  - [x] Update endpoint tests
  - [x] Get endpoint
  - [x] Get endpoint tests
  - [x] Delete endpoint
  - [x] Delete endpoint tests
- [x] Custom Domains
  - [x] Add custom domain
  - [x] Add custom domain tests
  - [x] Remove custom domain
  - [x] Remove custom domain tests
  - [x] List custom domains
  - [x] List custom domains tests
- [x] Trusted Domains
  - [x] Add trusted domain
  - [x] Add trusted domain tests
  - [x] Remove trusted domain
  - [x] Remove trusted domain tests
  - [x] List trusted domains
  - [x] List trusted domains tests

# Additional Changes

When looking for instances (through the `ListInstances` endpoint)
matching a given query, if you ask for the results to be order by a
specific column, the query will fail due to a syntax error. This is
fixed in acbbeedd32 . Further explanation
can be found in the commit message

# Additional Context

- Relates to #9452 
- CreateInstance has been excluded:
https://github.com/zitadel/zitadel/issues/9930
- Permission checks / instance retrieval (middleware) needs to be
changed to allow context based permission checks
(https://github.com/zitadel/zitadel/issues/9929), required for
ListInstances

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-05-21 10:50:44 +02:00
Livio Spring
968d91a3e0 chore: update dependencies (#9784)
# Which Problems Are Solved

Some dependencies are out of date and published new version including
(unaffected) vulnerability fixes.

# How the Problems Are Solved

- Updated at least all direct dependencies apart from i18n, webauthn
(existing issues),
  -  crewjam (https://github.com/zitadel/zitadel/issues/9783) and
- github.com/gorilla/csrf (https://github.com/gorilla/csrf/issues/190,
https://github.com/gorilla/csrf/issues/189,
https://github.com/gorilla/csrf/issues/188,
https://github.com/gorilla/csrf/issues/187,
https://github.com/gorilla/csrf/issues/186)
      -  noteworthy: https://github.com/golang/go/issues/73626
- Some dependencies require Go 1.24, which triggered an update for
zitadel to go 1.24 as well.

# Additional Changes

None

# Additional Context

None
2025-05-19 10:16:49 +00:00
Elio Bischof
d79d5e7b96 fix(projection): remove users with factors (#9877)
# Which Problems Are Solved

When users are removed, their auth factors stay in the projection. This
data inconsistency is visible if a removed user is recreated with the
same ID. In such a case, the login UI and the query API methods show the
removed users auth methods. This is unexpected behavior.

The old users auth methods are not usable to log in and they are not
found by the command side. This is expected behavior.

# How the Problems Are Solved

The auth factors projection reduces the user removed event by deleting
all factors.

# Additional Context

- Reported by support request
- requires backport to 2.x and 3.x
2025-05-12 12:05:12 +02:00
Livio Spring
867e9cb15a fix: correctly use single matching user (by loginname) (#9865)
# Which Problems Are Solved

In rare cases there was a possibility that multiple users were found by
a loginname. This prevented the corresponding user to sign in.

# How the Problems Are Solved

Fixed the corresponding query (to correctly respect the org domain
policy).

# Additional Changes

None

# Additional Context

Found during the investigation of a support request
2025-05-08 07:32:41 +00:00
Zach Hirschtritt
8cb1d24b36 fix: add user id index on sessions8 (#9834)
# Which Problems Are Solved

When a user changes their password, Zitadel needs to terminate all of
that user's active sessions. This query can take many seconds on
deployments with large session and user tables. This happens as part of
session projection handling, so doesn't directly impact user experience,
but potentially bogs down the projection handler which isn't great. In
the future, this index could be used to power a "see all of my current
sessions" feature in Zitadel.

# How the Problems Are Solved

Adds new index on `user_id` column on `projections.sessions8` table.
Alternatively, we can index on `(instance_id, user_id)` instead but
opted for keeping the index smaller as we already index on `instance_id`
separately.

# Additional Changes

None

# Additional Context

None

---------

Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
2025-05-06 06:38:19 +00:00
Stefan Benz
a05f7ce3fc fix: correct handling of removed targets (#9824)
# Which Problems Are Solved

In Actions v2, if a target is removed, which is still used in an
execution, the target is still listed when list executions.

# How the Problems Are Solved

Removed targets are now also removed from the executions.

# Additional Changes

To be sure the list executions include a check if the target is still
existing.

# Additional Context

None

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-04-30 12:58:10 +00:00
Silvan
181186e477 fix(mirror): add max auth request age configuration (#9812)
# Which Problems Are Solved

The `auth.auth_requests` table is not cleaned up so long running Zitadel
installations can contain many rows.
 
The mirror command can take long because a the data are first copied
into memory (or disk) on cockroach and users do not get any output from
mirror. This is unfortunate because people don't know if Zitadel got
stuck.

# How the Problems Are Solved

Enhance logging throughout the projection processes and introduce a
configuration option for the maximum age of authentication requests.

# Additional Changes

None

# Additional Context

closes https://github.com/zitadel/zitadel/issues/9764

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-04-29 15:29:16 +00:00
Stefan Benz
b8ba7bd5ba fix: remove action feature flag and include execution (#9727)
# Which Problems Are Solved

Actions v2 is not a feature flag anymore, include functionality on
executions is not used and json tags of proto messages are handled
incorrectly.

# How the Problems Are Solved

- Remove actions from the feature flags on system and instance level
- Remove include type on executions, only in the API, later maybe in the
handling logic as well
- Use protojson in request and response handling of actions v2

# Additional Changes

- Correct integration tests for request and response handling
- Use json.RawMessage for events, so that the event payload is not
base64 encoded
- Added separate context for async webhook calls, that executions are
not cancelled when called async

# Additional Context

Related to #9759 
Closes #9710

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
2025-04-28 11:24:50 +02:00
Tim Möhlmann
658ca3606b feat(permissions): project member permission filter (#9757)
# Which Problems Are Solved

Add the possibility to filter project resources based on project member
roles.

# How the Problems Are Solved

Extend and refactor existing Pl/PgSQL functions to implement the
following:

- Solve O(n) complexity in returned resources IDs by returning a boolean
filter for instance level permissions.
- Individually permitted orgs are returned only if there was no instance
permission
- Individually permitted projects are returned only if there was no
instance permission
- Because of the multiple filter terms, use `INNER JOIN`s instead of
`WHERE` clauses.

# Additional Changes

- system permission function no longer query the organization view and
therefore can be `immutable`, giving big performance benefits for
frequently reused system users. (like our hosted login in Zitadel cloud)
- The permitted org and project functions are now defined as `stable`
because the don't modify on-disk data. This might give a small
performance gain
- The Pl/PgSQL functions are now tested using Go unit tests.

# Additional Context

- Depends on https://github.com/zitadel/zitadel/pull/9677
- Part of https://github.com/zitadel/zitadel/issues/9188
- Closes https://github.com/zitadel/zitadel/issues/9190
2025-04-22 08:42:59 +00:00
Tim Möhlmann
a2f60f2e7a perf(query): org permission function for resources (#9677)
# Which Problems Are Solved

Classic permission checks execute for every returned row on resource
based search APIs. Complete background and problem definition can be
found here: https://github.com/zitadel/zitadel/issues/9188

# How the Problems Are Solved

- PermissionClause function now support dynamic query building, so it
supports multiple cases.
- PermissionClause is applied to all list resources which support org
level permissions.
- Wrap permission logic into wrapper functions so we keep the business
logic clean.

# Additional Changes

- Handle org ID optimization in the query package, so it is reusable for
all resources, instead of extracting the filter in the API.
- Cleanup and test system user conversion in the authz package. (context
middleware)
- Fix: `core_integration_db_up` make recipe was missing the postgres
service.

# Additional Context

- Related to https://github.com/zitadel/zitadel/issues/9190
2025-04-15 18:38:25 +02:00