# Which Problems Are Solved
In the "new" structured logging, request details were added in different
middlewares, such as request, instance and user IDs. This meant the the
upstream request logging middleware did not have access to metadata that
got added later, resulting in incomplete logs. Furthermore it was not
possible to correlate an API error response to log output.
# How the Problems Are Solved
A mutable request details object is added to the context early on. When
the api authz function run, the instance and user IDs are added to this
object as they become available. Every logline emitted after this
(time-wise) will then all contain these details under the `request` log
group.
<details>
<summary>example output in JSON</summary>
```json
{
"time": "2026-03-13T19:21:20.890428806Z",
"level": "INFO",
"source": {
"function": "github.com/zitadel/zitadel/internal/api/grpc/server/connect_middleware.LogHandler.func1.1",
"file": "/workspaces/zitadel/internal/api/grpc/server/connect_middleware/log_interceptor.go",
"line": 34
},
"msg": "request served",
"request": {
"id": "d6q67c04vtjmi77cbbpg",
"instance_host": "localhost:8080",
"instance_id": "362349751439458307",
"user_id": "362349751440048131"
},
"TraceID": "a9e0fee3522224f3583bbdcda737f4b4",
"SpanID": "a563056eee36920a",
"stream": "request",
"version": "2026-03-13T19:20:59Z",
"protocol": "connect",
"service": "zitadel.user.v2.UserService",
"http_method": "POST",
"path": "/zitadel.user.v2.UserService/ListUsers",
"code": "code_0",
"duration": 12254350
}
```
</details>
Request IDs are now also returned with a response header or metadata.
Depending on the protocol:
- HTTP calls always return the request ID as header, regardless of
status
- gRPC calls always return the request ID as header, even if there was
an error
- connect RPC calls returns the request ID as header on success, trailer
in case of error. This is because header must be set on the response
object, which is nil in case of error. When there is an error, metadata
can be added which are then sent as trailers.
# Additional Changes
- Use the existing call duration middleware for both request ID and
logging for a consistent request start timestamp in all layers.
- Upgrade sloggcp for some fixes (notably TraceID)
- Modify the NoCache middleware so it uses `SetHeaders` instead of
`SendHeaders`. The latter prevented any other handler from setting
headers, including the new request ID middleware.
# Additional Context
Follow up on demo of:
- https://github.com/zitadel/zitadel/pull/11159
- https://github.com/zitadel/zitadel/pull/11435
- backport to v4
---------
Co-authored-by: Copilot <[email protected]>
Co-authored-by: muhlemmer <[email protected]>
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Co-authored-by: Marco A. <[email protected]>
# Which Problems Are Solved
This PR adds functionality to propagate request headers in actions v2.
# How the Problems Are Solved
The new functionality is added to the`ExecutionHandler` interceptors,
where the incoming request headers (from a list of allowed headers to be
forwarded) are set in the payload of the request before calling the
target.
# Additional Changes
This PR also contains minor fixes to the Actions V2 example docs.
# Additional Context
- Closes#9941
---------
Co-authored-by: Marco A. <[email protected]>
# Which Problems Are Solved
The CORS handler for the new connectRPC handlers was missing, leading to
unhandled preflight requests and a unusable api for browser based calls,
e.g. cross domain gRPC-web requests.
# How the Problems Are Solved
- Added the http CORS middleware to the connectRPC handlers.
- Added `Grpc-Timeout`, `Connect-Protocol-Version`,`Connect-Timeout-Ms`
to the default allowed headers (this improves also the old grpc-web
handling)
- Added `Grpc-Status`, `Grpc-Message`, `Grpc-Status-Details-Bin` to the
default exposed headers (this improves also the old grpc-web handling)
# Additional Changes
None
# Additional Context
noticed internally while testing other issues
# Which Problems Are Solved
- Adds infrastructure code (basic implementation, error handling,
middlewares, ...) to implement the SCIM v2 interface
- Adds support for the user create SCIM v2 endpoint
# How the Problems Are Solved
- Adds support for the user create SCIM v2 endpoint under `POST
/scim/v2/{orgID}/Users`
# Additional Context
Part of #8140
# Which Problems Are Solved
Events like "password check succeeded" store some information about the
caller including their IP.
The `X-Forwarded-For` was not correctly logged, but instead the
RemoteAddress.
# How the Problems Are Solved
- Correctly get the `X-Forwarded-For` in canonical form.
# Additional Changes
None
# Additional Context
closes [#9106](https://github.com/zitadel/zitadel/issues/9106)
# 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
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
* take baseurl if saved on event
* refactor: make es mocks reusable
* Revert "refactor: make es mocks reusable"
This reverts commit 434ce12a6acf639514308bc231e76ebb8676b643.
* make messages testable
* test asset url
* fmt
* fmt
* simplify notification.Start
* test url combinations
* support init code added
* support password changed
* support reset pw
* support user domain claimed
* support add pwless login
* support verify phone
* Revert "support verify phone"
This reverts commit e40503303e2fdda0c85985b3fe3160ce96d43cca.
* save trigger origin from ctx
* add ready for review check
* camel
* test email otp
* fix variable naming
* fix DefaultOTPEmailURLV2
* Revert "fix DefaultOTPEmailURLV2"
This reverts commit fa34d4d2a83fbfd8353759c9148af9165a9dd44c.
* fix email otp challenged test
* fix email otp challenged test
* pass origin in login and gateway requests
* take origin from header
* take x-forwarded if present
* Update internal/notification/handlers/queries.go
Co-authored-by: Tim Möhlmann <[email protected]>
* Update internal/notification/handlers/commands.go
Co-authored-by: Tim Möhlmann <[email protected]>
* move origin header to ctx if available
* generate
* cleanup
* use forwarded header
* support X-Forwarded-* headers
* standardize context handling
* fix linting
---------
Co-authored-by: Tim Möhlmann <[email protected]>
* fix: 404 for robots.txt and meta robots tags
* fix: add unit tests for robots txt and tag
* fix: add meta tag robots none for login pages
* fix: weird format issue in header.go
* fix: add x-robots-tag=none to grpcwebserver
* fix linting
---------
Co-authored-by: Silvan <[email protected]>
Co-authored-by: Livio Spring <[email protected]>