mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 11:57:22 +00:00
chore: API guidelines (#9340)
# Which Problems Are Solved There were no guideline to how design future APIs and their endpoints. The V3 documentation was to specific and targeted towards internal stakeholders. This PR is intended as base and kept to the minimum. If more details or additional guideline or rules are needed, they will be added in the future. # How the Problems Are Solved - Removed the V3 description and corresponding examples. - Provided general guideline for the design of APIs, which includes the structure, naming, versioning, error handling and more. # Additional Changes None # Additional Context closes #9184 --------- Co-authored-by: Maximilian <mpa@zitadel.com> Co-authored-by: Silvan <27845747+adlerhurst@users.noreply.github.com>
This commit is contained in:
parent
444f682e25
commit
4df3b6492c
344
API_DESIGN.md
Normal file
344
API_DESIGN.md
Normal file
@ -0,0 +1,344 @@
|
||||
# API Design
|
||||
|
||||
This document describes the design principles and conventions for the ZITADEL API. It is scoped to the services and
|
||||
endpoints of the proprietary ZITADEL API and does not cover any standardized APIs like OAuth 2, OpenID Connect or SCIM.
|
||||
|
||||
## The Basics
|
||||
ZITADEL follows an API first approach. This means all features can not only be accessed via the UI but also via the API.
|
||||
The API is designed using the Protobuf specification. The Protobuf specification is then used to generate the API client
|
||||
and server code in different programming languages.
|
||||
The API is designed to be used by different clients, such as web applications, mobile applications, and other services.
|
||||
Therefore, the API is designed to be easy to use, consistent, and reliable.
|
||||
|
||||
Starting with the V2 API, the API and its services use a resource-oriented design.
|
||||
This means that the API is designed around resources, which are the key entities in the system.
|
||||
Each resource has a unique identifier and a set of properties that describe the resource.
|
||||
The entire lifecycle of a resource can be managed using the API.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> This style guide is a work in progress and will be updated over time.
|
||||
> Not all parts of the API might follow the guidelines yet.
|
||||
> However, all new endpoints and services MUST be designed according to this style guide.
|
||||
|
||||
### Protobuf, gRPC and connectRPC
|
||||
|
||||
The API is designed using the Protobuf specification. The Protobuf specification is used to define the API services, messages, and methods.
|
||||
Starting with the V2 API, the API uses connectRPC as the main transport protocol.
|
||||
[connectRPC](https://connectrpc.com/) is a protocol that is based on gRPC and HTTP/2.
|
||||
It allows clients to call the API using connectRPC, gRPC and also HTTP/1.1.
|
||||
|
||||
## Conventions
|
||||
|
||||
The API follows the base conventions of Protobuf and connectRPC.
|
||||
|
||||
Please check out their style guides and concepts for more information:
|
||||
- Protobuf: https://protobuf.dev/programming-guides/style/
|
||||
- gRPC: https://grpc.io/docs/what-is-grpc/core-concepts/
|
||||
- Buf: https://buf.build/docs/best-practices/style-guide/
|
||||
|
||||
Additionally, there are some conventions that are specific to the ZITADEL API.
|
||||
These conventions are described in the following sections.
|
||||
|
||||
### Versioning
|
||||
|
||||
The services and messages are versioned using major version numbers. This means that any change within a major version number is backward compatible.
|
||||
Any breaking change requires a new major version number.
|
||||
Each service is versioned independently. This means that a service can have a different version number than another service.
|
||||
When creating a new service, start with version `2`, as version `1` is reserved for the old context based API and services.
|
||||
|
||||
Please check out the structure Buf style guide for more information about the folder and package structure: https://buf.build/docs/best-practices/style-guide/
|
||||
|
||||
### Explicitness
|
||||
|
||||
Make the handling of the API as explicit as possible. Do not make assumptions about the client's knowledge of the system or the API.
|
||||
Provide clear and concise documentation for the API.
|
||||
|
||||
Do not rely on implicit fallbacks or defaults if the client does not provide certain parameters.
|
||||
Only use defaults if they are explicitly documented, such as returning a result set for the whole instance if no filter is provided.
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
Names of resources, fields and methods MUST be descriptive and consistent.
|
||||
Use domain-specific terminology and avoid abbreviations.
|
||||
For example, use `organization_id` instead of **org_id** or **resource_owner** for the creation of a new user or when returning one.
|
||||
|
||||
> [!NOTE]
|
||||
> We'll update the resources in the [concepts section](https://zitadel.com/docs/concepts/structure/instance) to describe
|
||||
> common resources and their meaning.
|
||||
> Until then, please refer to the following issue: https://github.com/zitadel/zitadel/issues/5888
|
||||
|
||||
#### Resources and Fields
|
||||
|
||||
When a context is required for creating a resource, the context is added as a field to the resource.
|
||||
For example, when creating a new user, the organization's id is required. The `organization_id` is added as a field to the `CreateUserRequest`.
|
||||
|
||||
```protobuf
|
||||
message CreateUserRequest {
|
||||
...
|
||||
string organization_id = 7 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
];
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Only allow providing a context where it is required. The context MUST not be provided if not required.
|
||||
For example, when retrieving or updating a user, the `organization_id` is not required, since the user can be determined by the user's id.
|
||||
However, it is possible to provide the `organization_id` as a filter to retrieve a list of users of a specific organization.
|
||||
|
||||
Prevent the creation of global messages that are used in multiple resources unless they always follow the same pattern.
|
||||
Use dedicated fields as described above or create a separate message for the specific context, that is only used in the boundary of the same resource.
|
||||
For example, settings might be set as a default on the instance level, but might be overridden on the organization level.
|
||||
In this case, the settings could share the same `SettingsContext` message to determine the context of the settings.
|
||||
But do not create a global `Context` message that is used across the whole API if there are different scenarios and different fields required for the context.
|
||||
The same applies to messages that are returned by multiple resources.
|
||||
For example, information about the `User` might be different when managing the user resource itself than when it's returned
|
||||
as part of an authorization or a manager role, where only limited information is needed.
|
||||
|
||||
Prevent reusing messages for the creation and the retrieval of a resource.
|
||||
Returning messages might contain additional information that is not required or even not available for the creation of the resource.
|
||||
What might sound obvious when designing the CreateUserRequest for example, where only an `organization_id` but not the
|
||||
`organization_name` is available, might not be so obvious when designing some sub-resource like a user's `IdentityProviderLink`,
|
||||
which might contain an `identity_provider_name` when returned but not when created.
|
||||
|
||||
```protobuf
|
||||
message CreateUserRequest {
|
||||
...
|
||||
repreated AddIdentityProviderLink identity_provider_links = 8;
|
||||
...
|
||||
}
|
||||
|
||||
message AddIdentityProviderLink {
|
||||
string identity_provider_id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
];
|
||||
string user_id = 2 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
];
|
||||
string user_name = 3;
|
||||
}
|
||||
|
||||
message IdentiyProviderLink {
|
||||
string identity_provider_id = 1;
|
||||
string identity_provider_name = 2;
|
||||
string user_id = 3;
|
||||
string user_name = 4;
|
||||
}
|
||||
```
|
||||
|
||||
#### Operations and Methods
|
||||
|
||||
Methods on a resource MUST be named using the following convention:
|
||||
|
||||
| Operation | Method Name | Description |
|
||||
|-----------|--------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Create | Create\<resource\> | Create a new resource. If the new resource conflicts with an existing resources uniqueness (id, loginname, ...) the creation MUST be prevented and an error returned. |
|
||||
| Update | Update\<resource\> | Update an existing resource. In most cases this SHOULD allow partial updates. If there are exception, they MUST be explicitly documented on the endpoint. The resource MUST already exists. An error is returned otherwise. |
|
||||
| Delete | Delete\<resource\> | Delete an existing resource. If the resource does not exist, no error SHOULD be returned. In case of an exception to this rule, the behavior MUST clearly be documented. |
|
||||
| Set | Set\<resource\> | Set a resource. This will replace the existing resource with the new resource. In case where the creation and update of a resource do not need to be differentiated, a single `Set` method SHOULD be used. It SHOULD allow partial changes. |
|
||||
| Get | Get\<resource\> | Retrieve a single resource by its unique identifier. If the resource does not exist, an error MUST be returned. |
|
||||
| List | List\<resource\> | Retrieve a list of resources. The endpoint SHOULD provide options to filter, sort and paginate. |
|
||||
|
||||
Methods on a list of resources MUST be named using the following convention:
|
||||
|
||||
| Operation | Method Name | Description |
|
||||
|-----------|--------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Add | Add\<resource\> | Add a new resource to a list. Any existing unique constraint (id, loginname, ...) will prevent the addition and return an error. |
|
||||
| Remove | Remove\<resource\> | Remove an existing resource from a list. If the resource does not exist in the list, no error SHOULD be returned. In case of an exception to this rule, the behavior MUST clearly be documented. |
|
||||
| Set | Set\<resource\> | Set a list of resources. This will replace the existing list with the new list. |
|
||||
|
||||
Additionally, state changes, specific actions or operations that do not fit into the CRUD operations SHOULD be named according to the action that is performed:
|
||||
- `Activate` or `Deactivate` for enabling or disabling a resource.
|
||||
- `Verify` for verifying a resource.
|
||||
- `Send` for sending a resource.
|
||||
- etc.
|
||||
|
||||
## Authentication and Authorization
|
||||
|
||||
The API uses OAuth 2 for authorization. There are corresponding middlewares that check the access token for validity and
|
||||
automatically return an error if the token is invalid.
|
||||
|
||||
Permissions grated to the user are organization specific and might only be checked based on the queried resource.
|
||||
Therefore, the API does not check the permissions itself but relies on the checks of the functions that are called by the API.
|
||||
Required permissions need to be documented in the [API documentation](#documentation).
|
||||
|
||||
## Pagination
|
||||
|
||||
The API uses pagination for listing resources. The client can specify a limit and an offset to retrieve a subset of the resources.
|
||||
Additionally, the client can specify sorting options to sort the resources by a specific field.
|
||||
|
||||
Most listing methods SHOULD provide use the `ListQuery` message to allow the client to specify the limit, offset, and sorting options.
|
||||
```protobuf
|
||||
|
||||
// ListQuery is a general query object for lists to allow pagination and sorting.
|
||||
message ListQuery {
|
||||
uint64 offset = 1;
|
||||
// limit is the maximum amount of objects returned. The default is set to 100
|
||||
// with a maximum of 1000 in the runtime configuration.
|
||||
// If the limit exceeds the maximum configured ZITADEL will throw an error.
|
||||
// If no limit is present the default is taken.
|
||||
uint32 limit = 2;
|
||||
// Asc is the sorting order. If true the list is sorted ascending, if false
|
||||
// the list is sorted descending. The default is descending.
|
||||
bool asc = 3;
|
||||
}
|
||||
```
|
||||
On the corresponding responses the `ListDetails` can be used to return the total count of the resources
|
||||
and allow the user to handle their offset and limit accordingly.
|
||||
|
||||
|
||||
## Error Handling
|
||||
|
||||
The API returns machine-readable errors in the response body. This includes a status code, an error code and possibly
|
||||
some details about the error. See the following sections for more information about the status codes, error codes and error messages.
|
||||
|
||||
### Status Codes
|
||||
|
||||
The API uses status codes to indicate the status of a request. Depending on the protocol used to call the API,
|
||||
the status code is returned as an HTTP status code or as a gRPC / connectRPC status code.
|
||||
Check the possible status codes https://zitadel.com/docs/apis/statuscodes
|
||||
|
||||
### Error Codes
|
||||
|
||||
Additionally to the status code, the API returns unique error codes for each type of error.
|
||||
The error codes are used to identify a specific error and can be used to handle the error programmatically.
|
||||
|
||||
> [!NOTE]
|
||||
> Currently, ZITADEL might already return some error codes. However, they do not follow a specific pattern yet
|
||||
> and are not documented. We will update the error codes and document them in the future.
|
||||
|
||||
### Error Message and Details
|
||||
|
||||
The API returns additional details about the error in the response body.
|
||||
This includes a human-readable error message and additional information that can help the client to understand the error
|
||||
as well as machine-readable details that can be used to handle the error programmatically.
|
||||
Error details use the Google RPC error details format: https://github.com/googleapis/googleapis/blob/master/google/rpc/error_details.proto
|
||||
|
||||
### Example
|
||||
|
||||
HTTP/1.1 example:
|
||||
```
|
||||
HTTP/1.1 400 Bad Request
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"code": "user_missing_information",
|
||||
"message": "missing required information for the creation of the user",
|
||||
"details": [
|
||||
{
|
||||
"@type": "type.googleapis.com/google.rpc.BadRequest",
|
||||
"fieldViolations": [
|
||||
{
|
||||
"field": "given_name",
|
||||
"description": "given name is required"
|
||||
},
|
||||
{
|
||||
"field": "family_name",
|
||||
"description": "family name is required"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
gRPC / connectRPC example:
|
||||
```
|
||||
HTTP/2.0 200 OK
|
||||
Content-Type: application/grpc
|
||||
Grpc-Message: missing required information for the creation of the user
|
||||
Grpc-Status: 3
|
||||
|
||||
{
|
||||
"code": "user_missing_information",
|
||||
"message": "missing required information for the creation of the user",
|
||||
"details": [
|
||||
{
|
||||
"@type": "type.googleapis.com/google.rpc.BadRequest",
|
||||
"fieldViolations": [
|
||||
{
|
||||
"field": "given_name",
|
||||
"description": "given name is required"
|
||||
},
|
||||
{
|
||||
"field": "family_name",
|
||||
"description": "family name is required"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Documentation
|
||||
|
||||
- Document the purpose of the API, the services, the endpoints, the request and response messages, the error codes and the status codes.
|
||||
- Describe the fields of the request and response messages, the purpose and if needed the constraints.
|
||||
- Document if the endpoints requires specific permissions or roles.
|
||||
- Document and explain the possible error codes and the error messages that can be returned by the API.
|
||||
|
||||
#### Examples
|
||||
|
||||
```protobuf
|
||||
// CreateUser will create a new user (human or machine) in the specified organization.
|
||||
// The username must be unique.
|
||||
//
|
||||
// For human users:
|
||||
// The user will receive a verification email if the email address is not marked as verified.
|
||||
// You can pass a hashed_password. This allows migrating your users from your own system to ZITADEL, without any password
|
||||
// reset for the user. Please check the required format and supported algorithms: <Link to documentation>.
|
||||
//
|
||||
// Required permission:
|
||||
// - user.write
|
||||
//
|
||||
// Error Codes:
|
||||
// - user_missing_information: The request is missing required information (either given_name, family_name and/or email) for the creation of the user. Check error details for the missing fields.
|
||||
// - user_already_exists: The user already exists. The username must be unique.
|
||||
// - invalid_request: Your request does not have a valid format. Check error details for the reason.
|
||||
// - permission_denied: You do not have the required permissions to access the requested resource.
|
||||
// - unauthenticated: You are not authenticated. Please provide a valid access token.
|
||||
rpc CreatUser(CreatUserRequest) returns (CreatUserResponse) {}
|
||||
```
|
||||
|
||||
```protobuf
|
||||
// ListUsers will return all matching users. By default, we will return all users of your instance that you have permission to read. Make sure to include a limit and sorting for pagination.
|
||||
//
|
||||
// Required permission:
|
||||
// - user.read
|
||||
// - no permission required to own user
|
||||
//
|
||||
// Error Codes:
|
||||
// - invalid_request: Your request does not have a valid format. Check error details for the reason.
|
||||
// - permission_denied: You do not have the required permissions to access the requested resource.
|
||||
// - unauthenticated: You are not authenticated. Please provide a valid access token.
|
||||
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) {}
|
||||
```
|
||||
|
||||
```protobuf
|
||||
// VerifyEmail will verify the provided verification code and mark the email as verified on success.
|
||||
// An error is returned if the verification code is invalid or expired or if the user does not exist.
|
||||
// Note that if multiple verification codes are generated, only the last one is valid.
|
||||
//
|
||||
// Required permission:
|
||||
// - no permission required, the user must be authenticated
|
||||
//
|
||||
// Error Codes:
|
||||
// - invalid_verification_code: The verification code is invalid or expired.
|
||||
// - invalid_request: Your request does not have a valid format. Check error details for the reason.
|
||||
// - unauthenticated: You are not authenticated. Please provide a valid access token.
|
||||
rpc VerifyEmail (VerifyEmailRequest) returns (VerifyEmailResponse) {}
|
||||
```
|
||||
|
||||
```protobuf
|
||||
message VerifyEmailRequest{
|
||||
// The id of the user to verify the email for.
|
||||
string user_id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200}
|
||||
];
|
||||
// The verification code generated and sent to the user.
|
||||
string verification_code = 2 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 20}
|
||||
];
|
||||
}
|
||||
|
||||
```
|
@ -141,6 +141,13 @@ Replace "policeman" with "police officer," "manpower" with "workforce," and "bus
|
||||
Ableist language includes words or phrases such as crazy, insane, blind to or blind eye to, cripple, dumb, and others.
|
||||
Choose alternative words depending on the context.
|
||||
|
||||
### API
|
||||
|
||||
ZITADEL follows an API first approach. This means all features can not only be accessed via the UI but also via the API.
|
||||
The API is designed to be used by different clients, such as web applications, mobile applications, and other services.
|
||||
Therefore, the API is designed to be easy to use, consistent, and reliable.
|
||||
Please check out the dedicated [API guidelines](./API_DESIGN.md) page when contributing to the API.
|
||||
|
||||
### Developing ZITADEL with Dev Containers
|
||||
|
||||
Follow the instructions provided by your code editor/IDE to initiate the development container. This typically involves opening the "Command Palette" or similar functionality and searching for commands related to "Dev Containers" or "Remote Containers". The quick start guide for VS Code can found [here](https://code.visualstudio.com/docs/devcontainers/containers#_quick-start-open-an-existing-folder-in-a-container)
|
||||
|
@ -1,123 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.resources.action.v3alpha;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/struct.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
import "zitadel/protoc_gen_zitadel/v2/options.proto";
|
||||
|
||||
import "zitadel/resources/object/v3alpha/object.proto";
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/resources/action/v3alpha;action";
|
||||
|
||||
message Execution {
|
||||
Condition condition = 1;
|
||||
// Target IDs which are called when the defined conditions trigger.
|
||||
repeated string targets = 2;
|
||||
// Included executions with the same condition-types.
|
||||
repeated string includes = 3;
|
||||
}
|
||||
|
||||
message GetExecution {
|
||||
zitadel.resources.object.v3alpha.Details details = 1;
|
||||
Execution execution = 2;
|
||||
}
|
||||
|
||||
message Condition {
|
||||
// Condition-types under which conditions the execution should trigger. Only one is possible.
|
||||
oneof condition_type {
|
||||
option (validate.required) = true;
|
||||
|
||||
// Condition-type to execute after a request on the defined API point is received.
|
||||
RequestExecution request = 1;
|
||||
// Condition-type to execute before a response on the defined API point is returned.
|
||||
ResponseExecution response = 2;
|
||||
// Condition-type to execute when a function is used, replaces actions v1.
|
||||
string function = 3;
|
||||
// Condition-type to execute after an event is created in the system.
|
||||
EventExecution event = 4;
|
||||
}
|
||||
}
|
||||
|
||||
message RequestExecution {
|
||||
// Condition for the request execution. Only one is possible.
|
||||
oneof condition{
|
||||
// GRPC-method as condition.
|
||||
string method = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 1000},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 1000,
|
||||
example: "\"/zitadel.session.v2.SessionService/ListSessions\"";
|
||||
}
|
||||
];
|
||||
// GRPC-service as condition.
|
||||
string service = 2 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 1000},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 1000,
|
||||
example: "\"zitadel.session.v2.SessionService\"";
|
||||
}
|
||||
];
|
||||
// All calls to any available services and methods as condition.
|
||||
bool all = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message ResponseExecution {
|
||||
// Condition for the response execution. Only one is possible.
|
||||
oneof condition{
|
||||
// GRPC-method as condition.
|
||||
string method = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 1000},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 1000,
|
||||
example: "\"/zitadel.session.v2.SessionService/ListSessions\"";
|
||||
}
|
||||
];
|
||||
// GRPC-service as condition.
|
||||
string service = 2 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 1000},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 1000,
|
||||
example: "\"zitadel.session.v2.SessionService\"";
|
||||
}
|
||||
];
|
||||
// All calls to any available services and methods as condition.
|
||||
bool all = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message EventExecution{
|
||||
// Condition for the event execution. Only one is possible.
|
||||
oneof condition{
|
||||
// Event name as condition.
|
||||
string event = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 1000},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 1000,
|
||||
example: "\"user.human.added\"";
|
||||
}
|
||||
];
|
||||
// Event group as condition, all events under this group.
|
||||
string group = 2 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 1000},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 1000,
|
||||
example: "\"user.human\"";
|
||||
}
|
||||
];
|
||||
// all events as condition.
|
||||
bool all = 3;
|
||||
}
|
||||
}
|
||||
|
@ -1,111 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.resources.action.v3alpha;
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/resources/action/v3alpha;action";
|
||||
|
||||
import "google/api/field_behavior.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
import "zitadel/resources/object/v3alpha/object.proto";
|
||||
import "zitadel/resources/action/v3alpha/execution.proto";
|
||||
|
||||
message ExecutionSearchFilter {
|
||||
oneof filter {
|
||||
option (validate.required) = true;
|
||||
|
||||
InConditionsFilter in_conditions = 1;
|
||||
ExecutionTypeFilter execution_type = 2;
|
||||
TargetFilter target = 3;
|
||||
IncludeFilter include = 4;
|
||||
}
|
||||
}
|
||||
|
||||
message InConditionsFilter {
|
||||
// Defines the conditions to query for.
|
||||
repeated Condition conditions = 1;
|
||||
}
|
||||
|
||||
message ExecutionTypeFilter {
|
||||
// Defines the type to query for.
|
||||
ExecutionType type = 1;
|
||||
}
|
||||
|
||||
message TargetFilter {
|
||||
// Defines the id to query for.
|
||||
string id = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "the id of the targets to include"
|
||||
example: "\"69629023906488334\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message IncludeFilter {
|
||||
// Defines the include to query for.
|
||||
string include = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "the id of the include"
|
||||
example: "\"request.zitadel.session.v2.SessionService\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message TargetSearchFilter {
|
||||
oneof query {
|
||||
option (validate.required) = true;
|
||||
|
||||
TargetNameFilter name = 1;
|
||||
InTargetIDsFilter in_ids = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message TargetNameFilter {
|
||||
// Defines the name of the target to query for.
|
||||
string name = 1 [
|
||||
(validate.rules).string = {max_len: 200},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
max_length: 200;
|
||||
example: "\"ip_allow_list\"";
|
||||
}
|
||||
];
|
||||
// Defines which text comparison method used for the name query.
|
||||
zitadel.resources.object.v3alpha.TextFilterMethod method = 2 [
|
||||
(validate.rules).enum.defined_only = true,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "defines which text equality method is used";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message InTargetIDsFilter {
|
||||
// Defines the ids to query for.
|
||||
repeated string ids = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "the ids of the targets to include"
|
||||
example: "[\"69629023906488334\",\"69622366012355662\"]";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
enum ExecutionType {
|
||||
EXECUTION_TYPE_UNSPECIFIED = 0;
|
||||
EXECUTION_TYPE_REQUEST = 1;
|
||||
EXECUTION_TYPE_RESPONSE = 2;
|
||||
EXECUTION_TYPE_EVENT = 3;
|
||||
EXECUTION_TYPE_FUNCTION = 4;
|
||||
}
|
||||
|
||||
enum TargetFieldName {
|
||||
TARGET_FIELD_NAME_UNSPECIFIED = 0;
|
||||
TARGET_FIELD_NAME_ID = 1;
|
||||
TARGET_FIELD_NAME_CREATION_DATE = 2;
|
||||
TARGET_FIELD_NAME_CHANGE_DATE = 3;
|
||||
TARGET_FIELD_NAME_NAME = 4;
|
||||
TARGET_FIELD_NAME_TARGET_TYPE = 5;
|
||||
TARGET_FIELD_NAME_URL = 6;
|
||||
TARGET_FIELD_NAME_TIMEOUT = 7;
|
||||
TARGET_FIELD_NAME_ASYNC = 8;
|
||||
TARGET_FIELD_NAME_INTERRUPT_ON_ERROR = 9;
|
||||
}
|
@ -1,554 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.resources.action.v3alpha;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/struct.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
import "zitadel/protoc_gen_zitadel/v2/options.proto";
|
||||
|
||||
import "zitadel/resources/action/v3alpha/target.proto";
|
||||
import "zitadel/resources/action/v3alpha/execution.proto";
|
||||
import "zitadel/resources/action/v3alpha/search.proto";
|
||||
import "zitadel/resources/object/v3alpha/object.proto";
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/resources/action/v3alpha;action";
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "Action Service";
|
||||
version: "3.0-alpha";
|
||||
description: "This API is intended to manage custom executions (previously known as actions) in a ZITADEL instance. It is behind the feature flag \"multitenancy_resources_api\". It will continue breaking as long as it is in alpha state.";
|
||||
contact:{
|
||||
name: "ZITADEL"
|
||||
url: "https://zitadel.com"
|
||||
email: "hi@zitadel.com"
|
||||
}
|
||||
license: {
|
||||
name: "Apache 2.0",
|
||||
url: "https://github.com/zitadel/zitadel/blob/main/LICENSE";
|
||||
};
|
||||
};
|
||||
schemes: HTTPS;
|
||||
schemes: HTTP;
|
||||
|
||||
consumes: "application/json";
|
||||
consumes: "application/grpc";
|
||||
|
||||
produces: "application/json";
|
||||
produces: "application/grpc";
|
||||
|
||||
consumes: "application/grpc-web+proto";
|
||||
produces: "application/grpc-web+proto";
|
||||
|
||||
host: "$ZITADEL_DOMAIN";
|
||||
base_path: "/resources/v3alpha";
|
||||
|
||||
external_docs: {
|
||||
description: "Detailed information about ZITADEL",
|
||||
url: "https://zitadel.com/docs"
|
||||
}
|
||||
security_definitions: {
|
||||
security: {
|
||||
key: "OAuth2";
|
||||
value: {
|
||||
type: TYPE_OAUTH2;
|
||||
flow: FLOW_ACCESS_CODE;
|
||||
authorization_url: "$CUSTOM-DOMAIN/oauth/v2/authorize";
|
||||
token_url: "$CUSTOM-DOMAIN/oauth/v2/token";
|
||||
scopes: {
|
||||
scope: {
|
||||
key: "openid";
|
||||
value: "openid";
|
||||
}
|
||||
scope: {
|
||||
key: "urn:zitadel:iam:org:project:id:zitadel:aud";
|
||||
value: "urn:zitadel:iam:org:project:id:zitadel:aud";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
security: {
|
||||
security_requirement: {
|
||||
key: "OAuth2";
|
||||
value: {
|
||||
scope: "openid";
|
||||
scope: "urn:zitadel:iam:org:project:id:zitadel:aud";
|
||||
}
|
||||
}
|
||||
}
|
||||
responses: {
|
||||
key: "403";
|
||||
value: {
|
||||
description: "Returned when the user does not have permission to access the resource.";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
responses: {
|
||||
key: "404";
|
||||
value: {
|
||||
description: "Returned when the resource does not exist.";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
service ZITADELActions {
|
||||
|
||||
// Create a target
|
||||
//
|
||||
// Create a new target, which can be used in executions.
|
||||
rpc CreateTarget (CreateTargetRequest) returns (CreateTargetResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/targets"
|
||||
body: "target"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "action.target.write"
|
||||
}
|
||||
http_response: {
|
||||
success_code: 201
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "201";
|
||||
value: {
|
||||
description: "Target successfully created";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/v2CreateTargetResponse";
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Patch a target
|
||||
//
|
||||
// Patch an existing target.
|
||||
rpc PatchTarget (PatchTargetRequest) returns (PatchTargetResponse) {
|
||||
option (google.api.http) = {
|
||||
patch: "/targets/{id}"
|
||||
body: "target"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "action.target.write"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "Target successfully updated";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Delete a target
|
||||
//
|
||||
// Delete an existing target. This will remove it from any configured execution as well.
|
||||
rpc DeleteTarget (DeleteTargetRequest) returns (DeleteTargetResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/targets/{id}"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "action.target.delete"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "Target successfully deleted";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Target by ID
|
||||
//
|
||||
// Returns the target identified by the requested ID.
|
||||
rpc GetTarget (GetTargetRequest) returns (GetTargetResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/targets/{id}"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "action.target.read"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200"
|
||||
value: {
|
||||
description: "Target successfully retrieved";
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Search targets
|
||||
//
|
||||
// Search all matching targets. By default, we will return all targets of your instance.
|
||||
// Make sure to include a limit and sorting for pagination.
|
||||
rpc SearchTargets (SearchTargetsRequest) returns (SearchTargetsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/targets/_search",
|
||||
body: "filters"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "action.target.read"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "A list of all targets matching the query";
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
key: "400";
|
||||
value: {
|
||||
description: "invalid list query";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Put an execution to call a target or include the targets of another execution.
|
||||
//
|
||||
// Creates an execution for the given condition if it doesn't exists.
|
||||
// Otherwise, the existing execution is updated.
|
||||
rpc PutExecution (PutExecutionRequest) returns (PutExecutionResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/executions"
|
||||
body: "execution"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "action.execution.write"
|
||||
}
|
||||
http_response: {
|
||||
success_code: 201
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "201";
|
||||
value: {
|
||||
description: "Execution successfully created";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/v2CreateExecutionResponse";
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "Execution successfully updated";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Delete an execution
|
||||
//
|
||||
// Delete an existing execution.
|
||||
rpc DeleteExecution (DeleteExecutionRequest) returns (DeleteExecutionResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/executions/{id}"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "action.execution.delete"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "Execution successfully deleted";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Search executions
|
||||
//
|
||||
// Search all matching executions. By default, we will return all executions of your instance.
|
||||
// Depending on the ZITADEL configuration, the number of returned resources is most probably limited.
|
||||
// To make sure you get deterministic results, sort and paginate by the resources creation dates.
|
||||
rpc SearchExecutions (SearchExecutionsRequest) returns (SearchExecutionsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/executions/_search"
|
||||
body: "filters"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "execution.read"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "A list of all executions matching the query";
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
key: "400";
|
||||
value: {
|
||||
description: "invalid list query";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// List all available functions
|
||||
//
|
||||
// List all available functions which can be used as condition for executions.
|
||||
rpc ListAvailableExecutionFunctions (ListAvailableExecutionFunctionsRequest) returns (ListAvailableExecutionFunctionsResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/executions/functions"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "execution.read"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "List all functions successfully";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
// List all available methods
|
||||
//
|
||||
// List all available methods which can be used as condition for executions.
|
||||
rpc ListAvailableExecutionMethods (ListAvailableExecutionMethodsRequest) returns (ListAvailableExecutionMethodsResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/executions/methods"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "execution.read"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "List all methods successfully";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
// List all available service
|
||||
//
|
||||
// List all available services which can be used as condition for executions.
|
||||
rpc ListAvailableExecutionServices (ListAvailableExecutionServicesRequest) returns (ListAvailableExecutionServicesResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/executions/services"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "execution.read"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "List all services successfully";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message CreateTargetRequest {
|
||||
Target target = 2;
|
||||
}
|
||||
|
||||
message CreateTargetResponse {
|
||||
zitadel.resources.object.v3alpha.Details details = 2;
|
||||
}
|
||||
|
||||
message PatchTargetRequest {
|
||||
string id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 200,
|
||||
example: "\"69629026806489455\"";
|
||||
}
|
||||
];
|
||||
PatchTarget target = 2;
|
||||
}
|
||||
|
||||
message PatchTargetResponse {
|
||||
zitadel.resources.object.v3alpha.Details details = 1;
|
||||
}
|
||||
|
||||
message DeleteTargetRequest {
|
||||
string id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 200,
|
||||
example: "\"69629026806489455\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message DeleteTargetResponse {
|
||||
zitadel.resources.object.v3alpha.Details details = 1;
|
||||
}
|
||||
|
||||
message SearchTargetsRequest {
|
||||
// list limitations and ordering.
|
||||
zitadel.resources.object.v3alpha.SearchQuery query = 2;
|
||||
// the field the result is sorted.
|
||||
zitadel.resources.action.v3alpha.TargetFieldName sorting_column = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"FIELD_NAME_SCHEMA_TYPE\""
|
||||
}
|
||||
];
|
||||
// Define the criteria to query for.
|
||||
repeated zitadel.resources.action.v3alpha.TargetSearchFilter filters = 4;
|
||||
}
|
||||
|
||||
message SearchTargetsResponse {
|
||||
zitadel.resources.object.v3alpha.ListDetails details = 1;
|
||||
zitadel.resources.action.v3alpha.TargetFieldName sorting_column = 2;
|
||||
repeated zitadel.resources.action.v3alpha.GetTarget result = 3;
|
||||
}
|
||||
|
||||
message GetTargetRequest {
|
||||
// unique identifier of the target.
|
||||
string id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 200,
|
||||
example: "\"69629026806489455\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message GetTargetResponse {
|
||||
zitadel.resources.action.v3alpha.GetTarget target = 1;
|
||||
}
|
||||
|
||||
message PutExecutionRequest {
|
||||
Execution execution = 2;
|
||||
}
|
||||
|
||||
message PutExecutionResponse {
|
||||
zitadel.resources.object.v3alpha.Details details = 2;
|
||||
}
|
||||
|
||||
message DeleteExecutionRequest {
|
||||
string id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 200,
|
||||
example: "\"69629026806489455\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message DeleteExecutionResponse {
|
||||
zitadel.resources.object.v3alpha.Details details = 1;
|
||||
}
|
||||
|
||||
message SearchExecutionsRequest {
|
||||
// list limitations and ordering.
|
||||
zitadel.resources.object.v3alpha.SearchQuery query = 1;
|
||||
// Define the criteria to query for.
|
||||
repeated zitadel.resources.action.v3alpha.ExecutionSearchFilter filters = 2;
|
||||
}
|
||||
|
||||
message SearchExecutionsResponse {
|
||||
zitadel.resources.object.v3alpha.ListDetails details = 1;
|
||||
repeated zitadel.resources.action.v3alpha.GetExecution result = 2;
|
||||
}
|
||||
|
||||
message ListAvailableExecutionFunctionsRequest{}
|
||||
message ListAvailableExecutionFunctionsResponse{
|
||||
// All available functions
|
||||
repeated string functions = 1;
|
||||
}
|
||||
message ListAvailableExecutionMethodsRequest{}
|
||||
message ListAvailableExecutionMethodsResponse{
|
||||
// All available methods
|
||||
repeated string methods = 1;
|
||||
}
|
||||
|
||||
message ListAvailableExecutionServicesRequest{}
|
||||
message ListAvailableExecutionServicesResponse{
|
||||
// All available services
|
||||
repeated string services = 1;
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.resources.action.v3alpha;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/struct.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
import "zitadel/protoc_gen_zitadel/v2/options.proto";
|
||||
|
||||
import "zitadel/resources/object/v3alpha/object.proto";
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/resources/action/v3alpha;action";
|
||||
|
||||
message Target {
|
||||
string name = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"ip_allow_list\"";
|
||||
}
|
||||
];
|
||||
// Defines the target type and how the response of the target is treated.
|
||||
oneof target_type {
|
||||
SetRESTWebhook rest_webhook = 4;
|
||||
SetRESTRequestResponse rest_request_response = 5;
|
||||
}
|
||||
// Timeout defines the duration until ZITADEL cancels the execution.
|
||||
google.protobuf.Duration timeout = 6 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"10s\"";
|
||||
}
|
||||
];
|
||||
oneof execution_type {
|
||||
// Set the execution to run asynchronously.
|
||||
bool is_async = 7;
|
||||
// Define if any error stops the whole execution. By default the process continues as normal.
|
||||
bool interrupt_on_error = 8;
|
||||
}
|
||||
}
|
||||
|
||||
message GetTarget {
|
||||
zitadel.resources.object.v3alpha.Details details = 1;
|
||||
Target target = 2;
|
||||
}
|
||||
|
||||
message PatchTarget {
|
||||
optional string name = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"ip_allow_list\"";
|
||||
}
|
||||
];
|
||||
// Defines the target type and how the response of the target is treated.
|
||||
oneof target_type {
|
||||
SetRESTWebhook rest_webhook = 3;
|
||||
SetRESTRequestResponse rest_request_response = 4;
|
||||
}
|
||||
// Timeout defines the duration until ZITADEL cancels the execution.
|
||||
optional google.protobuf.Duration timeout = 5 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"10s\"";
|
||||
}
|
||||
];
|
||||
oneof execution_type {
|
||||
// Set the execution to run asynchronously.
|
||||
bool is_async = 6;
|
||||
// Define if any error stops the whole execution. By default the process continues as normal.
|
||||
bool interrupt_on_error = 7;
|
||||
}
|
||||
}
|
||||
|
||||
message SetRESTWebhook {
|
||||
string url = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 1000, uri: true},
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 1000,
|
||||
example: "\"https://example.com/hooks/ip_check\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetRESTRequestResponse {
|
||||
string url = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 1000, uri: true},
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 1000,
|
||||
example: "\"https://example.com/hooks/ip_check\"";
|
||||
}
|
||||
];
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.resources.idp.v3alpha;
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/resources/idp/v3alpha;idp";
|
||||
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
import "zitadel/resources/object/v3alpha/object.proto";
|
||||
|
||||
message IDP {
|
||||
string name = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"GitLab\"";
|
||||
}
|
||||
];
|
||||
zitadel.resources.object.v3alpha.StatePolicy state_policy = 2;
|
||||
Options options = 3;
|
||||
}
|
||||
|
||||
message PatchIDP {
|
||||
optional string name = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"GitLab\"";
|
||||
}
|
||||
];
|
||||
optional zitadel.resources.object.v3alpha.StatePolicy state_policy = 2;
|
||||
optional Options options = 3;
|
||||
}
|
||||
|
||||
|
||||
message GetIDP {
|
||||
zitadel.resources.object.v3alpha.Details details = 1;
|
||||
optional zitadel.resources.object.v3alpha.Parent parent = 2;
|
||||
zitadel.resources.object.v3alpha.State state = 3;
|
||||
ProviderType type = 4;
|
||||
IDP idp = 5;
|
||||
}
|
||||
|
||||
enum ProviderType {
|
||||
PROVIDER_TYPE_UNSPECIFIED = 0;
|
||||
PROVIDER_TYPE_OIDC = 1;
|
||||
PROVIDER_TYPE_JWT = 2;
|
||||
PROVIDER_TYPE_LDAP = 3;
|
||||
PROVIDER_TYPE_OAUTH = 4;
|
||||
PROVIDER_TYPE_AZURE_AD = 5;
|
||||
PROVIDER_TYPE_GITHUB = 6;
|
||||
PROVIDER_TYPE_GITHUB_ES = 7;
|
||||
PROVIDER_TYPE_GITLAB = 8;
|
||||
PROVIDER_TYPE_GITLAB_SELF_HOSTED = 9;
|
||||
PROVIDER_TYPE_GOOGLE = 10;
|
||||
PROVIDER_TYPE_APPLE = 11;
|
||||
PROVIDER_TYPE_SAML = 12;
|
||||
}
|
||||
|
||||
|
||||
enum AutoLinkingOption {
|
||||
// AUTO_LINKING_OPTION_UNSPECIFIED disables the auto linking prompt.
|
||||
AUTO_LINKING_OPTION_UNSPECIFIED = 0;
|
||||
// AUTO_LINKING_OPTION_USERNAME will use the username of the external user to check for a corresponding ZITADEL user.
|
||||
AUTO_LINKING_OPTION_USERNAME = 1;
|
||||
// AUTO_LINKING_OPTION_EMAIL will use the email of the external user to check for a corresponding ZITADEL user with the same verified email
|
||||
// Note that in case multiple users match, no prompt will be shown.
|
||||
AUTO_LINKING_OPTION_EMAIL = 2;
|
||||
}
|
||||
|
||||
message Options {
|
||||
bool is_manual_linking_allowed = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "Enable if users should be able to link an existing ZITADEL user with an external account. Disable if users should only be allowed to link the proposed account in case of active auto_linking.";
|
||||
}
|
||||
];
|
||||
bool is_manual_creation_allowed = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "Enable if users should be able to create a new account in ZITADEL when using an external account. Disable if users should not be able to edit account information when auto_creation is enabled.";
|
||||
}
|
||||
];
|
||||
bool is_auto_creation = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "Enable if a new account in ZITADEL should be created automatically when login with an external account.";
|
||||
}
|
||||
];
|
||||
bool is_auto_update = 4 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "Enable if a the ZITADEL account fields should be updated automatically on each login.";
|
||||
}
|
||||
];
|
||||
AutoLinkingOption auto_linking = 5 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "Enable if users should get prompted to link an existing ZITADEL user to an external account if the selected attribute matches.";
|
||||
}
|
||||
];
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.resources.idp.v3alpha;
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/resources/idp/v3alpha;idp";
|
||||
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
import "zitadel/resources/object/v3alpha/object.proto";
|
||||
import "zitadel/resources/idp/v3alpha/idp.proto";
|
||||
|
||||
message GetGitLabIDP {
|
||||
zitadel.resources.object.v3alpha.Details details = 1;
|
||||
optional zitadel.resources.object.v3alpha.Parent parent = 2;
|
||||
zitadel.resources.object.v3alpha.State state = 3;
|
||||
ProviderType type = 4;
|
||||
GitLabIDP idp = 5;
|
||||
}
|
||||
|
||||
message GitLabIDP {
|
||||
IDP idp = 1;
|
||||
GitLabConfig config = 2;
|
||||
}
|
||||
|
||||
message PatchGitLabIDP {
|
||||
optional PatchIDP idp = 1;
|
||||
optional PatchGitLabConfig config = 2;
|
||||
}
|
||||
|
||||
message GitLabConfig {
|
||||
string client_id = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"client-id\"";
|
||||
description: "client id of the GitLab application";
|
||||
}
|
||||
];
|
||||
repeated string scopes = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "[\"openid\", \"profile\", \"email\"]";
|
||||
description: "the scopes requested by ZITADEL during the request to GitLab";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message PatchGitLabConfig {
|
||||
optional string client_id = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"client-id\"";
|
||||
description: "client id of the GitLab application";
|
||||
}
|
||||
];
|
||||
repeated string scopes = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "[\"openid\", \"profile\", \"email\"]";
|
||||
description: "the scopes requested by ZITADEL during the request to GitLab";
|
||||
}
|
||||
];
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.resources.idp.v3alpha;
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/resources/idp/v3alpha;idp";
|
||||
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
import "zitadel/resources/object/v3alpha/object.proto";
|
||||
|
||||
enum IDPFieldName {
|
||||
IDP_FIELD_NAME_UNSPECIFIED = 0;
|
||||
IDP_FIELD_NAME_NAME = 1;
|
||||
}
|
||||
|
||||
message IDPSearchFilter {
|
||||
oneof filter {
|
||||
IDPIDFilter id = 1;
|
||||
IDPNameFilter name = 2;
|
||||
resources.object.v3alpha.StateFilter state = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message IDPIDFilter {
|
||||
string id = 1 [
|
||||
(validate.rules).string = {max_len: 200},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"69629023906488334\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message IDPNameFilter {
|
||||
string name = 1 [
|
||||
(validate.rules).string = {max_len: 200},
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"google\"";
|
||||
}
|
||||
];
|
||||
zitadel.resources.object.v3alpha.TextFilterMethod method = 2 [
|
||||
(validate.rules).enum.defined_only = true,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "defines which text equality method is used";
|
||||
}
|
||||
];
|
||||
}
|
@ -1,325 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.resources.idp.v3alpha;
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
import "google/protobuf/struct.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
import "zitadel/protoc_gen_zitadel/v2/options.proto";
|
||||
|
||||
import "zitadel/resources/object/v3alpha/object.proto";
|
||||
import "zitadel/resources/idp/v3alpha/search.proto";
|
||||
import "zitadel/resources/idp/v3alpha/idp.proto";
|
||||
import "zitadel/resources/idp/v3alpha/gitlab.proto";
|
||||
import "zitadel/object/v3alpha/object.proto";
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/resources/idp/v3alpha;idp";
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "Identity Provider Service";
|
||||
version: "3.0-alpha";
|
||||
description: "This API is intended to manage identity providers (IDPs). IDPs can be created for specific organizations or for an instance. IDPs created on an instance can be activated (reused) or deactivated in organizations. It is behind the feature flag \"multitenancy_resources_api\". It will continue breaking as long as it is in alpha state.";
|
||||
contact:{
|
||||
name: "ZITADEL"
|
||||
url: "https://zitadel.com"
|
||||
email: "hi@zitadel.com"
|
||||
}
|
||||
license: {
|
||||
name: "Apache 2.0",
|
||||
url: "https://github.com/zitadel/zitadel/blob/main/LICENSE";
|
||||
};
|
||||
};
|
||||
schemes: HTTPS;
|
||||
schemes: HTTP;
|
||||
|
||||
consumes: "application/json";
|
||||
consumes: "application/grpc";
|
||||
|
||||
produces: "application/json";
|
||||
produces: "application/grpc";
|
||||
|
||||
consumes: "application/grpc-web+proto";
|
||||
produces: "application/grpc-web+proto";
|
||||
|
||||
host: "$ZITADEL_DOMAIN";
|
||||
base_path: "/resources/v3alpha";
|
||||
|
||||
external_docs: {
|
||||
description: "Detailed information about ZITADEL",
|
||||
url: "https://zitadel.com/docs"
|
||||
}
|
||||
security_definitions: {
|
||||
security: {
|
||||
key: "OAuth2";
|
||||
value: {
|
||||
type: TYPE_OAUTH2;
|
||||
flow: FLOW_ACCESS_CODE;
|
||||
authorization_url: "$CUSTOM-DOMAIN/oauth/v2/authorize";
|
||||
token_url: "$CUSTOM-DOMAIN/oauth/v2/token";
|
||||
scopes: {
|
||||
scope: {
|
||||
key: "openid";
|
||||
value: "openid";
|
||||
}
|
||||
scope: {
|
||||
key: "urn:zitadel:iam:org:project:id:zitadel:aud";
|
||||
value: "urn:zitadel:iam:org:project:id:zitadel:aud";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
security: {
|
||||
security_requirement: {
|
||||
key: "OAuth2";
|
||||
value: {
|
||||
scope: "openid";
|
||||
scope: "urn:zitadel:iam:org:project:id:zitadel:aud";
|
||||
}
|
||||
}
|
||||
}
|
||||
responses: {
|
||||
key: "403";
|
||||
value: {
|
||||
description: "Returned when the user does not have permission to access the resource.";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
responses: {
|
||||
key: "404";
|
||||
value: {
|
||||
description: "Returned when the resource does not exist.";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
service ZITADELIdentityProviders {
|
||||
|
||||
// Create a GitLab IDP
|
||||
rpc CreateGitLabIDP (CreateGitLabIDPRequest) returns (CreateGitLabIDPResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/idps/gitlab"
|
||||
body: "idp"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "idp.write"
|
||||
}
|
||||
http_response: {
|
||||
success_code: 201
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "201";
|
||||
value: {
|
||||
description: "GitLabIDP successfully created";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/v2CreateGitLabIDPResponse";
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Patch a GitLab IDP
|
||||
rpc PatchGitLabIDP (PatchGitLabIDPRequest) returns (PatchGitLabIDPResponse) {
|
||||
option (google.api.http) = {
|
||||
patch: "/idps/gitlab/{id}"
|
||||
body: "idp"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "idp.write"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "GitLabIDP successfully updated";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Find a GitLab IDP by ID
|
||||
rpc GetGitLabIDP (GetGitLabIDPRequest) returns (GetGitLabIDPResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/idps/gitlab/{id}"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "idp.read"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200"
|
||||
value: {
|
||||
description: "GitLabIDP successfully retrieved";
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Delete an IDP of any type
|
||||
rpc DeleteIDP (DeleteIDPRequest) returns (DeleteIDPResponse) {
|
||||
option (google.api.http) = {
|
||||
delete: "/idps/{id}"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "idp.delete"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "Identity provider successfully deleted";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// Search IDPs
|
||||
//
|
||||
// Search all matching IDPs. By default, all instance-level and organization-level providers of all types are returned.
|
||||
// Only type-agnostic properties are returned in the response.
|
||||
// To get the full details of a specific IDP, use the specific types Get method.
|
||||
// If you search by passing an organization context, the state and the state policy might be different than if you search within the default instance-level context.
|
||||
// Make sure to include a limit and sorting for pagination.
|
||||
rpc SearchIDPs (SearchIDPsRequest) returns (SearchIDPsResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/idps/_search",
|
||||
body: "filters"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "idp.read"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
responses: {
|
||||
key: "200";
|
||||
value: {
|
||||
description: "A list of all IDPs matching the query";
|
||||
};
|
||||
};
|
||||
responses: {
|
||||
key: "400";
|
||||
value: {
|
||||
description: "invalid list query";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
message CreateGitLabIDPRequest {
|
||||
optional zitadel.object.v3alpha.RequestContext ctx = 1;
|
||||
GitLabIDP idp = 2;
|
||||
}
|
||||
|
||||
message CreateGitLabIDPResponse {
|
||||
zitadel.resources.object.v3alpha.Details details = 2;
|
||||
}
|
||||
|
||||
message PatchGitLabIDPRequest {
|
||||
string id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 200,
|
||||
example: "\"69629026806489455\"";
|
||||
}
|
||||
];
|
||||
PatchGitLabIDP idp = 2;
|
||||
}
|
||||
|
||||
message PatchGitLabIDPResponse {
|
||||
zitadel.resources.object.v3alpha.Details details = 1;
|
||||
}
|
||||
|
||||
message DeleteIDPRequest {
|
||||
string id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 200,
|
||||
example: "\"69629026806489455\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message DeleteIDPResponse {
|
||||
zitadel.resources.object.v3alpha.Details details = 1;
|
||||
}
|
||||
|
||||
message SearchIDPsRequest {
|
||||
optional zitadel.object.v3alpha.RequestContext ctx = 1;
|
||||
// list limitations and ordering.
|
||||
zitadel.resources.object.v3alpha.SearchQuery query = 2;
|
||||
// the field the result is sorted.
|
||||
zitadel.resources.idp.v3alpha.IDPFieldName sorting_column = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"FIELD_NAME_SCHEMA_TYPE\""
|
||||
}
|
||||
];
|
||||
repeated zitadel.resources.idp.v3alpha.IDPSearchFilter filters = 4;
|
||||
}
|
||||
|
||||
message SearchIDPsResponse {
|
||||
zitadel.resources.object.v3alpha.ListDetails details = 1;
|
||||
zitadel.resources.idp.v3alpha.IDPFieldName sorting_column = 2;
|
||||
repeated zitadel.resources.idp.v3alpha.GetIDP result = 3;
|
||||
}
|
||||
|
||||
message GetGitLabIDPRequest {
|
||||
string id = 1 [
|
||||
(validate.rules).string = {min_len: 1, max_len: 200},
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
min_length: 1,
|
||||
max_length: 200,
|
||||
example: "\"69629026806489455\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message GetGitLabIDPResponse {
|
||||
zitadel.resources.idp.v3alpha.GetGitLabIDP idp = 1;
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.settings.language.v3alpha;
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/language/v3alpha;language";
|
||||
|
||||
import "validate/validate.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
|
||||
import "zitadel/settings/object/v3alpha/object.proto";
|
||||
import "zitadel/object/v3alpha/object.proto";
|
||||
|
||||
message SetLanguageSettings {
|
||||
optional zitadel.settings.object.v3alpha.Language default_language = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "default language for the current context"
|
||||
example: "\"en\""
|
||||
}
|
||||
];
|
||||
optional SetLanguages restricted_languages = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "To these languages, message texts and default login UI labels are translated to. Also, the discovery endpoint only lists these languages."
|
||||
example: "[\"en\", \"de\"]"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message ResolvedLanguageSettings {
|
||||
zitadel.settings.object.v3alpha.ResolvedString default_language = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "default language for the current context"
|
||||
example: "\"en\""
|
||||
}
|
||||
];
|
||||
ResolvedLanguages restricted_languages = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "To these languages, message texts and default login UI labels are translated to. Also, the discovery endpoint only lists these languages."
|
||||
example: "[\"en\", \"de\"]"
|
||||
}
|
||||
];
|
||||
ResolvedLanguages supported_languages = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "These languages are supported by the system. For simplicity, the field is of type ResolvedLanguages, even though the list is immutable and the owner is always of OWNER_TYPE_SYSTEM."
|
||||
example: "[\"en\", \"de\", \"it\"]"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetLanguages {
|
||||
repeated zitadel.settings.object.v3alpha.Language languages = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "List of languages to set"
|
||||
example: "[\"en\", \"de\"]"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message ResolvedLanguages {
|
||||
repeated zitadel.settings.object.v3alpha.Language value = 1[
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "List of languages"
|
||||
example: "[\"en\", \"de\"]"
|
||||
}
|
||||
];
|
||||
optional zitadel.object.v3alpha.Owner owner = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "If the value is inherited, the value is inherited from this owner.";
|
||||
}
|
||||
];
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.settings.language.v3alpha;
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/language/v3alpha;language";
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
|
||||
import "zitadel/object/v3alpha/object.proto";
|
||||
import "zitadel/settings/object/v3alpha/object.proto";
|
||||
import "zitadel/settings/language/v3alpha/language.proto";
|
||||
import "zitadel/protoc_gen_zitadel/v2/options.proto";
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "Language Settings Service";
|
||||
version: "3.0-alpha";
|
||||
description: "Language Service is intended to manage languages for ZITADEL. Enable the feature flag \"multitenancy_settings\" in order to activate it. Languages are settings, and are therefore inherited through the context hierarchy system -> instance -> org. It will continue breaking as long as it is in alpha state.";
|
||||
contact:{
|
||||
name: "ZITADEL"
|
||||
url: "https://zitadel.com"
|
||||
email: "hi@zitadel.com"
|
||||
}
|
||||
license: {
|
||||
name: "Apache 2.0",
|
||||
url: "https://github.com/zitadel/zitadel/blob/main/LICENSE";
|
||||
};
|
||||
};
|
||||
schemes: HTTPS;
|
||||
schemes: HTTP;
|
||||
|
||||
consumes: "application/json";
|
||||
consumes: "application/grpc";
|
||||
consumes: "application/grpc-web+proto";
|
||||
|
||||
produces: "application/json";
|
||||
produces: "application/grpc";
|
||||
produces: "application/grpc-web+proto";
|
||||
|
||||
host: "$ZITADEL_DOMAIN";
|
||||
base_path: "/settings/v3alpha";
|
||||
|
||||
external_docs: {
|
||||
description: "Detailed information about ZITADEL",
|
||||
url: "https://zitadel.com/docs"
|
||||
}
|
||||
security_definitions: {
|
||||
security: {
|
||||
key: "OAuth2";
|
||||
value: {
|
||||
type: TYPE_OAUTH2;
|
||||
flow: FLOW_ACCESS_CODE;
|
||||
authorization_url: "$ZITADEL_DOMAIN/oauth/v2/authorize";
|
||||
token_url: "$ZITADEL_DOMAIN/oauth/v2/token";
|
||||
scopes: {
|
||||
scope: {
|
||||
key: "openid";
|
||||
value: "openid";
|
||||
}
|
||||
scope: {
|
||||
key: "urn:zitadel:iam:org:project:id:zitadel:aud";
|
||||
value: "urn:zitadel:iam:org:project:id:zitadel:aud";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
security: {
|
||||
security_requirement: {
|
||||
key: "OAuth2";
|
||||
value: {
|
||||
scope: "openid";
|
||||
scope: "urn:zitadel:iam:org:project:id:zitadel:aud";
|
||||
}
|
||||
}
|
||||
}
|
||||
responses: {
|
||||
key: "403";
|
||||
value: {
|
||||
description: "Returned when the user does not have permission to access the settings in the given context.";
|
||||
schema: {
|
||||
json_schema: {
|
||||
ref: "#/definitions/rpcStatus";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// ZITADELLanguageSettings is intended to manage languages for ZITADEL.
|
||||
// Enable the feature flag \"multitenancy_settings\" in order to activate it.
|
||||
// Languages are settings, and are therefore inherited through the context hierarchy system -> instance -> org.
|
||||
service ZITADELLanguageSettings {
|
||||
rpc SetLanguages (SetLanguageSettingsRequest) returns (SetLanguageSettingsResponse) {
|
||||
option (google.api.http) = {
|
||||
patch: "/languages"
|
||||
body: "settings"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "authenticated"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "Set languages for a given context";
|
||||
description: "Configure and set languages for a given context. Only fields present in the request are set or unset."
|
||||
responses: {
|
||||
key: "200"
|
||||
value: {
|
||||
description: "OK";
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
rpc ResolveLanguages (ResolveLanguageSettingsRequest) returns (ResolveLanguageSettingsResponse) {
|
||||
option (google.api.http) = {
|
||||
get: "/languages"
|
||||
};
|
||||
|
||||
option (zitadel.protoc_gen_zitadel.v2.options) = {
|
||||
auth_option: {
|
||||
permission: "authenticated"
|
||||
}
|
||||
};
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
|
||||
summary: "Get the languages in the given context";
|
||||
description: "Returns all configured and inherited languages for the given context."
|
||||
responses: {
|
||||
key: "200"
|
||||
value: {
|
||||
description: "OK";
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
message SetLanguageSettingsRequest{
|
||||
optional zitadel.object.v3alpha.RequestContext ctx = 1;
|
||||
SetLanguageSettings settings = 2;
|
||||
}
|
||||
|
||||
message SetLanguageSettingsResponse{
|
||||
zitadel.settings.object.v3alpha.Details details = 1;
|
||||
}
|
||||
|
||||
message ResolveLanguageSettingsRequest{
|
||||
optional zitadel.object.v3alpha.RequestContext ctx = 1;
|
||||
}
|
||||
|
||||
message ResolveLanguageSettingsResponse{
|
||||
zitadel.settings.object.v3alpha.Details details = 1;
|
||||
ResolvedLanguageSettings settings = 2;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.object.v3alpha;
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/object/v3alpha;object";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
message RequestContext {
|
||||
// By default, the request context is set to the instance discovered by the domain from the requests host header.
|
||||
oneof owner {
|
||||
bool system = 1 [(validate.rules).bool = {const: true}]; // TODO: move the source of truth from the defaults.yaml into the database
|
||||
string instance_id = 2;
|
||||
string instance_domain = 3;
|
||||
string org_id = 4;
|
||||
string org_domain = 5;
|
||||
}
|
||||
}
|
||||
|
||||
enum OwnerType {
|
||||
OWNER_TYPE_UNSPECIFIED = 0;
|
||||
OWNER_TYPE_SYSTEM = 1; // TODO: move the source of truth from the defaults.yaml into the database
|
||||
OWNER_TYPE_INSTANCE = 2;
|
||||
OWNER_TYPE_ORG = 3;
|
||||
}
|
||||
|
||||
message Owner {
|
||||
OwnerType type = 1;
|
||||
string id = 2;
|
||||
}
|
||||
|
@ -1,155 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.resources.object.v3alpha;
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/resources/object/v3alpha;object";
|
||||
|
||||
import "google/api/field_behavior.proto";
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
|
||||
import "zitadel/object/v3alpha/object.proto";
|
||||
|
||||
message Organization {
|
||||
oneof org {
|
||||
string org_id = 1;
|
||||
string org_domain = 2;
|
||||
}
|
||||
}
|
||||
|
||||
message Details {
|
||||
string id = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"69629012906488334\"";
|
||||
}
|
||||
];
|
||||
|
||||
//sequence represents the order of events. It's always counting
|
||||
//
|
||||
// on read: the sequence of the last event reduced by the projection
|
||||
//
|
||||
// on manipulation: the timestamp of the event(s) added by the manipulation
|
||||
uint64 sequence = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"2\"";
|
||||
}
|
||||
];
|
||||
//change_date is the timestamp when the object was changed
|
||||
//
|
||||
// on read: the timestamp of the last event reduced by the projection
|
||||
//
|
||||
// on manipulation: the timestamp of the event(s) added by the manipulation
|
||||
google.protobuf.Timestamp change_date = 3;
|
||||
//resource_owner represents the context an object belongs to
|
||||
zitadel.object.v3alpha.Owner resource_owner = 4 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"69629023906488334\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
enum State {
|
||||
EFFECTIVE_STATE_UNSPECIFIED = 0;
|
||||
EFFECTIVE_STATE_ACTIVE = 1;
|
||||
EFFECTIVE_STATE_INACTIVE = 2;
|
||||
}
|
||||
|
||||
enum StatePolicy {
|
||||
STATE_POLICY_UNSPECIFIED = 0;
|
||||
STATE_POLICY_ACTIVATE = 1;
|
||||
STATE_POLICY_DEACTIVATE = 2;
|
||||
STATE_POLICY_INHERIT = 3;
|
||||
}
|
||||
|
||||
message StateFilter {
|
||||
// Defines the state to query for.
|
||||
resources.object.v3alpha.State state = 1 [
|
||||
(validate.rules).enum.defined_only = true,
|
||||
(google.api.field_behavior) = REQUIRED,
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"STATE_ACTIVE\""
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message Parent {
|
||||
zitadel.object.v3alpha.Owner parent = 1;
|
||||
State state = 2;
|
||||
}
|
||||
|
||||
message ListQuery {
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
|
||||
json_schema: {
|
||||
title: "General List Query"
|
||||
description: "Object unspecific list filters like offset, limit and asc/desc."
|
||||
}
|
||||
};
|
||||
uint64 offset = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"0\"";
|
||||
}
|
||||
];
|
||||
uint32 limit = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "100";
|
||||
description: "Maximum amount of events returned. The default is 100, the maximum is 1000. If the limit exceeds the maximum, ZITADEL throws an error.";
|
||||
}
|
||||
];
|
||||
bool asc = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "default is descending"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message ListDetails {
|
||||
uint32 applied_limit = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "100";
|
||||
}
|
||||
];
|
||||
bool end_of_list = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "true";
|
||||
}
|
||||
];
|
||||
uint64 total_result = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"2\"";
|
||||
}
|
||||
];
|
||||
uint64 processed_sequence = 4 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"267831\"";
|
||||
}
|
||||
];
|
||||
google.protobuf.Timestamp timestamp = 5 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "the last time the projection got updated"
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
enum TextFilterMethod {
|
||||
TEXT_FILTER_METHOD_EQUALS = 0;
|
||||
TEXT_FILTER_METHOD_EQUALS_IGNORE_CASE = 1;
|
||||
TEXT_FILTER_METHOD_STARTS_WITH = 2;
|
||||
TEXT_FILTER_METHOD_STARTS_WITH_IGNORE_CASE = 3;
|
||||
TEXT_FILTER_METHOD_CONTAINS = 4;
|
||||
TEXT_FILTER_METHOD_CONTAINS_IGNORE_CASE = 5;
|
||||
TEXT_FILTER_METHOD_ENDS_WITH = 6;
|
||||
TEXT_FILTER_METHOD_ENDS_WITH_IGNORE_CASE = 7;
|
||||
}
|
||||
|
||||
enum ListFilterMethod {
|
||||
LIST_FILTER_METHOD_IN = 0;
|
||||
}
|
||||
|
||||
enum TimestampFilterMethod {
|
||||
TIMESTAMP_Filter_METHOD_EQUALS = 0;
|
||||
TIMESTAMP_Filter_METHOD_GREATER = 1;
|
||||
TIMESTAMP_Filter_METHOD_GREATER_OR_EQUALS = 2;
|
||||
TIMESTAMP_Filter_METHOD_LESS = 3;
|
||||
TIMESTAMP_Filter_METHOD_LESS_OR_EQUALS = 4;
|
||||
}
|
@ -1,193 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package zitadel.settings.object.v3alpha;
|
||||
|
||||
option go_package = "github.com/zitadel/zitadel/pkg/grpc/settings/object/v3alpha;object";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
import "validate/validate.proto";
|
||||
import "google/protobuf/duration.proto";
|
||||
|
||||
import "zitadel/object/v3alpha/object.proto";
|
||||
|
||||
message Details {
|
||||
//sequence represents the order of events. It's always counting
|
||||
//
|
||||
// on read: the sequence of the last event reduced by the projection
|
||||
//
|
||||
// on manipulation: the timestamp of the event(s) added by the manipulation
|
||||
uint64 sequence = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"2\"";
|
||||
}
|
||||
];
|
||||
//change_date is the timestamp when the object was changed
|
||||
//
|
||||
// on read: the timestamp of the last event reduced by the projection
|
||||
//
|
||||
// on manipulation: the timestamp of the event(s) added by the manipulation
|
||||
google.protobuf.Timestamp change_date = 2;
|
||||
//resource_owner represents the context an object belongs to
|
||||
zitadel.object.v3alpha.Owner owner = 3 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"69629023906488334\"";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
message ResolvedBool {
|
||||
bool value = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "false";
|
||||
description: "The resolved value is valid for the given context. Either the value was explicitly set for the given context or it is inherited from a higher-level context.";
|
||||
}
|
||||
];
|
||||
optional zitadel.object.v3alpha.Owner owner = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "If the value is inherited, the value is inherited from this owner.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetBool {
|
||||
oneof value {
|
||||
bool set = 1;
|
||||
bool reset = 2 [(validate.rules).bool = {
|
||||
const: true
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
message ResolvedString {
|
||||
string value = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"a resolved string\"";
|
||||
description: "The resolved value is valid for the given context. Either the value was explicitly set for the given context or it is inherited from a higher-level context.";
|
||||
}
|
||||
];
|
||||
optional zitadel.object.v3alpha.Owner owner = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "If the value is inherited, the value is inherited from this owner.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetString {
|
||||
oneof value {
|
||||
string set = 1 [
|
||||
(validate.rules).string = {
|
||||
max_len: 256
|
||||
}
|
||||
];
|
||||
bool reset = 2 [(validate.rules).bool = {
|
||||
const: true
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
message SetStringLong {
|
||||
oneof value {
|
||||
string set = 1 [
|
||||
(validate.rules).string = {
|
||||
max_len: 2048
|
||||
}
|
||||
];
|
||||
bool reset = 2 [(validate.rules).bool = {
|
||||
const: true
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
message SetStringShort {
|
||||
oneof value {
|
||||
string set = 1 [
|
||||
(validate.rules).string = {
|
||||
max_len: 64
|
||||
}
|
||||
];
|
||||
bool reset = 2 [(validate.rules).bool = {
|
||||
const: true
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
message Language {
|
||||
string key = 1 [(validate.rules).string = {pattern: "^[a-z]{2}$"}];
|
||||
}
|
||||
|
||||
message ResolvedStrings {
|
||||
repeated string value = 1[
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "[\"a\", \"resolved\", \"list\", \"of\", \"strings\"]";
|
||||
description: "The resolved value is valid for the given context. Either the value was explicitly set for the given context or it is inherited from a higher-level context.";
|
||||
}
|
||||
];
|
||||
optional zitadel.object.v3alpha.Owner owner = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "If the value is inherited, the value is inherited from this owner.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetStrings {
|
||||
oneof value {
|
||||
SetStringsValue set = 1;
|
||||
bool reset = 2 [(validate.rules).bool = {
|
||||
const: true
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
message SetStringsValue {
|
||||
repeated string value = 1;
|
||||
}
|
||||
|
||||
message ResolvedUInt64 {
|
||||
uint64 value = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "1000";
|
||||
description: "The resolved value is valid for the given context. Either the value was explicitly set for the given context or it is inherited from a higher-level context.";
|
||||
}
|
||||
];
|
||||
optional zitadel.object.v3alpha.Owner owner = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "If the value is inherited, the value is inherited from this owner.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetUInt64 {
|
||||
oneof value {
|
||||
uint64 set = 1;
|
||||
bool reset = 2 [(validate.rules).bool = {
|
||||
const: true
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
message ResolvedDuration {
|
||||
google.protobuf.Duration value = 1 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
example: "\"5s\"";
|
||||
description: "The resolved value is valid for the given context. Either the value was explicitly set for the given context or it is inherited from a higher-level context.";
|
||||
}
|
||||
];
|
||||
optional zitadel.object.v3alpha.Owner owner = 2 [
|
||||
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
|
||||
description: "If the value is inherited, the value is inherited from this owner.";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
message SetDuration {
|
||||
oneof value {
|
||||
google.protobuf.Duration set = 1;
|
||||
bool reset = 2 [(validate.rules).bool = {
|
||||
const: true
|
||||
}];
|
||||
}
|
||||
}
|
@ -1,356 +0,0 @@
|
||||
---
|
||||
title: APIs V3 (Preview)
|
||||
---
|
||||
|
||||
import DocCardList from "@theme/DocCardList";
|
||||
import CodeBlock from "@theme/CodeBlock";
|
||||
import ActionServiceProto from "!!raw-loader!./_v3_action_service.proto";
|
||||
import ActionExecutionProto from "!!raw-loader!./_v3_action_execution.proto";
|
||||
import ActionTargetProto from "!!raw-loader!./_v3_action_target.proto";
|
||||
import ActionSearchProto from "!!raw-loader!./_v3_action_search.proto";
|
||||
import IDPServiceProto from "!!raw-loader!./_v3_idp_service.proto";
|
||||
import IDPProto from "!!raw-loader!./_v3_idp.proto";
|
||||
import IDPSearchProto from "!!raw-loader!./_v3_idp_search.proto";
|
||||
import IDPGitLabProto from "!!raw-loader!./_v3_idp_gitlab.proto";
|
||||
import LanguageServiceProto from "!!raw-loader!./_v3_language_service.proto";
|
||||
import LanguageProto from "!!raw-loader!./_v3_language.proto";
|
||||
import ObjectProto from "!!raw-loader!./_v3_object.proto";
|
||||
import ResourceObjectProto from "!!raw-loader!./_v3_resource_object.proto";
|
||||
import SettingsObjectProto from "!!raw-loader!./_v3_settings_object.proto";
|
||||
|
||||
The APIs described in this section are currently either in _Preview_ stage or not implemented, yet.
|
||||
Before using these APIs, pleases consider the [API release policy below](#api-release-policy)
|
||||
|
||||
## We Appreciate your Help
|
||||
|
||||
We invite you to...
|
||||
|
||||
- ... [discuss the concept with the ZITADEL community on GitHub](https://github.com/zitadel/zitadel/discussions/8125).
|
||||
- ... try the implementations and provide feedback [by filing issues on GitHub](https://github.com/zitadel/zitadel/issues/new/choose).
|
||||
|
||||
## The Ideas behind the New V3 APIs
|
||||
|
||||
The current ZITADEL _GA_ APIs are structured around contexts like System, Admin, Management, and Auth.
|
||||
This structure leads to duplicate methods and makes it hard to find the right API for the right task.
|
||||
Especially interacting with resources from multiple organizations is cumbersome.
|
||||
Also, the APIs evolved over time, which lead to inconsistencies and a lack of flexibility in development.
|
||||
|
||||
We address these issues with the following new API categories:
|
||||
|
||||
- [Standard Resources](#standard-resources)
|
||||
- [Reusable Resources](#reusable-resources)
|
||||
- [Settings](#settings)
|
||||
|
||||
The designs for the new API categories aim for the following improvements:
|
||||
|
||||
### Service Structure
|
||||
|
||||
Instead of structuring the API methods around contexts, new APIs are structured around resources and settings.
|
||||
This means, eventually, we deprecate the old System-, Admin-, Management- and AuthAPIs in favor of User-, Action-, Language-, FeatureAPIs and so on.
|
||||
This change makes it easier to find the right API for the right task, especially for multi-organization resources.
|
||||
Also, it allows for faster development and independent versioning of the APIs.
|
||||
|
||||
### Multitenancy Management and Consistency
|
||||
|
||||
To improve managing and reusing resources and settings in multitenancy scenarios, we define some rules for the new APIs:
|
||||
|
||||
- Single properties from default settings are overridable (patchable) in organizations.
|
||||
- Some settings support user-defined custom properties that are also overridable in organizations.
|
||||
- Improved experience with reusing resources in multiple organizations and instances.
|
||||
- Resources are searchable over all organizations with a single call by default.
|
||||
|
||||
### HTTP and gRPC Consistency
|
||||
|
||||
To make the APIs more consistent and easier to use, we follow the same patterns in all Proto files.
|
||||
|
||||
- Patching is favored over updating resources and settings.
|
||||
- HTTP calls are mapped so that query parameters can be used as much as possible. We avoid the annotation `body: "*"`.
|
||||
- For search performance, we enforce query limits.
|
||||
|
||||
## Standard Resources
|
||||
|
||||
Standard resources exist in exactly one context.
|
||||
For example, a user is always assigned to exactly one organization.
|
||||
Or one SMS provider is always assigned to exactly one instance.
|
||||
|
||||
Standard resource methods behave like this:
|
||||
|
||||
- Search request results can be scoped to a RequestContext.
|
||||
- Search request results only contain results for which the requesting user has the necessary read permissions.
|
||||
- Search requests are limited to 100 by default. The limit can be increased by the caller up to 1000 by default.
|
||||
- Resource configurations are partially updatable. With HTTP, this is done via PATCH requests. If no changes were made, the response is successful.
|
||||
- Status changes or other actions on resources with side effects are done via POST requests. Their HTTP path ends with the underscore prefixed action name. For example `POST /resources/users/{id}/_unlock`.
|
||||
|
||||
For a full proto example, have a look at the [ZITADELActions service](#zitadelactions).
|
||||
|
||||
## Reusable Resources
|
||||
|
||||
Reusable resources are like standard resources but can be reused in multiple contexts.
|
||||
For example, an external identity provider can be defined once on the instance.
|
||||
Each organization within this instance can then choose to use this identity provider or not.
|
||||
|
||||
Additionally to the methods described for standard resources, reusable have the following capabilities:
|
||||
|
||||
Reusable resources have the same behavior as standard resources with the following additions:
|
||||
|
||||
- Reusable resources can be created in a given context level (system, instance, org).
|
||||
- For requests, that require a resource ID, no request context is needed.
|
||||
- Reusable resources are available in child contexts, even if their state is _inactive_.
|
||||
- The child context can control if an inherited resource should be active or inactive for itself using a state policy.
|
||||
- In child contexts, the state policy of a reused resource is _inherit_ by default and can be changed to _activate_, _deactivate_ or back to _inherit_.
|
||||
- In child contexts, a reused resources configuration is read-only.
|
||||
- Child contexts can read at least the following properties of reused resources:
|
||||
- ID
|
||||
- name
|
||||
- description
|
||||
- state
|
||||
- the state policy in the child context
|
||||
- sequence
|
||||
- last changed date
|
||||
- parent context
|
||||
- state in the immediate parent context.
|
||||
- By default, search queries for reused resources return all resources from the given contexts, all inherited resources and all resources defined in all children contexts.
|
||||
|
||||
Typically, a new resource is first designed and implemented as a non-reusable resource.
|
||||
If the community sees a benefit in reusing the resource in multiple contexts, reusability is added to the resource.
|
||||
|
||||
For a full proto example, have a look at the [ZITADELIdentityProviders service](#zitadelidentityproviders).
|
||||
|
||||
## Resource Services
|
||||
|
||||
All resource services by default support the following CRUD operations [as described above](#standard-resources-behavior).
|
||||
|
||||
- Create
|
||||
- Read (get, search)
|
||||
- Patch (partially update, success on no changes)
|
||||
- Delete
|
||||
|
||||
### ZITADELActions
|
||||
|
||||
- Standard CRUD methods for Targets
|
||||
- Standard CRUD methods for Executions except the PutExecution method replaces the CreateExecution and PatchExecution methods
|
||||
|
||||
Additional to the standard CRUD methods:
|
||||
|
||||
- ListAvailableExecutionServices
|
||||
- ListAvailableExecutionMethods
|
||||
- ListAvailableExecutionFunctions
|
||||
|
||||
<details>
|
||||
<summary>action_service.proto</summary>
|
||||
<CodeBlock language="protobuf">{ActionServiceProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>action_target.proto</summary>
|
||||
<CodeBlock language="protobuf">{ActionTargetProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>action_execution.proto</summary>
|
||||
<CodeBlock language="protobuf">{ActionExecutionProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>action_query.proto</summary>
|
||||
<CodeBlock language="protobuf">{ActionSearchProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
### ZITADELUsers
|
||||
|
||||
Standard CRUD methods
|
||||
|
||||
### ZITADELUserSchemas
|
||||
|
||||
Standard CRUD methods
|
||||
|
||||
### ZITADELIdentityProviders
|
||||
|
||||
- Standard CRUD and methods for all IDPs
|
||||
- Resources have additional properties for reusability capabilities.
|
||||
|
||||
<details>
|
||||
<summary>idp_service.proto</summary>
|
||||
<CodeBlock language="protobuf">{IDPServiceProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>idp.proto</summary>
|
||||
<CodeBlock language="protobuf">{IDPProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>idp_search.proto</summary>
|
||||
<CodeBlock language="protobuf">{IDPSearchProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>idp_gitlab.proto</summary>
|
||||
<CodeBlock language="protobuf">{IDPGitLabProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>object.proto</summary>
|
||||
<CodeBlock language="protobuf">{ObjectProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>resource_object.proto</summary>
|
||||
<CodeBlock language="protobuf">{ResourceObjectProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
### ZITADELInstances
|
||||
|
||||
Additional to the standard CRUD methods:
|
||||
|
||||
- Limit (partial update of block and audit log retention)
|
||||
- BulkLimit (partial update of block and audit log retention for multiple instances)
|
||||
|
||||
### ZITADELOrganizations
|
||||
|
||||
Additional to the standard CRUD methods:
|
||||
|
||||
- SetAsInstanceDefault
|
||||
- GetInstanceDefault
|
||||
|
||||
### ZITADELDomains
|
||||
|
||||
Additional to the standard CRUD methods:
|
||||
|
||||
- SetAsPrimary
|
||||
- Validate
|
||||
|
||||
### ZITADELSessions
|
||||
|
||||
Standard CRUD methods
|
||||
|
||||
### ZITADELProjects
|
||||
|
||||
Standard CRUD methods
|
||||
|
||||
### ZITADELApps
|
||||
|
||||
Standard CRUD methods
|
||||
|
||||
### ZITADELMemberships
|
||||
|
||||
The given context defines the organization, instance or system where the membership is created.
|
||||
The context and the user ID together are unique.
|
||||
|
||||
Additional to the standard CRUD methods:
|
||||
|
||||
- ListAvailableRoles (context-aware)
|
||||
|
||||
### ZITADELGrants
|
||||
|
||||
- Standard CRUD methods for project grants
|
||||
- Standard CRUD methods for user grants
|
||||
- Standard CRUD methods for roles
|
||||
|
||||
### ZITADELSMTPProviders
|
||||
|
||||
Standard CRUD methods
|
||||
|
||||
### ZITADELSMSProviders
|
||||
|
||||
Standard CRUD methods
|
||||
|
||||
## Settings
|
||||
|
||||
Settings have no identity (ID) and are always context-aware.
|
||||
They also don't have a state like active or inactive.
|
||||
They only have properties that can be set and queried.
|
||||
These properties are inherited to from parent-contexts (instance) to child-contexts (organization).
|
||||
|
||||
Settings behave like this:
|
||||
|
||||
- Setting and retrieving settings is always context-aware. By default, the context is the instance discovered by the requests _Host_ header.
|
||||
- All settings properties can be partially overridden in child-contexts.
|
||||
- All settings properties can be partially reset in child-contexts, so their values default to the parent contexts property values.
|
||||
- All settings properties returned by queries contain the value and if it is inherited, the context where it is inherited from.
|
||||
|
||||
For a full proto example, have a look at the [ZITADELLanguageSettings service](#zitadellanguagesettings).
|
||||
|
||||
## Settings Services
|
||||
|
||||
### ZITADELLanguageSettings
|
||||
|
||||
Default language, restricted languages, supported languages
|
||||
|
||||
<details>
|
||||
<summary>language_service.proto</summary>
|
||||
<CodeBlock language="protobuf">{LanguageServiceProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>language.proto</summary>
|
||||
<CodeBlock language="protobuf">{LanguageProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>object.proto</summary>
|
||||
<CodeBlock language="protobuf">{ObjectProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>settings_object.proto</summary>
|
||||
<CodeBlock language="protobuf">{SettingsObjectProto}</CodeBlock>
|
||||
</details>
|
||||
|
||||
### ZITADELTextSettings
|
||||
|
||||
Key-value pairs for localized login texts, previously known as login texts
|
||||
|
||||
### ZITADELBrandingSettings
|
||||
|
||||
Predefined branding settings and custom key-value pairs, previously known as label policy or branding settings
|
||||
|
||||
### ZITADELLoginSettings
|
||||
|
||||
Previously known as login policy
|
||||
|
||||
### ZITADELLockoutSettings
|
||||
|
||||
Previously known as lockout policy
|
||||
|
||||
### ZITADELPasswordSettings
|
||||
|
||||
Previously known as password complexity policy
|
||||
|
||||
### ZITADELHelpSettings
|
||||
|
||||
Previously known as legal and support settings or privacy policy
|
||||
|
||||
### ZITADELDomainSettings
|
||||
|
||||
Previously known as domain policy
|
||||
|
||||
### ZITADELFeatureSettings
|
||||
|
||||
Feature toggles
|
||||
|
||||
Also contains disallow public org registrations on system and instance level.
|
||||
|
||||
### ZITADELTemplatesSettings
|
||||
|
||||
HTML and text templates for fully customizable emails and sms
|
||||
|
||||
### ZITADELSecretSettings
|
||||
|
||||
Replaces secret generators
|
||||
|
||||
## API Release Policy
|
||||
|
||||
- Defined but not yet implemented APIs are subject to change without further notice.
|
||||
- Once an API definition is implemented, it is released as _Preview_ and is available for testing.
|
||||
- When a _Preview_ API is tested enough so the concepts are proven to work, a new _Beta_ API is released.
|
||||
- When an API is feature-complete and stable enough, a new _GA_ (General Availability) API is released.
|
||||
- In all stages, changes to already implemented APIs are done in a backwards-compatible way, if possible.
|
||||
- When we release a new stage for an API, we deprecate the previous stage and keep it available for a smooth transition.
|
||||
|
||||
## Preview APIs
|
||||
|
||||
These APIs are ready for testing and feedback.
|
||||
Beware, they don't yet follow all the rules defined above.
|
||||
|
||||
<DocCardList />
|
@ -737,10 +737,6 @@ module.exports = {
|
||||
type: "category",
|
||||
label: "V3 (Preview)",
|
||||
collapsed: false,
|
||||
link: {
|
||||
type: "doc",
|
||||
id: "apis/v3",
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: "category",
|
||||
|
Loading…
x
Reference in New Issue
Block a user