# 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>
# Which Problems Are Solved
Return the user's project roles when the
`urn:zitadel:iam:org:projects:roles` scope is requested.
We alreayd returned it for access tokens, now also ID tokens.
# How the Problems Are Solved
Set `idTokenRoleAssertion` to `true` when calling
`accessTokenResponseFromSession` for service users. This parameter is
normally set to the client config. However, service user authentication
does not have a client.
# Additional Changes
- none
# Additional Context
- Introduced in https://github.com/zitadel/zitadel/pull/8046
- Closes https://github.com/zitadel/zitadel/issues/8107
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
Deal with eventual consistency in the webkey integration tests.
# How the Problems Are Solved
Use an eventual with T for the list state check.
# Additional Changes
- none
# Additional Context
- none
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
When checking for the next step for the login UI and a user did not yet
have an IdP linked, they would always be presented the password check
screen, even if the local authentication was disabled.
# How the Problems Are Solved
- Correctly check the login policy for the `Allow Username Password`
option
- In case the user has no IdP linked yet, fallback to the organizations
configuration (and redirect if possible)
- the user can be auto-linked based on the username / email after
successfully authenticating at the IdP
# Additional Changes
None
# Additional Context
- closes https://github.com/zitadel/zitadel/issues/5106
- closes https://github.com/zitadel/zitadel/issues/7502
# Which Problems Are Solved
Send SMS messages as a HTTP call to a relay, for own logic on handling
different SMS providers.
# How the Problems Are Solved
Add HTTP as SMS provider type and handling of webhook messages in the
notification handlers.
# Additional Changes
Clean up old Twilio events, which were supposed to handle the general
SMS providers with deactivate, activate and remove.
# Additional Context
Partially closes#8270
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
Use a single server instance for API integration tests. This optimizes
the time taken for the integration test pipeline,
because it allows running tests on multiple packages in parallel. Also,
it saves time by not start and stopping a zitadel server for every
package.
# How the Problems Are Solved
- Build a binary with `go build -race -cover ....`
- Integration tests only construct clients. The server remains running
in the background.
- The integration package and tested packages now fully utilize the API.
No more direct database access trough `query` and `command` packages.
- Use Makefile recipes to setup, start and stop the server in the
background.
- The binary has the race detector enabled
- Init and setup jobs are configured to halt immediately on race
condition
- Because the server runs in the background, races are only logged. When
the server is stopped and race logs exist, the Makefile recipe will
throw an error and print the logs.
- Makefile recipes include logic to print logs and convert coverage
reports after the server is stopped.
- Some tests need a downstream HTTP server to make requests, like quota
and milestones. A new `integration/sink` package creates an HTTP server
and uses websockets to forward HTTP request back to the test packages.
The package API uses Go channels for abstraction and easy usage.
# Additional Changes
- Integration test files already used the `//go:build integration`
directive. In order to properly split integration from unit tests,
integration test files need to be in a `integration_test` subdirectory
of their package.
- `UseIsolatedInstance` used to overwrite the `Tester.Client` for each
instance. Now a `Instance` object is returned with a gRPC client that is
connected to the isolated instance's hostname.
- The `Tester` type is now `Instance`. The object is created for the
first instance, used by default in any test. Isolated instances are also
`Instance` objects and therefore benefit from the same methods and
values. The first instance and any other us capable of creating an
isolated instance over the system API.
- All test packages run in an Isolated instance by calling
`NewInstance()`
- Individual tests that use an isolated instance use `t.Parallel()`
# Additional Context
- Closes#6684
- https://go.dev/doc/articles/race_detector
- https://go.dev/doc/build-cover
---------
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
# Which Problems Are Solved
Float64 which was used for the event.Position field is [not precise in
go and gets rounded](https://github.com/golang/go/issues/47300). This
can lead to unprecies position tracking of events and therefore
projections especially on cockcoachdb as the position used there is a
big number.
example of a unprecies position:
exact: 1725257931223002628
float64: 1725257931223002624.000000
# How the Problems Are Solved
The float64 was replaced by
[github.com/jackc/pgx-shopspring-decimal](https://github.com/jackc/pgx-shopspring-decimal).
# Additional Changes
Correct behaviour of makefile for load tests.
Rename `latestSequence`-queries to `latestPosition`
# Which Problems Are Solved
The end_session_endpoint currently always requires the userAgent cookie
to be able to terminate session created through the hosted login UI.
Only tokens issued through the Login V2 can be used to directly
terminate a specific session and without the need of a cookie.
This PR adds the possibility to terminate a single V1 session or all V1
sessions belonging to the same user agent without the need of the
userAgent cookie by providing an id_token as `id_token_hint` which
contains the id of a V1 session as `sid`.
# How the Problems Are Solved
- #8525 added the `sid` claim for id_tokens issued through the login UI
- The `sid` can now be checked for the `V1_` prefix and queries for
either the userAgentID and depending on the
`OIDCSingleV1SessionTermination` flag all userIDs of active session from
the same user agent id
- The `OIDCSingleV1SessionTermination` flag is added with default value
false to keep the existing behavior of terminating all sessions even in
case of providing an id_token_hint
# Additional Changes
- pass `context.Context` into session view functions for querying the
database with that context
# Additional Context
- relates to #8499
- closes#8501
# Which Problems Are Solved
id_tokens issued for auth requests created through the login UI
currently do not provide a sid claim.
This is due to the fact that (SSO) sessions for the login UI do not have
one and are only computed by the userAgent(ID), the user(ID) and the
authentication checks of the latter.
This prevents client to track sessions and terminate specific session on
the end_session_endpoint.
# How the Problems Are Solved
- An `id` column is added to the `auth.user_sessions` table.
- The `id` (prefixed with `V1_`) is set whenever a session is added or
updated to active (from terminated)
- The id is passed to the `oidc session` (as v2 sessionIDs), to expose
it as `sid` claim
# Additional Changes
- refactored `getUpdateCols` to handle different column value types and
add arguments for query
# Additional Context
- closes#8499
- relates to #8501
# Which Problems Are Solved
UserSchema API is currently not completely as defined for v3alpha.
# How the Problems Are Solved
Update the protos and integration tests.
# Additional Changes
None
# Additional Context
None
# Which Problems Are Solved
Added functionality that user with a userschema can be created and
removed.
# How the Problems Are Solved
Added logic and moved APIs so that everything is API v3 conform.
# Additional Changes
- move of user and userschema API to resources folder
- changed testing and parameters
- some renaming
# Additional Context
closes#7308
---------
Co-authored-by: Elio Bischof <elio@zitadel.com>
# Which Problems Are Solved
Do not push secret succeeded and failed events for API and OIDC clients
on the introspection endpoint.
On instances where introspection was fequently called, the pushed events
created issues on duplicate primary keys, due to collisions on the
`sequence` column in the eventstore. As the event pusher retries on this
collision and we pushed above mentioned events async, it would create a
backpressure of concurrent pushers and effectively cripple an instance.
We considered that pushing these events have little value with regards
to the audit trail, as we do not push similar events when client
assertion is used. Also, before #7657 the events were defined, but not
pushed.
# How the Problems Are Solved
- Removed API secret check succeeded and faild event definitions
- Removed OIDC secret check succeeded and faild event definitions
- Push only Hash Updated event when needed
# Additional Changes
- None
# Additional Context
- Fixes https://github.com/zitadel/zitadel/issues/8479
- Closes https://github.com/zitadel/zitadel/issues/8430
- Intoduced in https://github.com/zitadel/zitadel/pull/7657
# Which Problems Are Solved
There were UX issue with the autolinking prompt page and users were not
able to link their account or would not understand what to do. Since the
trust to the IdP is already bound by the configuration, the user can
directly be linked without any user input.
# How the Problems Are Solved
- remove the prompt page and directly link the user if possible
- remove corresponding customization texts from the API and Console
# Additional Changes
None
# Additional Context
- relates to https://github.com/zitadel/zitadel/issues/7977
- discussed with customers
- created as a `fix` to be able to backport
---------
Co-authored-by: Max Peintner <max@caos.ch>
# Which Problems Are Solved
The access token verifier returned a permission denied (HTTP 403 / GRPC
7) instead of a unauthenticated (HTTP 401 / GRPC 16) error.
# How the Problems Are Solved
Return the correct error type.
# Additional Changes
None
# Additional Context
close#8392
# Which Problems Are Solved
When using a JWT access_token on a ZITADEL API, the token was considered
invalid If the `WebKey` feature flag is enabled.
# How the Problems Are Solved
- Merge the new and old web keys if flag is enabled (as already done for
the keys endpoint).
# Additional Changes
None
# Additional Context
relates to #8449
# Which Problems Are Solved
Use web keys, managed by the `resources/v3alpha/web_keys` API, for OIDC
token signing and verification,
as well as serving the public web keys on the jwks / keys endpoint.
Response header on the keys endpoint now allows caching of the response.
This is now "safe" to do since keys can be created ahead of time and
caches have sufficient time to pickup the change before keys get
enabled.
# How the Problems Are Solved
- The web key format is used in the `getSignerOnce` function in the
`api/oidc` package.
- The public key cache is changed to get and store web keys.
- The jwks / keys endpoint returns the combined set of valid "legacy"
public keys and all available web keys.
- Cache-Control max-age default to 5 minutes and is configured in
`defaults.yaml`.
When the web keys feature is enabled, fallback mechanisms are in place
to obtain and convert "legacy" `query.PublicKey` as web keys when
needed. This allows transitioning to the feature without invalidating
existing tokens. A small performance overhead may be noticed on the keys
endpoint, because 2 queries need to be run sequentially. This will
disappear once the feature is stable and the legacy code gets cleaned
up.
# Additional Changes
- Extend legacy key lifetimes so that tests can be run on an existing
database with more than 6 hours apart.
- Discovery endpoint returns all supported algorithms when the Web Key
feature is enabled.
# Additional Context
- Closes https://github.com/zitadel/zitadel/issues/8031
- Part of https://github.com/zitadel/zitadel/issues/7809
- After https://github.com/zitadel/oidc/pull/637
- After https://github.com/zitadel/oidc/pull/638
# Which Problems Are Solved
IDPLinks list and other list endpoints can provide you with empty
results if the used user has no permission for the information.
# How the Problems Are Solved
List endpoints with subelements to users, and provided userIDQuery, will
return a PermissionDenied error if no permission for the user exsists.
# Additional Changes
Function to check for permission is re-used from the GetUserByID.
# Additional Context
Closes#8451
# Which Problems Are Solved
#8369 added the possibility to handle trusted domains for public hosts
as response. Additionally, the OIDC issuer is extracted from the
`DomainContext` and not from headers anymore.
This accidentally dropped support for the `x-zitadel-forwarded`.
# How the Problems Are Solved
Added `x-zitadel-forwarded` in the list of additionally handled headers.
# Additional Changes
None
# Additional Context
- relates to #8369
- reported in Discord:
https://discord.com/channels/927474939156643850/1275484169626980403
# Which Problems Are Solved
Currently the OIDC API of ZITADEL only prints parent errors to the logs.
Where 4xx status are typically warn level and 5xx error level. This
makes it hard to debug certain errors for client in multi-instance
environments like ZITADEL cloud, where there is no direct access to
logs. In case of support requests we often can't correlate past
log-lines to the error that was reported.
This change adds the possibility to return the parent error in the
response to the OIDC client. For the moment this only applies to JSON
body responses, not error redirects to the RP.
# How the Problems Are Solved
- New instance-level feature flag: `debug_oidc_parent_error`
- Use the new `WithReturnParentToClient()` function from the oidc lib
introduced in https://github.com/zitadel/oidc/pull/629 for all cases
where `WithParent` was already used and the request context is
available.
# Additional Changes
none
# Additional Context
- Depends on: https://github.com/zitadel/oidc/pull/629
- Related to: https://github.com/zitadel/zitadel/issues/8362
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
Sometimes integrations tests are failing with an error `http: no
location header in response`. The underlying cause was hidden, as in
some tests we assumed a 3xx range response but got a 4xx response
instead. No assertion on the status code was made, resulting in the
above error message on calling `resp.Location()`.
The underlying issue, the application not found in the projection, is
also fixed.
# How the Problems Are Solved
This change adds a check for the status code and returns the response
body if the response is not in the 3xx status code range.
Helper function that create applications now do an additional
`GetAppByID` in a retry loop to ensure consitency in the projection
before proceeding with tests.
# Additional Changes
- none
# Additional Context
- Pipline failures were observed, no issue was created
- Cherry-picked form WIP #8407
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
To have more insight on the performance, CPU and memory usage of
ZITADEL, we want to enable profiling.
# How the Problems Are Solved
- Allow profiling by configuration.
- Provide Google Cloud Profiler as first implementation
# Additional Changes
None.
# Additional Context
There were possible memory leaks reported:
https://discord.com/channels/927474939156643850/1273210227918897152
Co-authored-by: Silvan <silvan.reusser@gmail.com>
# Which Problems Are Solved
When Web keys with a large RSA Bitsize were generated, the new web key
did not get projected.
Zitadel logs printed the following errors:
```
time="2024-08-15T09:18:47Z" level=debug msg="execution of statements failed" caller="/home/tim/Repositories/zitadel/zitadel/internal/eventstore/handler/v2/handler.go:518" error="statement failed: ID=CRDB-pKtsr Message=exec failed Parent=(ERROR: index row size 3400 exceeds btree version 4 maximum 2704 for index \"web_keys_web_key_state_idx\" (SQLSTATE 54000))" lastProcessedIndex=-1 projection=projections.web_keys
```
# How the Problems Are Solved
Remove the the `WithInclude` option with the Private key from the
`web_keys` projection index and bump the projection version.
# Additional Changes
- Correct RPC summaries for documentation
- Fix docs slug in sidebar.js
# Additional Context
- Found during release review.
# Which Problems Are Solved
Execution responses with HTTP StatusCode not equal to 200 interrupt the
client request silently.
# How the Problems Are Solved
Adds information about the recieved StatusCode and Body into the error
if StatusCode not 200.
# Additional Context
Closes#8177
---------
Co-authored-by: Elio Bischof <elio@zitadel.com>
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
In case a user was deleted and recreated with the same id, they would
never be able to authenticate through the login UI, since it would
return an error "User not active".
This was due to the check in the auth request / session handling for the
login UI, where the user removed event would terminate an further event
check and ignore the newly added user.
# How the Problems Are Solved
- The user removed event no longer returns an error, but is handled as a
session termination event.
(A user removed event will already delete the user and the preceding
`activeUserById` function will deny the authentication.)
# Additional Changes
Updated tests to be able to handle multiple events in the mocks.
# Additional Context
closes https://github.com/zitadel/zitadel/issues/8201
Co-authored-by: Silvan <silvan.reusser@gmail.com>
# Which Problems Are Solved
Org v2 service does not have a ListOrganizations endpoint.
# How the Problems Are Solved
Implement ListOrganizations endpoint.
# Additional Changes
- moved descriptions in the protos to comments
- corrected the RemoveNoPermissions for the ListUsers, to get the
correct TotalResults
# Additional Context
For new typescript login
# Which Problems Are Solved
GetIDPByID as endpoint in the API v2 so that it can be available for the
new login.
# How the Problems Are Solved
Create GetIDPByID endpoint with IDP v2 API, throught the GetProviderByID
implementation from admin and management API.
# Additional Changes
- Remove the OwnerType attribute from the response, as the information
is available through the resourceOwner.
- correct refs to messages in proto which are used for doc generation
- renaming of elements for API v3
# Additional Context
Closes#8337
---------
Co-authored-by: Livio Spring <livio.a@gmail.com>
# Which Problems Are Solved
Implement a new API service that allows management of OIDC signing web
keys.
This allows users to manage rotation of the instance level keys. which
are currently managed based on expiry.
The API accepts the generation of the following key types and
parameters:
- RSA keys with 2048, 3072 or 4096 bit in size and:
- Signing with SHA-256 (RS256)
- Signing with SHA-384 (RS384)
- Signing with SHA-512 (RS512)
- ECDSA keys with
- P256 curve
- P384 curve
- P512 curve
- ED25519 keys
# How the Problems Are Solved
Keys are serialized for storage using the JSON web key format from the
`jose` library. This is the format that will be used by OIDC for
signing, verification and publication.
Each instance can have a number of key pairs. All existing public keys
are meant to be used for token verification and publication the keys
endpoint. Keys can be activated and the active private key is meant to
sign new tokens. There is always exactly 1 active signing key:
1. When the first key for an instance is generated, it is automatically
activated.
2. Activation of the next key automatically deactivates the previously
active key.
3. Keys cannot be manually deactivated from the API
4. Active keys cannot be deleted
# Additional Changes
- Query methods that later will be used by the OIDC package are already
implemented. Preparation for #8031
- Fix indentation in french translation for instance event
- Move user_schema translations to consistent positions in all
translation files
# Additional Context
- Closes#8030
- Part of #7809
---------
Co-authored-by: Elio Bischof <elio@zitadel.com>
# Which Problems Are Solved
As of now, **automatic creation** and **automatic linking options** were
only considered if the corresponding **allowed option** (account
creation / linking allowed) was enabled.
With this PR, this is no longer needed and allows administrators to
address cases, where only an **automatic creation** is allowed, but
users themselves should not be allowed to **manually** create new
accounts using an identity provider or edit the information during the
process.
Also, allowing users to only link to the proposed existing account is
now possible with an enabled **automatic linking option**, while
disabling **account linking allowed**.
# How the Problems Are Solved
- Check for **automatic** options without the corresponding **allowed**
option.
- added technical advisory to notify about the possible behavior change
# Additional Changes
- display the error message on the IdP linking step in the login UI (in
case there is one)
- display an error in case no option is possible
- exchanged deprecated `eventstoreExpect` with `expectEventstore` in
touched test files
# Additional Context
closes https://github.com/zitadel/zitadel/issues/7393
---------
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
# Which Problems Are Solved
Log some details when a secret generator is not found.
This should help us debugging such issue.
# How the Problems Are Solved
When a secret generator by type query fails,
we log the generator type and instance id for which
the generator was requested.
# Additional Changes
- none
# Additional Context
- Related to https://github.com/zitadel/zitadel/issues/8379
- Also encountered in https://github.com/zitadel/zitadel/pull/8407
# Which Problems Are Solved
The current v3alpha actions APIs don't exactly adhere to the [new
resources API
design](https://zitadel.com/docs/apis/v3#standard-resources).
# How the Problems Are Solved
- **Improved ID access**: The aggregate ID is added to the resource
details object, so accessing resource IDs and constructing proto
messages for resources is easier
- **Explicit Instances**: Optionally, the instance can be explicitly
given in each request
- **Pagination**: A default search limit and a max search limit are
added to the defaults.yaml. They apply to the new v3 APIs (currently
only actions). The search query defaults are changed to ascending by
creation date, because this makes the pagination results the most
deterministic. The creation date is also added to the object details.
The bug with updated creation dates is fixed for executions and targets.
- **Removed Sequences**: Removed Sequence from object details and
ProcessedSequence from search details
# Additional Changes
Object details IDs are checked in unit test only if an empty ID is
expected. Centralizing the details check also makes this internal object
more flexible for future evolutions.
# Additional Context
- Closes#8169
- Depends on https://github.com/zitadel/zitadel/pull/8225
---------
Co-authored-by: Silvan <silvan.reusser@gmail.com>
Co-authored-by: Stefan Benz <46600784+stebenz@users.noreply.github.com>
# Which Problems Are Solved
The mirror command used the wrong position to filter for events if
different database technologies for source and destination were used.
# How the Problems Are Solved
The statements which diverge are stored on the client so that different
technologies can use different statements.
# Additional Context
- https://discord.com/channels/927474939156643850/1256396896243552347
# Which Problems Are Solved
There was no default configuration for `DeviceAuth`, which makes it
impossible to override by environment variables.
Additionally, a custom `CharAmount` value would overwrite also the
`DashInterval`.
# How the Problems Are Solved
- added to defaults.yaml
- fixed customization
# Additional Changes
None.
# Additional Context
- noticed during a customer request
# Which Problems Are Solved
If the processing time of serializable transactions in the fields
handler take too long, the next iteration can fail.
# How the Problems Are Solved
Changed the isolation level of the current states query to Read Commited
# Which Problems Are Solved
During triggering of the fields table WriteTooOld errors can occure when
using cockroachdb.
# How the Problems Are Solved
The statements exclusively lock the projection before they start to
insert data by using `FOR UPDATE`.
# Which Problems Are Solved
We noticed logging where 500: Internal Server errors were returned from
the token endpoint, mostly for the `refresh_token` grant. The error was
thrown by the database as it received non-UTF8 strings for token IDs
Zitadel uses symmetric encryption for opaque tokens, including refresh
tokens. Encrypted values are base64 encoded. It appeared to be possible
to send garbage base64 to the token endpoint, which will pass decryption
and string-splitting. In those cases the resulting ID is not a valid
UTF-8 string.
Invalid non-UTF8 strings are now rejected during token decryption.
# How the Problems Are Solved
- `AESCrypto.DecryptString()` checks if the decrypted bytes only contain
valid UTF-8 characters before converting them into a string.
- `AESCrypto.Decrypt()` is unmodified and still allows decryption on
non-UTF8 byte strings.
- `FromRefreshToken` now uses `DecryptString` instead of `Decrypt`
# Additional Changes
- Unit tests added for `FromRefreshToken` and
`AESCrypto.DecryptString()`.
- Fuzz tests added for `FromRefreshToken` and
`AESCrypto.DecryptString()`. This was to pinpoint the problem
- Testdata with values that resulted in invalid strings are committed.
In the pipeline this results in the Fuzz tests to execute as regular
unit-test cases. As we don't use the `-fuzz` flag in the pipeline no
further fuzzing is performed.
# Additional Context
- Closes#7765
- https://go.dev/doc/tutorial/fuzz
# Which Problems Are Solved
ZITADEL currently selects the instance context based on a HTTP header
(see https://github.com/zitadel/zitadel/issues/8279#issue-2399959845 and
checks it against the list of instance domains. Let's call it instance
or API domain.
For any context based URL (e.g. OAuth, OIDC, SAML endpoints, links in
emails, ...) the requested domain (instance domain) will be used. Let's
call it the public domain.
In cases of proxied setups, all exposed domains (public domains) require
the domain to be managed as instance domain.
This can either be done using the "ExternalDomain" in the runtime config
or via system API, which requires a validation through CustomerPortal on
zitadel.cloud.
# How the Problems Are Solved
- Two new headers / header list are added:
- `InstanceHostHeaders`: an ordered list (first sent wins), which will
be used to match the instance.
(For backward compatibility: the `HTTP1HostHeader`, `HTTP2HostHeader`
and `forwarded`, `x-forwarded-for`, `x-forwarded-host` are checked
afterwards as well)
- `PublicHostHeaders`: an ordered list (first sent wins), which will be
used as public host / domain. This will be checked against a list of
trusted domains on the instance.
- The middleware intercepts all requests to the API and passes a
`DomainCtx` object with the hosts and protocol into the context
(previously only a computed `origin` was passed)
- HTTP / GRPC server do not longer try to match the headers to instances
themself, but use the passed `http.DomainContext` in their interceptors.
- The `RequestedHost` and `RequestedDomain` from authz.Instance are
removed in favor of the `http.DomainContext`
- When authenticating to or signing out from Console UI, the current
`http.DomainContext(ctx).Origin` (already checked by instance
interceptor for validity) is used to compute and dynamically add a
`redirect_uri` and `post_logout_redirect_uri`.
- Gateway passes all configured host headers (previously only did
`x-zitadel-*`)
- Admin API allows to manage trusted domain
# Additional Changes
None
# Additional Context
- part of #8279
- open topics:
- "single-instance" mode
- Console UI
# Which Problems Are Solved
The current v3alpha actions APIs don't exactly adhere to the [new
resources API
design](https://zitadel.com/docs/apis/v3#standard-resources).
# How the Problems Are Solved
- **Breaking**: The current v3alpha actions APIs are removed. This is
breaking.
- **Resource Namespace**: New v3alpha actions APIs for targets and
executions are added under the namespace /resources.
- **Feature Flag**: New v3alpha actions APIs still have to be activated
using the actions feature flag
- **Reduced Executions Overhead**: Executions are managed similar to
settings according to the new API design: an empty list of targets
basically makes an execution a Noop. So a single method, SetExecution is
enough to cover all use cases. Noop executions are not returned in
future search requests.
- **Compatibility**: The executions created with previous v3alpha APIs
are still available to be managed with the new executions API.
# Additional Changes
- Removed integration tests which test executions but rely on readable
targets. They are added again with #8169
# Additional Context
Closes#8168
# Which Problems Are Solved
ZITADEL administrators can enable a setting called "Ignoring unknown
usernames" which helps mitigate attacks that try to guess/enumerate
usernames. If enabled, ZITADEL will show the password prompt even if the
user doesn't exist and report "Username or Password invalid".
Due to a implementation change to prevent deadlocks calling the
database, the flag would not be correctly respected in all cases and an
attacker would gain information if an account exist within ZITADEL,
since the error message shows "object not found" instead of the generic
error message.
# How the Problems Are Solved
- Proper check of the error using an error function / type and
`errors.Is`
# Additional Changes
None.
# Additional Context
- raised in a support request
Co-authored-by: Silvan <silvan.reusser@gmail.com>
# Which Problems Are Solved
ZITADEL uses HTML for emails and renders certain information such as
usernames dynamically. That information can be entered by users or
administrators. Due to a missing output sanitization, these emails could
include malicious code.
This may potentially lead to a threat where an attacker, without
privileges, could send out altered notifications that are part of the
registration processes. An attacker could create a malicious link, where
the injected code would be rendered as part of the email.
During investigation of this issue a related issue was found and
mitigated, where on the user's detail page the username was not
sanitized and would also render HTML, giving an attacker the same
vulnerability.
While it was possible to inject HTML including javascript, the execution
of such scripts would be prevented by most email clients and the Content
Security Policy in Console UI.
# How the Problems Are Solved
- All arguments used for email are sanitized (`html.EscapeString`)
- The email text no longer `html.UnescapeString` (HTML in custom text is
still possible)
- Console no longer uses `[innerHtml]` to render the username
# Additional Changes
None
# Additional Context
- raised via email
---------
Co-authored-by: peintnermax <max@caos.ch>
# Which Problems Are Solved
The v2beta services are stable but not GA.
# How the Problems Are Solved
The v2beta services are copied to v2. The corresponding v1 and v2beta
services are deprecated.
# Additional Context
Closes#7236
---------
Co-authored-by: Elio Bischof <elio@zitadel.com>
# Which Problems Are Solved
I fixed more spelling and grammar misstakes in the German language
files.
# Additional Context
- Follow-up for PR #8240
Co-authored-by: Fabi <fabienne@zitadel.com>
# Which Problems Are Solved
The initial load of the login UI with dark mode preference
(prefers-color-scheme: dark) first rendered the logo configured for
light mode. Also switching from dark to light or vice versa would result
in the same behavior.
This was due to a mixed logic of server (based on cookie) and client
(prefers-color-scheme and cookie) deciding which mode to render.
# How the Problems Are Solved
- Since the main logic of which mode to use (`prefers-color-scheme`) can
only be achieve client side, both logos will be served in the HTML and
either will be rendered based on CSS.
# Additional Changes
None
# Additional Context
- closes#2085
# Which Problems Are Solved
The default terms of service and privacy policy links are applied to all
new ZITADEL instances, also for self hosters. However, the links
contents don't apply to self-hosters.
# How the Problems Are Solved
The links are removed from the DefaultInstance section in the
*defaults.yaml* file.
By default, the links are not shown anymore in the hosted login pages.
They can still be configured using the privacy policy.
# Additional Context
- Found because of a support request
# Which Problems Are Solved
- Adds delete phone endpoint to v2 api
# How the Problems Are Solved
- Adds new endpoint with DELETE method to /v2beta/users/:userId/phone
which removes currently set phone number
# Additional Changes
- Added integration test for new endpoint.
# Additional Context
- Solves
https://discord.com/channels/927474939156643850/1255557862286032996