
# 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>
6.5 KiB
title |
---|
Actions V2 |
This page describes the options you have when defining ZITADEL Actions V2.
Endpoints
ZITADEL sends an HTTP Post request to the endpoint set as Target, the received request than can be edited and send back or custom processes can be handled.
Sent information Request
The information sent to the Endpoint is structured as JSON:
{
"fullMethod": "full method of the GRPC call",
"instanceID": "instanceID of the called instance",
"orgID": "ID of the organization related to the calling context",
"projectID": "ID of the project related to the used application",
"userID": "ID of the calling user",
"request": "full request of the call"
}
Sent information Response
The information sent to the Endpoint is structured as JSON:
{
"fullMethod": "full method of the GRPC call",
"instanceID": "instanceID of the called instance",
"orgID": "ID of the organization related to the calling context",
"projectID": "ID of the project related to the used application",
"userID": "ID of the calling user",
"request": "full request of the call",
"response": "full response of the call"
}
Target
The Target describes how ZITADEL interacts with the Endpoint.
There are different types of Targets:
Webhook
, the call handles the status code but response is irrelevant, can be InterruptOnErrorCall
, the call handles the status code and response, can be InterruptOnErrorAsync
, the call handles neither status code nor response, but can be called in parallel with other Targets
InterruptOnError
means that the Execution gets interrupted if any of the calls return with a status code >= 400, and the next Target will not be called anymore.
The API documentation to create a target can be found here
Execution
ZITADEL decides on specific conditions if one or more Targets have to be called. The Execution resource contains 2 parts, the condition and the called targets.
The condition can be defined for 4 types of processes:
Requests
, before a request is processed by ZITADELResponses
, before a response is sent back to the applicationFunctions
, handling specific functionality in the logic of ZITADELEvents
, after a specific event happened and was stored in ZITADEL
The API documentation to set an Execution can be found here
Condition Best Match
As the conditions can be defined on different levels, ZITADEL tries to find out which Execution is the best match.
This means that for example if you have an Execution defined on all requests
, on the service zitadel.user.v2.UserService
and on /zitadel.user.v2.UserService/AddHumanUser
,
ZITADEL would with a call on the /zitadel.user.v2.UserService/AddHumanUser
use the Executions with the following priority:
/zitadel.user.v2.UserService/AddHumanUser
zitadel.user.v2.UserService
all
If you then have a call on /zitadel.user.v2.UserService/UpdateHumanUser
the following priority would be found:
zitadel.user.v2.UserService
all
And if you use a different service, for example zitadel.session.v2.SessionService
, then the all
Execution would still be used.
Targets and Includes
:::info Includes are limited to 3 levels, which mean that include1->include2->include3 is the maximum for now. If you have feedback to the include logic, or a reason why 3 levels are not enough, please open an issue on github or start a discussion on github/start a topic on discord :::
An execution can not only contain a list of Targets, but also Includes. The Includes can be defined in the Execution directly, which means you include all defined Targets by a before set Execution.
If you define 2 Executions as follows:
{
"condition": {
"request": {
"service": "zitadel.user.v2.UserService"
}
},
"targets": [
{
"target": "<TargetID1>"
}
]
}
{
"condition": {
"request": {
"method": "/zitadel.user.v2.UserService/AddHumanUser"
}
},
"targets": [
{
"target": "<TargetID2>"
},
{
"include": {
"request": {
"service": "zitadel.user.v2.UserService"
}
}
}
]
}
The called Targets on "/zitadel.user.v2.UserService/AddHumanUser" would be, in order:
<TargetID2>
<TargetID1>
Condition for Requests and Responses
For Request and Response there are 3 levels the condition can be defined:
Method
, handling a request or response of a specific GRPC full method, which includes the service name and method of the ZITADEL APIService
, handling any request or response under a service of the ZITADEL APIAll
, handling any request or response under the ZITADEL API
The available conditions can be found under:
- All available Methods, for example
/zitadel.user.v2.UserService/AddHumanUser
- All available Services, for example
zitadel.user.v2.UserService
Condition for Functions
Replace the current Actions with the following flows:
The available conditions can be found under all available Functions.
Condition for Events
For event there are 3 levels the condition can be defined:
- Event, handling a specific event
- Group, handling a specific group of events
- All, handling any event in ZITADEL
The concept of events can be found under Events
Error forwarding
If you want to forward a specific error from the Target through ZITADEL, you can provide a response from the Target with status code 200 and a JSON in the following format:
{
"forwardedStatusCode": 403,
"forwardedErrorMessage": "Call is forbidden through the IP AllowList definition"
}
Only values from 400 to 499 will be forwarded through ZITADEL, other StatusCodes will end in a PreconditionFailed error.
If the Target returns any other status code than >= 200 and < 299, the execution is looked at as failed, and a PreconditionFailed error is logged.