# Which Problems Are Solved
IdPs using form callback were not always correctly handled with the
newly introduced cache mechanism
(https://github.com/zitadel/zitadel/pull/9097).
# How the Problems Are Solved
Get the data from cache before parsing it.
# Additional Changes
None
# Additional Context
Relates to https://github.com/zitadel/zitadel/pull/9097
# Which Problems Are Solved
Some IdP callbacks use HTTP form POST to return their data on callbacks.
For handling CSRF in the login after such calls, a 302 Found to the
corresponding non form callback (in ZITADEL) is sent. Depending on the
size of the initial form body, this could lead to ZITADEL terminating
the connection, resulting in the user not getting a response or an
intermediate proxy to return them an HTTP 502.
# How the Problems Are Solved
- the form body is parsed and stored into the ZITADEL cache (using the
configured database by default)
- the redirect (302 Found) is performed with the request id
- the callback retrieves the data from the cache instead of the query
parameters (will fallback to latter to handle open uncached requests)
# Additional Changes
- fixed a typo in the default (cache) configuration: `LastUsage` ->
`LastUseAge`
# Additional Context
- reported by a customer
- needs to be backported to current cloud version (2.66.x)
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
# Which Problems Are Solved
The v2 api currently has no endpoint the get all second factors of a
user.
# How the Problems Are Solved
Our v1 api has the ListHumanAuthFactors which got added to the v2 api
under the User resource.
# Additional Changes
# Additional Context
Closes#8833
---------
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
# Which Problems Are Solved
Added search by phone to user Service V2.
```
curl --request POST \
--url https://<zitadel_domain>/v2/users \
--header 'Accept: application/json' \
--header 'Authorization: Bearer <Token>' \
--header 'Content-Type: application/json' \
--header 'content-type: application/json' \
--data '{
"query": {
"offset": "0",
"limit": 100,
"asc": true
},
"sortingColumn": "USER_FIELD_NAME_UNSPECIFIED",
"queries": [
{
"phoneQuery": {
"number": "+12011223313",
"method": "TEXT_QUERY_METHOD_EQUALS"
}
}
]
}'
```
Why?
Searching for a user by phone was missing from User Service V2 and V2
beta.
# How the Problems Are Solved
* Added to the SearchQuery proto
* Added code to filter users by phone
# Additional Changes
N/A
# Additional Context
Search by phone is present in V3 User Service
---------
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
# Which Problems Are Solved
There is currently no endpoint to send an email code for verification of
the email if you don't change the email itself.
# How the Problems Are Solved
Endpoint HasEmailCode to get the information that an email code is
existing, used by the new login.
Endpoint SendEmailCode, if no code is existing to replace
ResendEmailCode as there is a check that a code has to be there, before
it can be resend.
# Additional Changes
None
# Additional Context
Closes#9096
---------
Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
# Which Problems Are Solved
SAML IdPs exposing an `EntitiesDescriptor` using an `xsd:duration` time
format for the `cacheDuration` property (e.g. `PT5H`) failed parsing.
# How the Problems Are Solved
Handle the unmarshalling for `EntitiesDescriptor` specifically.
[crewjam/saml](bbccb7933d/metadata.go (L88-L103))
already did this for `EntitiyDescriptor` the same way.
# Additional Changes
None
# Additional Context
- reported by a customer
- needs to be backported to current cloud version (2.66.x)
# Which Problems Are Solved
It is currently not possible to use SAML with the Session API.
# How the Problems Are Solved
Add SAML service, to get and resolve SAML requests.
Add SAML session and SAML request aggregate, which can be linked to the
Session to get back a SAMLResponse from the API directly.
# Additional Changes
Update of dependency zitadel/saml to provide all functionality for
handling of SAML requests and responses.
# Additional Context
Closes#6053
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
To be able to migrate or test the new login UI, admins might want to
(temporarily) switch individual apps.
At a later point admin might want to make sure all applications use the
new login UI.
# How the Problems Are Solved
- Added a feature flag `` on instance level to require all apps to use
the new login and provide an optional base url.
- if the flag is enabled, all (OIDC) applications will automatically use
the v2 login.
- if disabled, applications can decide based on their configuration
- Added an option on OIDC apps to use the new login UI and an optional
base url.
- Removed the requirement to use `x-zitadel-login-client` to be
redirected to the login V2 and retrieve created authrequest and link
them to SSO sessions.
- Added a new "IAM_LOGIN_CLIENT" role to allow management of users,
sessions, grants and more without `x-zitadel-login-client`.
# Additional Changes
None
# Additional Context
closes https://github.com/zitadel/zitadel/issues/8702
# Which Problems Are Solved
To list IDPs for potential linking, we need to filter them. The
GetActiveIdentityProviderResponse should therefore be extended to
provide the IDPConfig or information about whether the IDP is allowed to
be linked or created.
# How the Problems Are Solved
Add parameters to the request to exclude CreationDisallowed and/or
LinkingDisallowed in the query.
# Additional Changes
Added integration tests for the GetGetActiveIdentityProvider endpoint.
# Additional Context
Closes#8981
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
During authentication in the login UI, there is a check if the user's
MFA is already checked or needs to be setup.
In cases where the user was just set up or especially, if the user was
just federated without a verified email address, this can lead to the
problem, where OTP Email cannot be setup as there's no verified email
address.
# How the Problems Are Solved
- Added a check if there's no verified email address on the user and
require a mail verification check before checking for MFA.
Note: that if the user had a verified email address, but changed it and
has not verified it, they will still be prompted with an MFA check
before the email verification. This is make sure, we don't break the
existing behavior and the user's authentication is properly checked.
# Additional Changes
None
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/9035
# Which Problems Are Solved
When Zitadel starts the first time with a configured Redis cache, the
circuit break would open on the first requests, with no explanatory
error and only log-lines explaining the state of the Circuit breaker.
Using a debugger, `NOSCRIPT No matching script. Please use EVAL.` was
found the be passed to `Limiter.ReportResult`. This error is actually
retried by go-redis after a
[`Script.Run`](https://pkg.go.dev/github.com/redis/go-redis/v9@v9.7.0#Script.Run):
> Run optimistically uses EVALSHA to run the script. If script does not
exist it is retried using EVAL.
# How the Problems Are Solved
Add the `NOSCRIPT` error prefix to the whitelist.
# Additional Changes
- none
# Additional Context
- Introduced in: https://github.com/zitadel/zitadel/pull/8890
- Workaround for: https://github.com/redis/go-redis/issues/3203
# Which Problems Are Solved
Scheduled handlers use `eventstore.InstanceIDs` to get the all active
instances within a given timeframe. This function scrapes through all
events written within that time frame which can cause heavy load on the
database.
# How the Problems Are Solved
A new query cache `activeInstances` is introduced which caches the ids
of all instances queried by id or host within the configured timeframe.
# Additional Changes
- Changed `default.yaml`
- Removed `HandleActiveInstances` from custom handler configs
- Added `MaxActiveInstances` to define the maximal amount of cached
instance ids
- fixed start-from-init and start-from-setup to start auth and admin
projections twice
- fixed org cache invalidation to use correct index
# Additional Context
- part of #8999
# Which Problems Are Solved
In eventstore queries with aggregate ID exclusion filters, filters on
events creation date where not passed to the sub-query. This results in
a high amount of returned rows from the sub-query and high overall query
cost.
# How the Problems Are Solved
When CreatedAfter and CreatedBefore are used on the global search query,
copy those filters to the sub-query. We already did this for the
position column filter.
# Additional Changes
- none
# Additional Context
- Introduced in https://github.com/zitadel/zitadel/pull/8940
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
There are some problems related to the use of CockroachDB with the new
notification handling (#8931).
See #9002 for details.
# How the Problems Are Solved
- Brought back the previous notification handler as legacy mode.
- Added a configuration to choose between legacy mode and new parallel
workers.
- Enabled legacy mode by default to prevent issues.
# Additional Changes
None
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/9002
- relates to #8931
# Which Problems Are Solved
Slice initialized with a fixed length instead of capacity, this leads to
unexpected results when calling the append function.
# How the Problems Are Solved
fixed slice initialization, slice is initialized with zero length and
with capacity of function's argument
# Additional Changes
test case added
# Additional Context
none
Co-authored-by: Kolokhanin Roman <zuzmic@gmail.com>
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
# Which Problems Are Solved
While running the latest RC / main, we noticed some errors including
context timeouts and rollback issues.
# How the Problems Are Solved
- The transaction context is passed and used for any event being written
and for handling savepoints to be able to handle context timeouts.
- The user projection is not triggered anymore. This will reduce
unnecessary load and potential timeouts if lot of workers are running.
In case a user would not be projected yet, the request event will log an
error and then be skipped / retried on the next run.
- Additionally, the context is checked if being closed after each event
process.
- `latestRetries` now correctly only returns the latest retry events to
be processed
- Default values for notifications have been changed to run workers less
often, more retry delay, but less transaction duration.
# Additional Changes
None
# Additional Context
relates to #8931
---------
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
# Which Problems Are Solved
Instance domains are only computed on read side. This can cause missing
domains if calls are executed shortly after a instance domain (or
instance) was added.
# How the Problems Are Solved
The instance domain is added to the fields table which is filled on
command side.
# Additional Changes
- added setup step to compute instance domains
- instance by host uses fields table instead of instance_domains table
# Additional Context
- part of https://github.com/zitadel/zitadel/issues/8999
# Which Problems Are Solved
If many events are written to the same aggregate id it can happen that
zitadel [starts to retry the push
transaction](48ffc902cc/internal/eventstore/eventstore.go (L101))
because [the locking
behaviour](48ffc902cc/internal/eventstore/v3/sequence.go (L25))
during push does compute the wrong sequence because newly committed
events are not visible to the transaction. These events impact the
current sequence.
In cases with high command traffic on a single aggregate id this can
have severe impact on general performance of zitadel. Because many
connections of the `eventstore pusher` database pool are blocked by each
other.
# How the Problems Are Solved
To improve the performance this locking mechanism was removed and the
business logic of push is moved to sql functions which reduce network
traffic and can be analyzed by the database before the actual push. For
clients of the eventstore framework nothing changed.
# Additional Changes
- after a connection is established prefetches the newly added database
types
- `eventstore.BaseEvent` now returns the correct revision of the event
# Additional Context
- part of https://github.com/zitadel/zitadel/issues/8931
---------
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
Co-authored-by: Livio Spring <livio.a@gmail.com>
Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: Elio Bischof <elio@zitadel.com>
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
Co-authored-by: Miguel Cabrerizo <30386061+doncicuto@users.noreply.github.com>
Co-authored-by: Joakim Lodén <Loddan@users.noreply.github.com>
Co-authored-by: Yxnt <Yxnt@users.noreply.github.com>
Co-authored-by: Stefan Benz <stefan@caos.ch>
Co-authored-by: Harsha Reddy <harsha.reddy@klaviyo.com>
Co-authored-by: Zach H <zhirschtritt@gmail.com>
# Which Problems Are Solved
Wrongly created project grants with a unexpected resourceowner can't be
removed as there is a check if the project is existing, the project is
never existing as the wrong resourceowner is used.
# How the Problems Are Solved
There is already a fix related to the resourceowner of the project
grant, which should remove the possibility that this situation can
happen anymore. This PR removes the check for the project existing, as
when the projectgrant is existing and the project is not already
removed, this check is not needed anymore.
# Additional Changes
None
# Additional Context
Closes#8900
# Which Problems Are Solved
There are multiple issues with the metadata and error handling of SAML:
- When providing a SAML metadata for an IdP, which cannot be processed,
the error will only be noticed once a user tries to use the IdP.
- Parsing for metadata with any other encoding than UTF-8 fails.
- Metadata containing an enclosing EntitiesDescriptor around
EntityDescriptor cannot be parsed.
- Metadata's `validUntil` value is always set to 48 hours, which causes
issues on external providers, if processed from a manual down/upload.
- If a SAML response cannot be parsed, only a generic "Authentication
failed" error is returned, the cause is hidden to the user and also to
actions.
# How the Problems Are Solved
- Return parsing errors after create / update and retrieval of an IdP in
the API.
- Prevent the creation and update of an IdP in case of a parsing
failure.
- Added decoders for encodings other than UTF-8 (including ASCII,
windows and ISO, [currently
supported](efd25daf28/encoding/ianaindex/ianaindex.go (L156)))
- Updated parsing to handle both `EntitiesDescriptor` and
`EntityDescriptor` as root element
- `validUntil` will automatically set to the certificate's expiration
time
- Unwrapped the hidden error to be returned. The Login UI will still
only provide a mostly generic error, but action can now access the
underlying error.
# Additional Changes
None
# Additional Context
reported by a customer
# Which Problems Are Solved
Some user v2 API calls checked for permission only on the user itself.
# How the Problems Are Solved
Consistent check for permissions on user v2 API.
# Additional Changes
None
# Additional Context
Closes#7944
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
Hello everyone,
To support Korean-speaking users who may experience challenges in using
this excellent tool due to language barriers, I have added Korean
language support with the help of ChatGPT.
I hope that this contribution allows ZITADEL to be more useful and
accessible to Korean-speaking users.
Thank you.
---
안녕하세요 여러분, 언어의 어려움으로 이 훌륭한 도구를 활용하는데 곤란함을 겪는 한국어 사용자들을 위하여 ChatGPT의 도움을
받아 한국어 지원을 추가하였습니다.
이 기여를 통해 ZITADEL이 한국어 사용자들에게 유용하게 활용되었으면 좋겠습니다.
감사합니다.
Co-authored-by: Max Peintner <max@caos.ch>
# Which Problems Are Solved
- The quality of the Russian locale in the auth module is currently low,
likely due to automatic translation.
# How the Problems Are Solved
- Corrected grammatical errors and awkward phrasing from
auto-translation (e.g., "footer" → ~"нижний колонтитул"~ "примечание").
- Enhanced alignment with the English (reference) locale, including
improvements to casing and semantics.
- Ensured consistency in terminology (e.g., the "next"/"cancel" buttons
are now consistently translated as "продолжить"/"отмена").
- Improved clarity and readability (e.g., "подтверждение пароля" →
"повторите пароль").
# Additional Changes
N/A
# Additional Context
- Follow-up for PR #6864
Co-authored-by: Fabi <fabienne@zitadel.com>
# Which Problems Are Solved
Domains are processed as still verified in the domain verified
writemodel even if the org is removed.
# How the Problems Are Solved
Handle the org removed event in the writemodel.
# Additional Changes
None
# Additional Context
Closes#8514
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
The action v2 messages were didn't contain anything providing security
for the sent content.
# How the Problems Are Solved
Each Target now has a SigningKey, which can also be newly generated
through the API and returned at creation and through the Get-Endpoints.
There is now a HTTP header "Zitadel-Signature", which is generated with
the SigningKey and Payload, and also contains a timestamp to check with
a tolerance if the message took to long to sent.
# Additional Changes
The functionality to create and check the signature is provided in the
pkg/actions package, and can be reused in the SDK.
# Additional Context
Closes#7924
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
The current handling of notification follows the same pattern as all
other projections:
Created events are handled sequentially (based on "position") by a
handler. During the process, a lot of information is aggregated (user,
texts, templates, ...).
This leads to back pressure on the projection since the handling of
events might take longer than the time before a new event (to be
handled) is created.
# How the Problems Are Solved
- The current user notification handler creates separate notification
events based on the user / session events.
- These events contain all the present and required information
including the userID.
- These notification events get processed by notification workers, which
gather the necessary information (recipient address, texts, templates)
to send out these notifications.
- If a notification fails, a retry event is created based on the current
notification request including the current state of the user (this
prevents race conditions, where a user is changed in the meantime and
the notification already gets the new state).
- The retry event will be handled after a backoff delay. This delay
increases with every attempt.
- If the configured amount of attempts is reached or the message expired
(based on config), a cancel event is created, letting the workers know,
the notification must no longer be handled.
- In case of successful send, a sent event is created for the
notification aggregate and the existing "sent" events for the user /
session object is stored.
- The following is added to the defaults.yaml to allow configuration of
the notification workers:
```yaml
Notifications:
# The amount of workers processing the notification request events.
# If set to 0, no notification request events will be handled. This can be useful when running in
# multi binary / pod setup and allowing only certain executables to process the events.
Workers: 1 # ZITADEL_NOTIFIACATIONS_WORKERS
# The amount of events a single worker will process in a run.
BulkLimit: 10 # ZITADEL_NOTIFIACATIONS_BULKLIMIT
# Time interval between scheduled notifications for request events
RequeueEvery: 2s # ZITADEL_NOTIFIACATIONS_REQUEUEEVERY
# The amount of workers processing the notification retry events.
# If set to 0, no notification retry events will be handled. This can be useful when running in
# multi binary / pod setup and allowing only certain executables to process the events.
RetryWorkers: 1 # ZITADEL_NOTIFIACATIONS_RETRYWORKERS
# Time interval between scheduled notifications for retry events
RetryRequeueEvery: 2s # ZITADEL_NOTIFIACATIONS_RETRYREQUEUEEVERY
# Only instances are projected, for which at least a projection-relevant event exists within the timeframe
# from HandleActiveInstances duration in the past until the projection's current time
# If set to 0 (default), every instance is always considered active
HandleActiveInstances: 0s # ZITADEL_NOTIFIACATIONS_HANDLEACTIVEINSTANCES
# The maximum duration a transaction remains open
# before it spots left folding additional events
# and updates the table.
TransactionDuration: 1m # ZITADEL_NOTIFIACATIONS_TRANSACTIONDURATION
# Automatically cancel the notification after the amount of failed attempts
MaxAttempts: 3 # ZITADEL_NOTIFIACATIONS_MAXATTEMPTS
# Automatically cancel the notification if it cannot be handled within a specific time
MaxTtl: 5m # ZITADEL_NOTIFIACATIONS_MAXTTL
# Failed attempts are retried after a confogired delay (with exponential backoff).
# Set a minimum and maximum delay and a factor for the backoff
MinRetryDelay: 1s # ZITADEL_NOTIFIACATIONS_MINRETRYDELAY
MaxRetryDelay: 20s # ZITADEL_NOTIFIACATIONS_MAXRETRYDELAY
# Any factor below 1 will be set to 1
RetryDelayFactor: 1.5 # ZITADEL_NOTIFIACATIONS_RETRYDELAYFACTOR
```
# Additional Changes
None
# Additional Context
- closes#8931
# Which Problems Are Solved
Integration tests are flaky due to eventual consistency.
# How the Problems Are Solved
Remove t.Parallel so that less concurrent requests on multiple instance
happen. This allows the projections to catch up more easily.
# Additional Changes
- none
# Additional Context
- none
# Which Problems Are Solved
When an org is removed, the corresponding fields are not deleted. This
creates issues, such as recreating a new org with the same verified
domain.
# How the Problems Are Solved
Remove the search fields by the org aggregate, instead of just setting
the removed state.
# Additional Changes
- Cleanup migration script that removed current stale fields.
# Additional Context
- Closes https://github.com/zitadel/zitadel/issues/8943
- Related to https://github.com/zitadel/zitadel/pull/8790
---------
Co-authored-by: Silvan <silvan.reusser@gmail.com>
# Which Problems Are Solved
For truly event-based notification handler, we need to be able to filter
out events of aggregates which are already handled. For example when an
event like `notify.success` or `notify.failed` was created on an
aggregate, we no longer require events from that aggregate ID.
# How the Problems Are Solved
Extend the query builder to use a `NOT IN` clause which excludes
aggregate IDs when they have certain events for a certain aggregate
type. For optimization and proper index usages, certain filters are
inherited from the parent query, such as:
- Instance ID
- Instance IDs
- Position offset
This is a prettified query as used by the unit tests:
```sql
SELECT created_at, event_type, "sequence", "position", payload, creator, "owner", instance_id, aggregate_type, aggregate_id, revision
FROM eventstore.events2
WHERE instance_id = $1
AND aggregate_type = $2
AND event_type = $3
AND "position" > $4
AND aggregate_id NOT IN (
SELECT aggregate_id
FROM eventstore.events2
WHERE aggregate_type = $5
AND event_type = ANY($6)
AND instance_id = $7
AND "position" > $8
)
ORDER BY "position" DESC, in_tx_order DESC
LIMIT $9
```
I used this query to run it against the `oidc_session` aggregate looking
for added events, excluding aggregates where a token was revoked,
against a recent position. It fully used index scans:
<details>
```json
[
{
"Plan": {
"Node Type": "Index Scan",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "es_projection",
"Relation Name": "events2",
"Alias": "events2",
"Actual Rows": 2,
"Actual Loops": 1,
"Index Cond": "((instance_id = '286399006995644420'::text) AND (aggregate_type = 'oidc_session'::text) AND (event_type = 'oidc_session.added'::text) AND (\"position\" > 1731582100.784168))",
"Rows Removed by Index Recheck": 0,
"Filter": "(NOT (hashed SubPlan 1))",
"Rows Removed by Filter": 1,
"Plans": [
{
"Node Type": "Index Scan",
"Parent Relationship": "SubPlan",
"Subplan Name": "SubPlan 1",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "es_projection",
"Relation Name": "events2",
"Alias": "events2_1",
"Actual Rows": 1,
"Actual Loops": 1,
"Index Cond": "((instance_id = '286399006995644420'::text) AND (aggregate_type = 'oidc_session'::text) AND (event_type = 'oidc_session.access_token.revoked'::text) AND (\"position\" > 1731582100.784168))",
"Rows Removed by Index Recheck": 0
}
]
},
"Triggers": [
]
}
]
```
</details>
# Additional Changes
- None
# Additional Context
- Related to https://github.com/zitadel/zitadel/issues/8931
---------
Co-authored-by: adlerhurst <silvan.reusser@gmail.com>
# Which Problems Are Solved
`eventstore.PushWithClient` required the wrong type of for the client
parameter.
# How the Problems Are Solved
Changed type of client from `database.Client` to
`database.QueryExecutor`
# Which Problems Are Solved
Push is not capable of external transactions.
# How the Problems Are Solved
A new function `PushWithClient` is added to the eventstore framework
which allows to pass a client which can either be a `*sql.Client` or
`*sql.Tx` and is used during push.
# Additional Changes
Added interfaces to database package.
# Additional Context
- part of https://github.com/zitadel/zitadel/issues/8931
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
# Which Problems Are Solved
We need a reliable way to lock events that are being processed as part
of a job queue. For example in the notification handlers.
# How the Problems Are Solved
Allow setting `FOR UPDATE [ NOWAIT | SKIP LOCKED ]` to the eventstore
query builder using an open transaction.
- NOWAIT returns an errors if the lock cannot be obtained
- SKIP LOCKED only returns row which are not locked.
- Default is to wait for the lock to be released.
# Additional Changes
- none
# Additional Context
- [Locking
docs](https://www.postgresql.org/docs/17/sql-select.html#SQL-FOR-UPDATE-SHARE)
- Related to https://github.com/zitadel/zitadel/issues/8931
# Which Problems Are Solved
Organizations are ofter searched for by ID or primary domain. This
results in many redundant queries, resulting in a performance impact.
# How the Problems Are Solved
Cache Organizaion objects by ID and primary domain.
# Additional Changes
- Adjust integration test config to use all types of cache.
- Adjust integration test lifetimes so the pruner has something to do
while the tests run.
# Additional Context
- Closes#8865
- After #8902
# Which Problems Are Solved
Noisy neighbours can introduce projection latencies because the
projections only query events older than the start timestamp of the
oldest push transaction.
# How the Problems Are Solved
During push we set the application name to
`zitadel_es_pusher_<instance_id>` instead of `zitadel_es_pusher` which
is used to query events by projections.
# Which Problems Are Solved
- ImportHuman was not checking for a `UserStateDeleted` state on import,
resulting in "already existing" errors when attempting to delete and
re-import a user with the same id
# How the Problems Are Solved
Use the `Exists` helper method to check for both `UserStateUnspecified`
and `UserStateDeleted` states on import
# Additional Changes
N/A
# Additional Context
N/A
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
Some SAML IdPs including Google only allow to configure a single
AssertionConsumerService URL.
Since the current metadata provides multiple and the hosted login UI is
not published as neither the first nor with `isDefault=true`, those IdPs
take another and then return an error on sign in.
# How the Problems Are Solved
Allow to reorder the ACS URLs using a query parameter
(`internalUI=true`) when retrieving the metadata endpoint.
This will list the `ui/login/login/externalidp/saml/acs` first and also
set the `isDefault=true`.
# Additional Changes
None
# Additional Context
Reported by a customer
# Which Problems Are Solved
The order of actions on a trigger was not respected on the execution and
not correctly returned when retrieving the flow, for example in Console.
The supposed correction of the order (e.g. in the UI) would then return
a "no changes" error since the order was already as desired.
# How the Problems Are Solved
- Correctly order the actions of a trigger based on their configuration
(`trigger_sequence`).
# Additional Changes
- replaced a `reflect.DeepEqual` with `slices.Equal` for checking the
action list
# Additional Context
- reported by a customer
- requires backports
# Which Problems Are Solved
If a redis cache has connection issues or any other type of permament
error,
it tanks the responsiveness of ZITADEL.
We currently do not support things like Redis cluster or sentinel. So
adding a simple redis cache improves performance but introduces a single
point of failure.
# How the Problems Are Solved
Implement a [circuit
breaker](https://learn.microsoft.com/en-us/previous-versions/msp-n-p/dn589784(v=pandp.10)?redirectedfrom=MSDN)
as
[`redis.Limiter`](https://pkg.go.dev/github.com/redis/go-redis/v9#Limiter)
by wrapping sony's [gobreaker](https://github.com/sony/gobreaker)
package. This package is picked as it seems well maintained and we
already use their `sonyflake` package
# Additional Changes
- The unit tests constructed an unused `redis.Client` and didn't cleanup
the connector. This is now fixed.
# Additional Context
Closes#8864
# Which Problems Are Solved
The setup filter for previous steps and kept getting slower. This is due
to the filter, which did not provide any instanceID and thus resulting
in a full table scan.
# How the Problems Are Solved
- Added an empty instanceID filter (since it's on system level)
# Additional Changes
None
# Additional Context
Noticed internally and during migrations on some regions
# Which Problems Are Solved
Do not return an access token for implicit flow from v1 login, if the
`response_type` is `id_token`
# How the Problems Are Solved
Do not create the access token event if if the `response_type` is
`id_token`.
# Additional Changes
Token endpoint calls without auth request, such as machine users, token
exchange and refresh token, do not have a `response_type`. For such
calls the `OIDCResponseTypeUnspecified` enum is added at a `-1` offset,
in order not to break existing client configs.
# Additional Context
- https://discord.com/channels/927474939156643850/1294001717725237298
- Fixes https://github.com/zitadel/zitadel/issues/8776
# Which Problems Are Solved
The intention here should be to initialize a slice with a capacity of
len(queriedOrgs.Orgs) rather than initializing the length of this slice.
the online demo: https://go.dev/play/p/vNUPNjdb2gJ
# How the Problems Are Solved
use `processedOrgs := make([]string, 0, len(queriedOrgs.Orgs))`
# Additional Changes
None
# Additional Context
None
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
# Which Problems Are Solved
https://github.com/zitadel/zitadel/pull/8788 accidentally changed the
spelling of milestone types from PascalCase to snake_case. This breaks
systems where `milestone.pushed` events already exist.
# How the Problems Are Solved
- Use PascalCase again
- Prefix event types with v2. (Previous pushed event type was anyway
ignored).
- Create `milstones3` projection
# Additional Changes
None
# Additional Context
relates to #8788
# Which Problems Are Solved
Add a cache implementation using Redis single mode. This does not add
support for Redis Cluster or sentinel.
# How the Problems Are Solved
Added the `internal/cache/redis` package. All operations occur
atomically, including setting of secondary indexes, using LUA scripts
where needed.
The [`miniredis`](https://github.com/alicebob/miniredis) package is used
to run unit tests.
# Additional Changes
- Move connector code to `internal/cache/connector/...` and remove
duplicate code from `query` and `command` packages.
- Fix a missed invalidation on the restrictions projection
# Additional Context
Closes#8130
# Which Problems Are Solved
Currently ZITADEL supports RP-initiated logout for clients. Back-channel
logout ensures that user sessions are terminated across all connected
applications, even if the user closes their browser or loses
connectivity providing a more secure alternative for certain use cases.
# How the Problems Are Solved
If the feature is activated and the client used for the authentication
has a back_channel_logout_uri configured, a
`session_logout.back_channel` will be registered. Once a user terminates
their session, a (notification) handler will send a SET (form POST) to
the registered uri containing a logout_token (with the user's ID and
session ID).
- A new feature "back_channel_logout" is added on system and instance
level
- A `back_channel_logout_uri` can be managed on OIDC applications
- Added a `session_logout` aggregate to register and inform about sent
`back_channel` notifications
- Added a `SecurityEventToken` channel and `Form`message type in the
notification handlers
- Added `TriggeredAtOrigin` fields to `HumanSignedOut` and
`TerminateSession` events for notification handling
- Exported various functions and types in the `oidc` package to be able
to reuse for token signing in the back_channel notifier.
- To prevent that current existing session termination events will be
handled, a setup step is added to set the `current_states` for the
`projections.notifications_back_channel_logout` to the current position
- [x] requires https://github.com/zitadel/oidc/pull/671
# Additional Changes
- Updated all OTEL dependencies to v1.29.0, since OIDC already updated
some of them to that version.
- Single Session Termination feature is correctly checked (fixed feature
mapping)
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/8467
- TODO:
- Documentation
- UI to be done: https://github.com/zitadel/zitadel/issues/8469
---------
Co-authored-by: Hidde Wieringa <hidde@hiddewieringa.nl>
# Which Problems Are Solved
Migration of milestones failed on our QA due to the new milestone Type
enum being 0-indexed. The valid range was 0 till 5, inclusive. While on
the previous zitadel version this was 1 till 6, inclusive.
# How the Problems Are Solved
Offset the first constant with `1`.
# Additional Changes
- none
# Additional Context
Introduced in https://github.com/zitadel/zitadel/pull/8788
Closes#8838
This fixes a bug of the `/register/org` page where scripts where not
referenced correctly
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
# Which Problems Are Solved
Resource owner can be different than expected if the provided
x-zitadel-orgid header is provided.
# How the Problems Are Solved
Check that the project is only checked with the correct resource owner
to avoid unexpected situations.
# Additional Changes
None
# Additional Context
Closes#8685
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
Milestones used existing events from a number of aggregates. OIDC
session is one of them. We noticed in load-tests that the reduction of
the oidc_session.added event into the milestone projection is a costly
business with payload based conditionals. A milestone is reached once,
but even then we remain subscribed to the OIDC events. This requires the
projections.current_states to be updated continuously.
# How the Problems Are Solved
The milestone creation is refactored to use dedicated events instead.
The command side decides when a milestone is reached and creates the
reached event once for each milestone when required.
# Additional Changes
In order to prevent reached milestones being created twice, a migration
script is provided. When the old `projections.milestones` table exist,
the state is read from there and `v2` milestone aggregate events are
created, with the original reached and pushed dates.
# Additional Context
- Closes https://github.com/zitadel/zitadel/issues/8800
# Which Problems Are Solved
Searching orgs by domain currently only looked for the primary domain,
but should be possible with all verified domains (as documented)
# How the Problems Are Solved
- fixed the search query
# Additional Changes
None
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/8749
# Which Problems Are Solved
In integration tests there is waiting for the application, but the
project is also included if the token can be created.
# How the Problems Are Solved
Wait for project not only for the application in the integration tests.
# Additional Changes
Some more corrections in integration tests.
# Additional Context
None
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
- **docs: s/Secondfactor/Second factor/**
- **docs: s/IDP/IdP/**
- **docs: s/Hardwaretokens/Hardware tokens/**
- **docs: standardize multi-factor vs multi factor vs multifactor**
# Which Problems Are Solved
- English strings are improved
# How the Problems Are Solved
- With better strings
---------
Co-authored-by: Fabi <fabienne@zitadel.com>
# Which Problems Are Solved
System administrators can block hosts and IPs for HTTP calls in actions.
Using DNS, blocked IPs could be bypassed.
# How the Problems Are Solved
- Hosts are resolved (DNS lookup) to check whether their corresponding
IP is blocked.
# Additional Changes
- Added complete lookup ip address range and "unspecified" address to
the default `DenyList`
# Which Problems Are Solved
Eventual consistency is handled wrongly in the newly improved
integration tests.
# How the Problems Are Solved
Correct the usage of the require package with the assert package where
necessary, to remove the panics where the EventuallyWithT functions can
rerun.
# Additional Changes
Modify the timeout values for some EventuallyWithT which can vary when a
instance is freshly setup.
# Additional Context
None
Improve integration tests:
- spliting the tests in TokenExchange to isolated instances and in
parallel
- corrected some test structure so that the check for Details is no done
anymore if the test already failed
- replace required-calls with assert-calls to not stop the testing
- add gofakeit for application, project and usernames(emails)
- add eventually checks for testing in actions v2, so the request only
get called when the execution is defined
- check for length of results in list/search endpoints to avoid index
errors
# Which Problems Are Solved
There is currently the possibility that you can jump to the register
path, even if register is disallowed through the settings.
# How the Problems Are Solved
Check before handling the HTTP requests if register is allowed.
# Additional Changes
Function to determine the resourceowner for all register related
functionality in the login.
# Additional Context
closes#8123
- Fully translated all UI elements, documentation, and error messages
- Added Hungarian as a new supported language option
- Updated language selection menus and related configuration files
- Ensured consistency across all translated content
# Which Problems Are Solved
- ZITADEL was not accessible for Hungarian-speaking users due to lack of
language support
- Hungarian users had to rely on English or other languages to use the
platform
- Potential user base was limited due to language barrier
# How the Problems Are Solved
- Translated all user interface elements, including console and login
interfaces
- Translated all documentation files to Hungarian
- Added Hungarian translations for all error messages and notifications
- Implemented Hungarian as a selectable language option in the system
# Additional Changes
- Updated language selection menus to include Hungarian
- Modified configuration files to support Hungarian language
- Ensured consistent terminology and style across all translated content
- Added Hungarian language option to relevant dropdown menus and
settings
# Additional Context
- Relates to the ongoing internationalization efforts of ZITADEL
- Enhances accessibility for Hungarian-speaking developers and users
- Expands ZITADEL's potential user base in Hungary and
Hungarian-speaking regions
---------
Co-authored-by: Max Peintner <max@caos.ch>
Co-authored-by: Tim Möhlmann <tim+github@zitadel.com>
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
# Which Problems Are Solved
Adding a SAML IDPs with an empty metadata XML and URL leads to failed
projection events. The main IDP template projection succeeds, but the
subtable projection for SAML template fails, because the metadata field
is not nullable in that table. The SAML IDP shows up in list queries,
because the list method only queries the main template projection.
However, getting a SAML IDP created without metadata by ID misses the
SAML specific IDP data.
# How the Problems Are Solved
- The command for adding a SAML IDP properly ensures that non-empty
metadata is either given by XML or resolved by URL.
- The console doesn't send requests with empty metadata anymore. This
works by explicitly setting a single oneof option for either XML or URL
and emptying the other one.
# Additional Context
Closes#8443
# Which Problems Are Solved
If SAML response validation in crewjam/saml fails, a generic
"Authentication failed" error is thrown. This makes it challenging to
determine the actual cause, since there are a variety of reasons
response validation may fail.
# How the Problems Are Solved
Add a log statement if we receive a response validation error from
crewjam/saml that logs the internal `InvalidResponseError.PrivateErr`
error from crewjam/saml to stdout. We continue to return a generic error
message to the client to prevent leaking data.
Verified by running `go test -v ./internal/idp/providers/saml` in
verbose mode, which output the following line for the "response_invalid"
test case:
```
time="2024-10-03T14:53:10+01:00" level=info msg="invalid SAML response details" caller="/Users/sdouglas/Documents/thirdparty-repos/zitadel/internal/idp/providers/saml/session.go:72" error="cannot parse base64: illegal base64 data at input byte 2"
```
# Additional Changes
None
# Additional Context
- closes#8717
---------
Co-authored-by: Stuart Douglas <sdouglas@hopper.com>
# Which Problems Are Solved
There is no option to only query auth methods related to specific
domains.
# How the Problems Are Solved
Add domain as attribute to the ListAuthenticationMethodTypes request.
# Additional Changes
OwnerRemoved column removed from the projection.
# Additional Context
Closes#8615
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
If an organization was preselected using an orgID or primaryDomain
scope, users could still switch to another organization, if the latter
allowed domain discovery and the entered username / or login_hint
included the corresponding domain suffix.
# How the Problems Are Solved
Domain discovery will only be done in case no org was preselected.
# Additional Changes
None
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/8464
- closes https://github.com/zitadel/zitadel/issues/8588
# Which Problems Are Solved
OTP Email links currently could not use / include the sessionID they
belong to. This prevents an easy use for redirecting and handling OTP
via email through the session API.
# How the Problems Are Solved
Added the sessionID as placeholder for the OTP Email link template.
# Additional Changes
List all available placeholders in the url_templates of V2 endpoints.
# Additional Context
- discussed in a customer meeting
# Which Problems Are Solved
Admins can set the branding to be used from the project's organization.
Until now, only the branding (colors) were respected, but texts were
still loaded from the user's organization.
# How the Problems Are Solved
Respect the setting when loading the texts for the login pages.
# Additional Changes
None
# Additional Context
- closes#8502
# Which Problems Are Solved
Since the optiimzation of the token endpoint, we longer push the
`user.token.added` event. However, the milestone projection keeps
quering for it, including a payload query.
This incured a static waste of DB resources.
# How the Problems Are Solved
Remove the `user.token.added` event reducer from the milestone
projection
# Additional Changes
- none
# Additional Context
- Related to https://github.com/zitadel/zitadel/issues/8742. Other
changes ommitted so this PR can be backported to stable.
# Which Problems Are Solved
There is no check that the creation of a project also has a resource
owner.
# How the Problems Are Solved
Check if resource owner and the ID of the owner are provided on command
side.
# Additional Changes
None
# Additional Context
Closes#7794
# Which Problems Are Solved
A customer reported, that after a created user (in initial state) got
(manually) locked and a new initial code would be created, the user
could not be locked again.
# How the Problems Are Solved
Query for the initial code added event
# Additional Changes
None
# Additional Context
- reported by a customer
# Which Problems Are Solved
Optimize the query that checks for terminated sessions in the access
token verifier. The verifier is used in auth middleware, userinfo and
introspection.
# How the Problems Are Solved
The previous implementation built a query for certain events and then
appended a single `PositionAfter` clause. This caused the postgreSQL
planner to use indexes only for the instance ID, aggregate IDs,
aggregate types and event types. Followed by an expensive sequential
scan for the position. This resulting in internal over-fetching of rows
before the final filter was applied.

Furthermore, the query was searching for events which are not always
applicable. For example, there was always a session ID search and if
there was a user ID, we would also search for a browser fingerprint in
event payload (expensive). Even if those argument string would be empty.
This PR changes:
1. Nest the position query, so that a full `instance_id, aggregate_id,
aggregate_type, event_type, "position"` index can be matched.
2. Redefine the `es_wm` index to include the `position` column.
3. Only search for events for the IDs that actually have a value. Do not
search (noop) if none of session ID, user ID or fingerpint ID are set.
New query plan:

# Additional Changes
- cleanup how we load multi-statement migrations and make that a bit
more reusable.
# Additional Context
- Related to https://github.com/zitadel/zitadel/issues/7639
# Which Problems Are Solved
To get the default organization we have no direct solution.
# How the Problems Are Solved
Add default organization as query to the org v2 List.
# Additional Changes
None
# Additional Context
Closes#8616
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
The recently added possibility to generate and verify codes through
Twilio verification service did failed on checking OTP SMS code through
the session API. Additionally, password codes generated by the V2 API
and sent through phone would always use the internal generator and
verification mechanism rather than the configured.
# How the Problems Are Solved
- Correctly set the verifier for OTP SMS for the session API
- Always use the internal verifier for OTP Email (for now)
- Select the generator / verifier based on the configuration for
password codes with notification type SMS for V2 APIs
# Additional Changes
None
# Additional Context
- relates to #8678
- reported by customer
---------
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
# Which Problems Are Solved
Cache implementation using a PGX connection pool.
# How the Problems Are Solved
Defines a new schema `cache` in the zitadel database.
A table for string keys and a table for objects is defined.
For postgreSQL, tables are unlogged and partitioned by cache name for
performance.
Cockroach does not have unlogged tables and partitioning is an
enterprise feature that uses alternative syntax combined with sharding.
Regular tables are used here.
# Additional Changes
- `postgres.Config` can return a pxg pool. See following discussion
# Additional Context
- Part of https://github.com/zitadel/zitadel/issues/8648
- Closes https://github.com/zitadel/zitadel/issues/8647
---------
Co-authored-by: Silvan <silvan.reusser@gmail.com>
# Which Problems Are Solved
https://github.com/zitadel/zitadel/pull/8545 incorrectly created the
list of current smtp providers, if an SMTP provider was changed, that
was created before https://github.com/zitadel/zitadel/pull/6932 /
[v2.50.0](https://github.com/zitadel/zitadel/releases/tag/v2.50.0)).
This led to problems when trying to send emails to users (email
verification and OTP email).
# How the Problems Are Solved
Correctly handle events of old SMTP configurations, which do not have an
id set.
# Additional Changes
None
# Additional Context
- relates to #8545
- support requests from cloud customers
# Which Problems Are Solved
Errors messages are mixed up for some policies
# How the Problems Are Solved
Define new error IDs and correct the messages.
# Additional Changes
None
# Additional Context
None
# Which Problems Are Solved
If a SAML IdP did not send a `NameID` (even though required by the
specification), ZITADEL would crash.
# How the Problems Are Solved
- Check specifically if the `Subject` and its `NameID` is passed
# Additional Changes
None
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/8654
# Which Problems Are Solved
There are cases where not all statements of multiExec are succeed. This
leads to inconsistent states. One example is [LDAP
IDPs](https://github.com/zitadel/zitadel/issues/7959).
If statements get executed only partially this can lead to inconsistent
states or even break projections for objects which might not were
correctly created in a sub table.
This behaviour is possible because we use
[`SAVEPOINTS`](https://www.postgresql.org/docs/current/sql-savepoint.html)
during each statement of a multiExec.
# How the Problems Are Solved
SAVEPOINTS are only created at the beginning of an exec function not
during every execution like before. Additionally `RELEASE` or `ROLLBACK`
of `SAVEPOINTS` are only used when needed.
# Additional Changes
- refactor some unused parameters
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/7959
# Which Problems Are Solved
V2 and V3 APIs allow setting the organization context by providing the
organization domain in the request. Users currently experience the
following error: "rpc error: code = Unauthenticated desc = context
missing (AUTH-rKLWEH)"
# How the Problems Are Solved
Correctly check the org domain when set.
# Additional Changes
None
# Additional Context
- support request
# Which Problems Are Solved
Calls with tokens issued through JWT Profile or Client Credentials
Grants were no longer possible and threw a "could not read projectid by
clientid (AUTH-GHpw2)" error.
ZITADEL checks the allowed origins of an application and load its
projectID into the context on any API call.
Tokens from service accounts did not contain any clientID and therefore
never did that check.
But due to a change in https://github.com/zitadel/zitadel/pull/8580,
were the service user id was set as client_id in the OIDC session to fix
the introspection response
(https://github.com/zitadel/zitadel/issues/8590).
# How the Problems Are Solved
- Check if the project and origin were retrieved and only then check the
origins
# Additional Changes
None.
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/8676
- relates to https://github.com/zitadel/zitadel/pull/8580 (released on
2.62.0)
- relates to https://github.com/zitadel/zitadel/issues/8590
# Which Problems Are Solved
When executing many concurrent authentication requests on a single
machine user, there were performance issues. As the same aggregate is
being searched and written to concurrently, we traced it down to a
locking issue on the used index.
We already optimized the token endpoint by creating a separate OIDC
aggregate.
At the time we decided to push a single event to the user aggregate, for
the user audit log. See [technical advisory
10010](https://zitadel.com/docs/support/advisory/a10010) for more
details.
However, a recent security fix introduced an additional search query on
the user aggregate, causing the locking issue we found.
# How the Problems Are Solved
Add a feature flag which disables pushing of the `user.token.v2.added`.
The event has no importance and was only added for informational
purposes on the user objects. The `oidc_session.access_token.added` is
the actual payload event and is pushed on the OIDC session aggregate and
can still be used for audit trail.
# Additional Changes
- Fix an event mapper type for
`SystemOIDCSingleV1SessionTerminationEventType`
# Additional Context
- Reported by support request
- https://github.com/zitadel/zitadel/pull/7822 changed the token
aggregate
- https://github.com/zitadel/zitadel/pull/8631 introduced user state
check
Load test trace graph with `user.token.v2.added` **enabled**. Query
times are steadily increasing:

Load test trace graph with `user.token.v2.added` **disabled**. Query
times constant:

---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
Twilio supports a robust, multi-channel verification service that
notably supports multi-region SMS sender numbers required for our use
case. Currently, Zitadel does much of the work of the Twilio Verify (eg.
localization, code generation, messaging) but doesn't support the pool
of sender numbers that Twilio Verify does.
# How the Problems Are Solved
To support this API, we need to be able to store the Twilio Service ID
and send that in a verification request where appropriate: phone number
verification and SMS 2FA code paths.
This PR does the following:
- Adds the ability to use Twilio Verify of standard messaging through
Twilio
- Adds support for international numbers and more reliable verification
messages sent from multiple numbers
- Adds a new Twilio configuration option to support Twilio Verify in the
admin console
- Sends verification SMS messages through Twilio Verify
- Implements Twilio Verification Checks for codes generated through the
same
# Additional Changes
# Additional Context
- base was implemented by @zhirschtritt in
https://github.com/zitadel/zitadel/pull/8268❤️
- closes https://github.com/zitadel/zitadel/issues/8581
---------
Co-authored-by: Zachary Hirschtritt <zachary.hirschtritt@klaviyo.com>
Co-authored-by: Joey Biscoglia <joey.biscoglia@klaviyo.com>
# Which Problems Are Solved
We identified the need of caching.
Currently we have a number of places where we use different ways of
caching, like go maps or LRU.
We might also want shared chaches in the future, like Redis-based or in
special SQL tables.
# How the Problems Are Solved
Define a generic Cache interface which allows different implementations.
- A noop implementation is provided and enabled as.
- An implementation using go maps is provided
- disabled in defaults.yaml
- enabled in integration tests
- Authz middleware instance objects are cached using the interface.
# Additional Changes
- Enabled integration test command raceflag
- Fix a race condition in the limits integration test client
- Fix a number of flaky integration tests. (Because zitadel is super
fast now!) 🎸🚀
# Additional Context
Related to https://github.com/zitadel/zitadel/issues/8648
# Which Problems Are Solved
Endpoints to maintain email and phone contact on user v3 are not
implemented.
# How the Problems Are Solved
Add 3 endpoints with SetContactEmail, VerifyContactEmail and
ResendContactEmailCode.
Add 3 endpoints with SetContactPhone, VerifyContactPhone and
ResendContactPhoneCode.
Refactor the logic how contact is managed in the user creation and
update.
# Additional Changes
None
# Additional Context
- part of https://github.com/zitadel/zitadel/issues/6433
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
ZITADEL's user account deactivation mechanism did not work correctly
with service accounts. Deactivated service accounts retained the ability
to request tokens, which could lead to unauthorized access to
applications and resources.
# How the Problems Are Solved
Additionally to checking the user state on the session API and login UI,
the state is checked on all oidc session methods resulting in a new
token or when returning the user information (userinfo, introspection,
id_token / access_token and saml attributes)
# Which Problems Are Solved
ZITADEL's user grants deactivation mechanism did not work correctly.
Deactivated user grants were still provided in token, which could lead
to unauthorized access to applications and resources.
Additionally, the management and auth API always returned the state as
active or did not provide any information about the state.
# How the Problems Are Solved
- Correctly check the user grant state on active for tokens and user
information (userinfo, introspection, saml attributes)
- Map state in API and display in Console
# Which Problems Are Solved
In Zitadel, even after an organization is deactivated, associated
projects, respectively their applications remain active. Users across
other organizations can still log in and access through these
applications, leading to unauthorized access.
Additionally, if a project was deactivated access to applications was
also still possible.
# How the Problems Are Solved
- Correctly check the status of the organization and related project.
(Corresponding functions have been renamed to `Active...`)
# Which Problems Are Solved
Reduce the chance for projection dead-locks. Increasing or disabling the
projection transaction duration solved dead-locks in all reported cases.
# How the Problems Are Solved
Increase the default transaction duration to 1 minute.
Due to the high value it is functionally similar to disabling,
however it still provides a safety net for transaction that do freeze,
perhaps due to connection issues with the database.
# Additional Changes
- Integration test uses default.
- Technical advisory
# Additional Context
- Related to https://github.com/zitadel/zitadel/issues/8517
---------
Co-authored-by: Silvan <silvan.reusser@gmail.com>
# Which Problems Are Solved
Users are not yet able to update their information an status in user API
v3.
# How the Problems Are Solved
Add endpoints and functionality to update users and their status in user
API v3.
# Additional Changes
Aggregate_type and event_types are updated with "userschema" to avoid
conflicts with old events.
# Additional Context
closes#7898
# Which Problems Are Solved
If a user is created through the login UI with an IdP and an unverified
email, the user is prompted with the email verification and to set a
password.
This was unintentionally changed with #8291
# How the Problems Are Solved
- Check if the user has any IdP linked when computing the
EmailVerification step.
# Additional Changes
None
# Additional Context
- reported in a support request
There were some problems after changing from SMTP providers to email
providers (https://github.com/zitadel/zitadel/pull/8545):
- panic (nil pointer) on SMTP provider retrieval for HTTP configs
- old SMTP configuration created before the multi SMTP configurations
(without id)
- were not projected / listed
- could not be always be activated
- Console treated HTTP configs as SMTP
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
When the `openid` scope was not requested, as is possible in machine
authentication, we didn't set the `sub` (subject) claim to tokens and
possibly also userInfo and introspection.
This fix always sets the `sub` claim for all cases.
# How the Problems Are Solved
Set the `Subject` field to regardless of passed scopes.
# Additional Changes
- none
# Additional Context
According to standards:
- [RFC9068 - JSON Web Token (JWT) Profile for OAuth 2.0 Access
Tokens](https://datatracker.ietf.org/doc/html/rfc9068#name-data-structure)
this claim is **required**.
- [RFC7667 - OAuth 2.0 Token
Introspection](https://datatracker.ietf.org/doc/html/rfc7662#section-2.2)
the claim is optional, however there is no correlation to the `openid`
or OpenID Connect. Therefore it doesn't harm to always return this
claim.
- [OpenID connect, User Info
Response](https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse):
"The sub (subject) Claim **MUST** always be returned in the UserInfo
Response."
Closes https://github.com/zitadel/zitadel/issues/8591
# Which Problems Are Solved
Send Email messages as a HTTP call to a relay, for own logic on handling
different Email providers
# How the Problems Are Solved
Create endpoints under Email provider to manage SMTP and HTTP in the
notification handlers.
# Additional Changes
Clean up old logic in command and query side to handle the general Email
providers with deactivate, activate and remove.
# Additional Context
Partially closes#8270
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
Apple is not availabe as IDP type in the settings v2 API.
# How the Problems Are Solved
Add Apple as type.
# Additional Changes
None
# Additional Context
None
Co-authored-by: Max Peintner <max@caos.ch>
# Which Problems Are Solved
As an administrator I want to be able to invite users to my application
with the API V2, some user data I will already prefil, the user should
add the authentication method themself (password, passkey, sso).
# How the Problems Are Solved
- A user can now be created with a email explicitly set to false.
- If a user has no verified email and no authentication method, an
`InviteCode` can be created through the User V2 API.
- the code can be returned or sent through email
- additionally `URLTemplate` and an `ApplicatioName` can provided for
the email
- The code can be resent and verified through the User V2 API
- The V1 login allows users to verify and resend the code and set a
password (analog user initialization)
- The message text for the user invitation can be customized
# Additional Changes
- `verifyUserPasskeyCode` directly uses `crypto.VerifyCode` (instead of
`verifyEncryptedCode`)
- `verifyEncryptedCode` is removed (unnecessarily queried for the code
generator)
# Additional Context
- closes#8310
- TODO: login V2 will have to implement invite flow:
https://github.com/zitadel/typescript/issues/166
# Which Problems Are Solved
In actions/v3 there was no check for the feature flag on any of the:
- ListExecutionFunctions
- ListExecutionMethods
- ListExecutionServices
In the integration tests `ensureFeatureEnabled` relies on
`ListExecutionMethods` to return an error if the feature is not enabled.
This fix makes the test wait untill the feature is fully projected.
# How the Problems Are Solved
Add the feature check to all of the above methods.
# Additional Changes
- none
# Additional Context
Flaky introduced in https://github.com/zitadel/zitadel/pull/8407
# Which Problems Are Solved
Improve performance by removing a GetUserByID call. The call also
executed a Trigger on projections, which significantly impacted
concurrent requests.
# How the Problems Are Solved
Token creation needs information from the user, such as the resource
owner and access token type.
For client credentials this is solved in a single search. By getting the
user by username (`client_id`), the user details and secret were
obtained in a single query. After that verification and token creation
can proceed. For JWT profile it is a bit more complex. We didn't know
anything about the user until after JWT verification.
The verification did a query for the AuthN key and after that we did a
GetUserByID to get remaining details.
This change uses a joined query when the OIDC library calls the
`GetKeyByIDAndClientID` method on the token storage. The found user
details are set to the verifieer object and returned after verification
is completed.
It is safe because the `jwtProfileKeyStorage` is a single-use object as
a wrapper around `query.Queries`.
This way getting the public key and user details are obtained in a
single query.
# Additional Changes
- Correctly set the `client_id` field with machine's username.
# Additional Context
- Related to: https://github.com/zitadel/zitadel/issues/8352
# Which Problems Are Solved
Add a debug API which allows pushing a set of events to be reduced in a
dedicated projection.
The events can carry a sleep duration which simulates a slow query
during projection handling.
# How the Problems Are Solved
- `CreateDebugEvents` allows pushing multiple events which simulate the
lifecycle of a resource. Each event has a `projectionSleep` field, which
issues a `pg_sleep()` statement query in the projection handler :
- Add
- Change
- Remove
- `ListDebugEventsStates` list the current state of the projection,
optionally with a Trigger
- `GetDebugEventsStateByID` get the current state of the aggregate ID in
the projection, optionally with a Trigger
# Additional Changes
- none
# Additional Context
- Allows reproduction of https://github.com/zitadel/zitadel/issues/8517
# Which Problems Are Solved
defaults.yaml only specifies defaults for cockroach. Therefore, options
omitted for postgresql are actually set to `0`.
This means that the connections timeouts are set to `0` and connections
were not reused, resulting in a performance penalty while running the
integration tests.
# How the Problems Are Solved
Set MaxConnLifeTime and MaxConnIdleTime options in postgres
# Additional Changes
- none
# Additional Context
- none
Co-authored-by: Silvan <silvan.reusser@gmail.com>
Co-authored-by: Livio Spring <livio.a@gmail.com>