From 104034c6284a02bb8b874f39af65b95ee7aef7b8 Mon Sep 17 00:00:00 2001 From: Livio Spring Date: Thu, 15 Feb 2024 11:22:48 +0100 Subject: [PATCH] chore(api): initial definition of API for user schemas (user v3 and user schema v3 service) (#7372) Adds the initial proto definition for a new user service (v3) based on user schema and it's corresponding user schema service (v3) --- docs/buf.gen.yaml | 5 +- docs/docusaurus.config.js | 20 +- docs/sidebars.js | 337 ++- .../user/schema/v3alpha/user_schema.proto | 168 ++ .../schema/v3alpha/user_schema_service.proto | 452 ++++ .../zitadel/user/v3alpha/authenticator.proto | 476 ++++ .../zitadel/user/v3alpha/communication.proto | 109 + proto/zitadel/user/v3alpha/query.proto | 207 ++ proto/zitadel/user/v3alpha/user.proto | 66 + proto/zitadel/user/v3alpha/user_service.proto | 2099 +++++++++++++++++ 10 files changed, 3821 insertions(+), 118 deletions(-) create mode 100644 proto/zitadel/user/schema/v3alpha/user_schema.proto create mode 100644 proto/zitadel/user/schema/v3alpha/user_schema_service.proto create mode 100644 proto/zitadel/user/v3alpha/authenticator.proto create mode 100644 proto/zitadel/user/v3alpha/communication.proto create mode 100644 proto/zitadel/user/v3alpha/query.proto create mode 100644 proto/zitadel/user/v3alpha/user.proto create mode 100644 proto/zitadel/user/v3alpha/user_service.proto diff --git a/docs/buf.gen.yaml b/docs/buf.gen.yaml index 46d49e75c7..a628f6e748 100644 --- a/docs/buf.gen.yaml +++ b/docs/buf.gen.yaml @@ -5,4 +5,7 @@ managed: plugins: - plugin: buf.build/grpc-ecosystem/openapiv2 out: .artifacts/openapi - opt: allow_delete_body + opt: + - allow_delete_body + - remove_internal_comments=true + - preserve_rpc_order=true diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index ce54fe9ad2..35b4341338 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -290,14 +290,28 @@ module.exports = { groupPathsBy: "tag", }, }, + user_schema: { + specPath: ".artifacts/openapi/zitadel/user/schema/v3alpha/user_schema_service.swagger.json", + outputDir: "docs/apis/resources/user_schema_service_v3", + sidebarOptions: { + groupPathsBy: "tag", + }, + }, + user_v3: { + specPath: ".artifacts/openapi/zitadel/user/v3alpha/user_service.swagger.json", + outputDir: "docs/apis/resources/user_service_v3", + sidebarOptions: { + groupPathsBy: "tag", + }, + }, execution_v3: { specPath: ".artifacts/openapi/zitadel/execution/v3alpha/execution_service.swagger.json", outputDir: "docs/apis/resources/execution_service_v3", sidebarOptions: { - groupPathsBy: "tag", + groupPathsBy: "tag", }, - } - } + }, + }, }, ], require.resolve("docusaurus-plugin-image-zoom"), diff --git a/docs/sidebars.js b/docs/sidebars.js index 65cf221ede..5e9c5ea27e 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -521,129 +521,238 @@ module.exports = { link: { type: "generated-index", title: "Core Resources", - slug: "/apis/resources/", - description: "Resource based API definitions", + slug: "/apis/apis/", + description: + "ZITADEL provides multiple APIs to manage the system, instances and resources such as users, projects and more.\n" + + "\n" + + "There are multiple different versions and multiple services available:"+ + "\n" + + "The resource based APIs are, as the name suggests, organized by resources such as users, session, settings and more.\n" + + "These services are the future of the ZITADEL APIS and the best way to start integrating ZITADEL.\n" + + "\n"+ + "The service based APIs are organized by UseCase/Context, such as Auth API for authenticated users,"+ + "Management API for organization managers, Admin API for instance managers and a System API for system managers.", }, items: [ { type: "category", - label: "Authenticated User", + label: "Service Based (V1)", + collapsed: false, link: { type: "generated-index", - title: "Auth API", - slug: "/apis/resources/auth", + title: "Service Based APIs (V1)", + slug: "/apis/services/", description: - "The authentication API (aka Auth API) is used for all operations on the currently logged in user. The user id is taken from the sub claim in the token.", - }, - items: require("./docs/apis/resources/auth/sidebar.js"), - }, - { - type: "category", - label: "Organization Objects", - link: { - type: "generated-index", - title: "Management API", - slug: "/apis/resources/mgmt", - description: - "The management API is as the name states the interface where systems can mutate IAM objects like, organizations, projects, clients, users and so on if they have the necessary access rights. To identify the current organization you can send a header x-zitadel-orgid or if no header is set, the organization of the authenticated user is set.", - }, - items: require("./docs/apis/resources/mgmt/sidebar.js"), - }, - { - type: "category", - label: "Instance Objects", - link: { - type: "generated-index", - title: "Admin API", - slug: "/apis/resources/admin", - description: - "This API is intended to configure and manage one ZITADEL instance itself.", - }, - items: require("./docs/apis/resources/admin/sidebar.js"), - }, - { - type: "category", - label: "Instance Lifecycle", - link: { - type: "generated-index", - title: "System API", - slug: "/apis/resources/system", - description: - "This API is intended to manage the different ZITADEL instances within the system.\n" + - "\n" + - "Checkout the guide how to access the ZITADEL System API.", - }, - items: require("./docs/apis/resources/system/sidebar.js"), - }, - { - type: "category", - label: "User Lifecycle (Beta)", - link: { - type: "generated-index", - title: "User Service API (Beta)", - slug: "/apis/resources/user_service", - description: - "This API is intended to manage users in a ZITADEL instance.\n" + - "\n" + - "This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.", - }, - items: require("./docs/apis/resources/user_service/sidebar.js"), - }, - { - type: "category", - label: "Session Lifecycle (Beta)", - link: { - type: "generated-index", - title: "Session Service API (Beta)", - slug: "/apis/resources/session_service", - description: - "This API is intended to manage sessions in a ZITADEL instance.\n" + - "\n" + - "This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.", - }, - items: require("./docs/apis/resources/session_service/sidebar.js"), - }, - { - type: "category", - label: "OIDC Lifecycle (Beta)", - link: { - type: "generated-index", - title: "OIDC Service API (Beta)", - slug: "/apis/resources/oidc_service", - description: - "Get OIDC Auth Request details and create callback URLs.\n" + - "\n" + - "This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.", - }, - items: require("./docs/apis/resources/oidc_service/sidebar.js"), - }, - { - type: "category", - label: "Settings Lifecycle (Beta)", - link: { - type: "generated-index", - title: "Settings Service API (Beta)", - slug: "/apis/resources/settings_service", - description: - "This API is intended to manage settings in a ZITADEL instance.\n" + - "\n" + - "This project is in beta state. It can AND will continue to break until the services provide the same functionality as the current login.", - }, - items: require("./docs/apis/resources/settings_service/sidebar.js"), - }, - { - type: "category", - label: "Execution Lifecycle (Alpha)", - link: { - type: "generated-index", - title: "Execution Service API (Alpha)", - slug: "/apis/resources/execution_service_v3", - description: - "This API is intended to manage custom executions (previously known as actions) in a ZITADEL instance.\n"+ + "The service based APIs are organized by UseCase/Context, such as Auth API for authenticated users,"+ + "Management API for organization managers, Admin API for instance managers and a System API for system managers.\n"+ "\n"+ - "This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current actions.", + "To improve the developer experience in managing the different resources, ZITADEL also offers Resource Based APIs (v2 and v3). "+ + "Those APIs focus on the resources themselves. For example they offer a User Service, which will give you the possibility " + + "to search for users across multiple organizations.\n"+ + "Note that the Resource Based APIs are not yet generally available. Please check the corresponding service" + + "for their state and functionality.", }, - items: require("./docs/apis/resources/execution_service_v3/sidebar.js"), + items: [ + { + type: "category", + label: "Authenticated User", + link: { + type: "generated-index", + title: "Auth API", + slug: "/apis/resources/auth", + description: + "The authentication API (aka Auth API) is used for all operations on the currently logged in user. The user id is taken from the sub claim in the token.", + }, + items: require("./docs/apis/resources/auth/sidebar.js"), + }, + { + type: "category", + label: "Organization Objects", + link: { + type: "generated-index", + title: "Management API", + slug: "/apis/resources/mgmt", + description: + "The management API is as the name states the interface where systems can mutate IAM objects like, organizations, projects, clients, users and so on if they have the necessary access rights. To identify the current organization you can send a header x-zitadel-orgid or if no header is set, the organization of the authenticated user is set.", + }, + items: require("./docs/apis/resources/mgmt/sidebar.js"), + }, + { + type: "category", + label: "Instance Objects", + link: { + type: "generated-index", + title: "Admin API", + slug: "/apis/resources/admin", + description: + "This API is intended to configure and manage one ZITADEL instance itself.", + }, + items: require("./docs/apis/resources/admin/sidebar.js"), + }, + { + type: "category", + label: "Instance Lifecycle", + link: { + type: "generated-index", + title: "System API", + slug: "/apis/resources/system", + description: + "This API is intended to manage the different ZITADEL instances within the system.\n" + + "\n" + + "Checkout the guide how to access the ZITADEL System API.", + }, + items: require("./docs/apis/resources/system/sidebar.js"), + }, + ], + }, + { + type: "category", + label: "Resource Based (V2)", + collapsed: false, + link: { + type: "generated-index", + title: "Resource Based APIs (V2)", + slug: "/apis/resources/", + description: + "The resource based APIs are, as the name suggest, organized by resources such as users, session, settings and more. "+ + "Check the list below to get an overview of all available resources.\n"+ + "\n"+ + "While the service based APIs (V1) work great for use cases in a specific context such as a single organization, " + + "it's sometime difficult to know which API to use, particularly for resources across multiple organizations. "+ + "For instance, SearchUsers on an Instance level or on an Organization level.\n"+ + "This is exactly where the resource based APIs come in place, e.g. with the User Service, " + + "where you're able to search all users and can provide the context (organization) yourself if needed or just search the whole instance.\n"+ + "\n"+ + "Note that these APIs are not yet generally available and therefore breaking changes might still occur.\n"+ + "Please check the corresponding service for more information on the state and availability.", + }, + items: [ + { + type: "category", + label: "User Lifecycle (Beta)", + link: { + type: "generated-index", + title: "User Service API (Beta)", + slug: "/apis/resources/user_service", + description: + "This API is intended to manage users in a ZITADEL instance.\n" + + "\n" + + "This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.", + }, + items: require("./docs/apis/resources/user_service/sidebar.js"), + }, + { + type: "category", + label: "Session Lifecycle (Beta)", + link: { + type: "generated-index", + title: "Session Service API (Beta)", + slug: "/apis/resources/session_service", + description: + "This API is intended to manage sessions in a ZITADEL instance.\n" + + "\n" + + "This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.", + }, + items: require("./docs/apis/resources/session_service/sidebar.js"), + }, + { + type: "category", + label: "OIDC Lifecycle (Beta)", + link: { + type: "generated-index", + title: "OIDC Service API (Beta)", + slug: "/apis/resources/oidc_service", + description: + "Get OIDC Auth Request details and create callback URLs.\n" + + "\n" + + "This project is in beta state. It can AND will continue breaking until the services provide the same functionality as the current login.", + }, + items: require("./docs/apis/resources/oidc_service/sidebar.js"), + }, + { + type: "category", + label: "Settings Lifecycle (Beta)", + link: { + type: "generated-index", + title: "Settings Service API (Beta)", + slug: "/apis/resources/settings_service", + description: + "This API is intended to manage settings in a ZITADEL instance.\n" + + "\n" + + "This project is in beta state. It can AND will continue to break until the services provide the same functionality as the current login.", + }, + items: require("./docs/apis/resources/settings_service/sidebar.js"), + }, + ] + }, + { + type: "category", + label: "Resource Based (V3)", + collapsed: false, + link: { + type: "generated-index", + title: "Resource Based APIs (V3)", + slug: "/apis/resources_v3/", + description: + "The resource based APIs are, as the name suggests, organized by resources such as users, session, settings and more.\n"+ + "\n"+ + "While the service based APIs (V1) work great for use cases in a specific context such as a single organization, " + + "it's sometime difficult to know which API to use, particularly for resources across multiple organizations. "+ + "For instance, SearchUsers on an Instance level or on an Organization level.\n"+ + "This is exactly where the resource based APIs come in place, e.g. with the User Service, " + + "where you're able to search all users and can provide the context (organization) yourself if needed or just search the whole instance.\n"+ + "\n"+ + "Version 3 offers more customization than the V2 resource bases APIs. You can define your own user schema "+ + "to be able to manage users based on these schemas and customize various behaviors, such as manipulating "+ + "inbound API calls, call webhooks on different event and more with the execution service.\n"+ + "\n"+ + "Note that these APIs are not yet generally available and therefore breaking changes might still occur.\n"+ + "Please check the corresponding service for more information on the state and availability.", + }, + items: [ + { + type: "category", + label: "User Schema Lifecycle (Alpha)", + link: { + type: "generated-index", + title: "User Schema Service API (Aplha)", + slug: "/apis/resources/user_schema_service", + description: + "This API is intended to manage data schemas for users in a ZITADEL instance.\n" + + "\n" + + "This project is in alpha state. It can AND will continue breaking until the service provides the same functionality as the v1 and v2 user services.", + }, + items: require("./docs/apis/resources/user_schema_service_v3/sidebar.js"), + }, + { + type: "category", + label: "User Lifecycle (Alpha)", + link: { + type: "generated-index", + title: "User Service API (Aplha)", + slug: "/apis/resources/user_service_v3", + description: + "This API is intended to manage users with your own data schema in a ZITADEL instance.\n"+ + "\n"+ + "This project is in alpha state. It can AND will continue breaking until the service provides the same functionality as the v1 and v2 user services." + }, + items: require("./docs/apis/resources/user_service_v3/sidebar.js"), + }, + { + type: "category", + label: "Execution Lifecycle (Alpha)", + link: { + type: "generated-index", + title: "Execution Service API (Alpha)", + slug: "/apis/resources/execution_service_v3", + description: + "This API is intended to manage custom executions (previously known as actions) in a ZITADEL instance.\n"+ + "\n"+ + "This project is in alpha state. It can AND will continue breaking until the services provide the same functionality as the current actions.", + }, + items: require("./docs/apis/resources/execution_service_v3/sidebar.js"), + }, + ] }, { type: "category", diff --git a/proto/zitadel/user/schema/v3alpha/user_schema.proto b/proto/zitadel/user/schema/v3alpha/user_schema.proto new file mode 100644 index 0000000000..1b5be71a7d --- /dev/null +++ b/proto/zitadel/user/schema/v3alpha/user_schema.proto @@ -0,0 +1,168 @@ +syntax = "proto3"; + +package zitadel.user.schema.v3alpha; + +import "google/api/field_behavior.proto"; +import "google/protobuf/struct.proto"; +import "validate/validate.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "zitadel/object/v2beta/object.proto"; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/schema/v3alpha"; + +message UserSchema { + + // ID is the read-only unique identifier of the schema. + string id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629012906488334\"" + } + ]; + // Details provide some base information (such as the last change date) of the schema. + zitadel.object.v2beta.Details details = 2; + // Type is a human readable text describing the schema. + string type = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"employees\"" + } + ]; + // Current state of the schema. + State state = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"STATE_ACTIVE\"" + } + ]; + // Revision is a read only version of the schema, each update increases the revision. + uint32 revision = 5 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2\"" + } + ]; + // JSON schema representation defining the user. + google.protobuf.Struct schema = 6 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "{\"$schema\":\"https://example.com/user/employees\",\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\",\"required\":true},\"description\":{\"type\":\"string\"}}}" + } + ]; + // Defines the possible types of authenticators. + // This allows creating different user types like human/machine without usage of actions to validate possible authenticators. + // Removal of an authenticator does not remove the authenticator on a user. + repeated AuthenticatorType possible_authenticators = 7 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "[\"AUTHENTICATOR_TYPE_USERNAME\",\"AUTHENTICATOR_TYPE_PASSWORD\",\"AUTHENTICATOR_TYPE_WEBAUTHN\"]"; + } + ]; +} + +enum FieldName { + FIELD_NAME_UNSPECIFIED = 0; + FIELD_NAME_TYPE = 1; + FIELD_NAME_STATE = 2; + FIELD_NAME_REVISION = 3; + FIELD_NAME_CREATION_DATE = 4; +} + +message SearchQuery { + oneof query { + option (validate.required) = true; + + // Union the results of each sub query ('OR'). + OrQuery or_query = 1; + // Limit the result to match all sub queries ('AND'). + // Note that if you specify multiple queries, they will be implicitly used as andQueries. + // Use the andQuery in combination with orQuery and notQuery. + AndQuery and_query = 2; + // Exclude / Negate the result of the sub query ('NOT'). + NotQuery not_query = 3; + + // Limit the result to a specific schema type. + TypeQuery type_query = 5; + // Limit the result to a specific state of the schema. + StateQuery state_query = 6; + } +} + +message OrQuery { + repeated SearchQuery queries = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "[{\"idQuery\": {\"id\": \"163840776835432705\",\"method\": \"TEXT_QUERY_METHOD_EQUALS\"}},{\"idQuery\": {\"id\": \"163840776835943483\",\"method\": \"TEXT_QUERY_METHOD_EQUALS\"}}]" + } + ]; +} +message AndQuery { + repeated SearchQuery queries = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "[{\"typeQuery\": {\"id\": \"employees\",\"method\": \"TEXT_QUERY_METHOD_STARTS_WITH\"}},{\"stateQuery\": {\"state\": \"STATE_ACTIVE\"}}]" + } + ]; +} + +message NotQuery { + SearchQuery query = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "{\"stateQuery\": {\"state\": \"STATE_ACTIVE\"}}" + } + ]; +} + +message IDQuery { + // Defines the ID of the user schema to query for. + 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: "\"163840776835432705\""; + } + ]; + // Defines which text comparison method used for the id query. + zitadel.object.v2beta.TextQueryMethod method = 2 [ + (validate.rules).enum.defined_only = true + ]; +} + +message TypeQuery { + // Defines which type to query for. + string type = 1 [ + (validate.rules).string = {max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + max_length: 200, + example: "\"employees\""; + } + ]; + // Defines which text comparison method used for the type query. + zitadel.object.v2beta.TextQueryMethod method = 2 [ + (validate.rules).enum.defined_only = true + ]; +} + +message StateQuery { + // Defines the state to query for. + 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\"" + } + ]; +} + +enum State { + STATE_UNSPECIFIED = 0; + STATE_ACTIVE = 1; + STATE_INACTIVE = 2; +} + +enum AuthenticatorType { + AUTHENTICATOR_TYPE_UNSPECIFIED = 0; + AUTHENTICATOR_TYPE_USERNAME = 1; + AUTHENTICATOR_TYPE_PASSWORD = 2; + AUTHENTICATOR_TYPE_WEBAUTHN = 3; + AUTHENTICATOR_TYPE_TOTP = 4; + AUTHENTICATOR_TYPE_OTP_EMAIL = 5; + AUTHENTICATOR_TYPE_OTP_SMS = 6; + AUTHENTICATOR_TYPE_AUTHENTICATION_KEY = 7; + AUTHENTICATOR_TYPE_IDENTITY_PROVIDER = 8; +} \ No newline at end of file diff --git a/proto/zitadel/user/schema/v3alpha/user_schema_service.proto b/proto/zitadel/user/schema/v3alpha/user_schema_service.proto new file mode 100644 index 0000000000..0ef1c9c5c5 --- /dev/null +++ b/proto/zitadel/user/schema/v3alpha/user_schema_service.proto @@ -0,0 +1,452 @@ +syntax = "proto3"; + +package zitadel.user.schema.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/object/v2beta/object.proto"; +import "zitadel/protoc_gen_zitadel/v2/options.proto"; +import "zitadel/user/schema/v3alpha/user_schema.proto"; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/schema/v3alpha"; + + +option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { + info: { + title: "User Schema Service"; + version: "3.0-alpha"; + description: "This API is intended to manage data schemas for users in a ZITADEL instance. This project is in alpha state. It can AND will continue breaking until the service provides the same functionality as the v1 and v2 user services."; + 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"; + produces: "application/json"; + + consumes: "application/grpc"; + produces: "application/grpc"; + + consumes: "application/grpc-web+proto"; + produces: "application/grpc-web+proto"; + + host: "$CUSTOM-DOMAIN"; + base_path: "/"; + + 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 UserSchemaService { + + // List user schemas + // + // List all matching user schemas. By default, we will return all user schema of your instance. Make sure to include a limit and sorting for pagination. + rpc ListUserSchemas (ListUserSchemasRequest) returns (ListUserSchemasResponse) { + option (google.api.http) = { + post: "/v3alpha/user_schemas/search" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "userschema.read" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "A list of all user schema matching the query"; + }; + }; + responses: { + key: "400"; + value: { + description: "invalid list query"; + schema: { + json_schema: { + ref: "#/definitions/rpcStatus"; + }; + }; + }; + }; + }; + } + + // User schema by ID + // + // Returns the user schema identified by the requested ID. + rpc GetUserSchemaByID (GetUserSchemaByIDRequest) returns (GetUserSchemaByIDResponse) { + option (google.api.http) = { + get: "/v3alpha/user_schemas/{id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "userschema.read" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Schema successfully retrieved"; + } + }; + }; + } + + // Create a user schema + // + // Create the first revision of a new user schema. The schema can then be used on users to store and validate their data. + rpc CreateUserSchema (CreateUserSchemaRequest) returns (CreateUserSchemaResponse) { + option (google.api.http) = { + post: "/v3alpha/user_schemas" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "userschema.write" + } + http_response: { + success_code: 201 + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "201"; + value: { + description: "Schema successfully created"; + schema: { + json_schema: { + ref: "#/definitions/v3alphaCreateUserSchemaResponse"; + } + } + }; + }; + }; + } + + // Update a user schema + // + // Update an existing user schema to a new revision. Users based on the current revision will not be affected until they are updated. + rpc UpdateUserSchema (UpdateUserSchemaRequest) returns (UpdateUserSchemaResponse) { + option (google.api.http) = { + put: "/v3alpha/user_schemas/{id}" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "userschema.write" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "Schema successfully updated"; + }; + }; + }; + } + + // Deactivate a user schema + // + // Deactivate an existing user schema and change it into a read-only state. Users based on this schema cannot be updated anymore, but are still able to authenticate. + rpc DeactivateUserSchema (DeactivateUserSchemaRequest) returns (DeactivateUserSchemaResponse) { + option (google.api.http) = { + post: "/v3alpha/user_schemas/{id}/deactivate" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "userschema.write" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "Schema successfully deactivated"; + }; + }; + }; + } + + // Reactivate a user schema + // + // Reactivate an previously deactivated user schema and change it into an active state again. + rpc ReactivateUserSchema (ReactivateUserSchemaRequest) returns (ReactivateUserSchemaResponse) { + option (google.api.http) = { + post: "/v3alpha/user_schemas/{id}/reactivate" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "userschema.write" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "Schema successfully reactivated"; + }; + }; + }; + } + + // Delete a user schema + // + // Delete an existing user schema. This operation is only allowed if there are no associated users to it. + rpc DeleteUserSchema (DeleteUserSchemaRequest) returns (DeleteUserSchemaResponse) { + option (google.api.http) = { + delete: "/v3alpha/user_schemas/{id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "userschema.delete" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "Schema successfully deleted"; + }; + }; + }; + } + +} + +message ListUserSchemasRequest { + // list limitations and ordering. + zitadel.object.v2beta.ListQuery query = 1; + // the field the result is sorted. + zitadel.user.schema.v3alpha.FieldName sorting_column = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"FIELD_NAME_TYPE\""; + } + ]; + // Define the criteria to query for. + repeated zitadel.user.schema.v3alpha.SearchQuery queries = 3; +} + +message ListUserSchemasResponse { + // Details provides information about the returned result including total amount found. + zitadel.object.v2beta.ListDetails details = 1; + // States by which field the results are sorted. + zitadel.user.schema.v3alpha.FieldName sorting_column = 2; + // The result contains the user schemas, which matched the queries. + repeated zitadel.user.schema.v3alpha.UserSchema result = 3; +} + + +message GetUserSchemaByIDRequest { + // unique identifier of the schema. + 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 GetUserSchemaByIDResponse { + zitadel.user.schema.v3alpha.UserSchema schema = 1; +} + + +message CreateUserSchemaRequest { + // Type is a human readable word describing the schema. + string type = 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: "\"employees\""; + } + ]; + oneof data_type { + option (validate.required) = true; + + // JSON schema representation defining the user. + google.protobuf.Struct schema = 2 [ + (validate.rules).message = {required: true}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "{\"$schema\":\"https://example.com/user/employees\",\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\",\"required\":true},\"description\":{\"type\":\"string\"}}}" + } + ]; + + // (--In the future we will allow to use an external registry.--) + } + // Defines the possible types of authenticators. + repeated AuthenticatorType possible_authenticators = 3 [ + (validate.rules).repeated = {unique: true, items: {enum: {defined_only: true}}}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "[\"AUTHENTICATOR_TYPE_USERNAME\",\"AUTHENTICATOR_TYPE_PASSWORD\",\"AUTHENTICATOR_TYPE_WEBAUTHN\"]"; + } + ]; +} + +message CreateUserSchemaResponse { + // ID is the read-only unique identifier of the schema. + string id = 1; + // Details provide some base information (such as the last change date) of the schema. + zitadel.object.v2beta.Details details = 2; +} + + +message UpdateUserSchemaRequest { + // unique identifier of the schema. + string id = 1; + // Type is a human readable word describing the schema. + optional string type = 2 [ + (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: "\"employees\""; + } + ]; + oneof data_type { + // JSON schema representation defining the user. + google.protobuf.Struct schema = 3 [ + (validate.rules).message = {required: true}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "{\"$schema\":\"https://example.com/user/employees\",\"type\":\"object\",\"properties\":{\"name\":{\"type\":\"string\",\"required\":true},\"description\":{\"type\":\"string\"}}}" + } + ]; + } + // Defines the possible types of authenticators. + // + // Removal of an authenticator does not remove the authenticator on a user. + repeated AuthenticatorType possible_authenticators = 4 [ + (validate.rules).repeated = {unique: true, items: {enum: {defined_only: true}}}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "[\"AUTHENTICATOR_TYPE_USERNAME\",\"AUTHENTICATOR_TYPE_PASSWORD\",\"AUTHENTICATOR_TYPE_WEBAUTHN\"]"; + } + ]; +} + +message UpdateUserSchemaResponse { + // Details provide some base information (such as the last change date) of the schema. + zitadel.object.v2beta.Details details = 1; +} + +message DeactivateUserSchemaRequest { + // unique identifier of the schema. + string id = 1; +} + +message DeactivateUserSchemaResponse { + // Details provide some base information (such as the last change date) of the schema. + zitadel.object.v2beta.Details details = 1; +} + +message ReactivateUserSchemaRequest { + // unique identifier of the schema. + string id = 1; +} + +message ReactivateUserSchemaResponse { + // Details provide some base information (such as the last change date) of the schema. + zitadel.object.v2beta.Details details = 1; +} + +message DeleteUserSchemaRequest { + // unique identifier of the schema. + string id = 1; +} + +message DeleteUserSchemaResponse { + // Details provide some base information (such as the last change date) of the schema. + zitadel.object.v2beta.Details details = 1; +} + + diff --git a/proto/zitadel/user/v3alpha/authenticator.proto b/proto/zitadel/user/v3alpha/authenticator.proto new file mode 100644 index 0000000000..a87aaf010f --- /dev/null +++ b/proto/zitadel/user/v3alpha/authenticator.proto @@ -0,0 +1,476 @@ +syntax = "proto3"; + +package zitadel.user.v3alpha; + +import "google/api/field_behavior.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; +import "zitadel/object/v2beta/object.proto"; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v3alpha"; + +message Authenticators { + // All of the user's usernames, which will be used for identification during authentication. + repeated Username usernames = 1; + // If the user has set a password, the time it was last changed will be returned. + Password password = 2; + // Meta information about the user's WebAuthN authenticators. + repeated WebAuthN web_auth_n = 3; + // A list of the user's time-based one-time-password (TOTP) authenticators, + // incl. the name for identification. + repeated TOTP totps = 4; + // A list of the user's one-time-password (OTP) SMS authenticators. + repeated OTPSMS otp_sms = 5; + // A list of the user's one-time-password (OTP) Email authenticators. + repeated OTPEmail otp_email = 6; + // A list of the user's authentication keys. They can be used to authenticate e.g. by JWT Profile. + repeated AuthenticationKey authentication_keys = 7; + // A list of the user's linked identity providers (IDPs). + repeated IdentityProvider identity_providers = 8; +} + +message Username { + // unique identifier of the username. + string username_id = 1; + // The user's unique username. It is used for identification during authentication. + string username = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"gigi-giraffe\""; + } + ]; + // By default usernames must be unique across all organizations in an instance. + // This option allow to restrict the uniqueness to the user's own organization. + // As a result, this username can only be used if the authentication is limited + // to the corresponding organization. + // + // This can be useful if you provide multiple usernames for a single user, where one + // if specific to your organization, e.g.: + // - gigi-giraffe@zitadel.com (unique across organizations) + // - gigi-giraffe (unique only inside the ZITADEL organization) + bool is_organization_specific = 3; +} + +message SetUsername { + // Set the user's username. This will be used for identification during authentication. + string username = 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: "\"gigi-giraffe\""; + } + ]; + // By default username must be unique across all organizations in an instance. + // This option allow to restrict the uniqueness to the user's own organization. + // As a result, this username can only be used if the authentication is limited + // to the corresponding organization. + // + // This can be useful if you provide multiple usernames for a single user, where one + // if specific to your organization, e.g.: + // - gigi-giraffe@zitadel.com (unique across organizations) + // - gigi-giraffe (unique only inside the ZITADEL organization) + bool is_organization_specific = 2; +} + +message Password { + // States the time the password was last changed. + google.protobuf.Timestamp last_changed = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"2019-04-01T08:45:00.000000Z\""; + } + ]; +} + +message WebAuthN { + // unique identifier of the WebAuthN authenticator. + string web_auth_n_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629023906488334\"" + } + ]; + // Name of the WebAuthN authenticator. This is used for easier identification. + string name = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"fido key\"" + } + ]; + // State whether the WebAuthN registration has been completed. + bool is_verified = 3; + // States if the user has been verified during the registration. Authentication with this device + // will be considered as multi factor authentication (MFA) without the need to check a password + // (typically known as Passkeys). + // Without user verification it will be a second factor authentication (2FA), typically done + // after a password check. + // + // More on WebAuthN User Verification: https://www.w3.org/TR/webauthn/#user-verification + bool user_verified = 4; +} + +message OTPSMS { + // unique identifier of the one-time-password (OTP) SMS authenticator. + string otp_sms_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629023906488334\"" + } + ]; + // The phone number used for the OTP SMS authenticator. + string phone = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"+41791234567\""; + } + ]; + // State whether the OTP SMS registration has been completed. + bool is_verified = 3; +} + +message OTPEmail { + // unique identifier of the one-time-password (OTP) Email authenticator. + string otp_email_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629023906488334\"" + } + ]; + // The email address used for the OTP Email authenticator. + string address = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"mini@mouse.com\""; + } + ]; + // State whether the OTP Email registration has been completed. + bool is_verified = 3; +} + +message TOTP { + // unique identifier of the time-based one-time-password (TOTP) authenticator. + string totp_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629023906488334\"" + } + ]; + // The name provided during registration. This is used for easier identification. + string name = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"Google Authenticator\"" + } + ]; + // State whether the TOTP registration has been completed. + bool is_verified = 3; +} + +message AuthenticationKey { + // ID is the read-only unique identifier of the authentication key. + string authentication_key_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629023906488334\""; + } + ]; + zitadel.object.v2beta.Details details = 2; + // the file type of the key + AuthNKeyType type = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"KEY_TYPE_JSON\""; + } + ]; + // After the expiration date, the key will no longer be usable for authentication. + google.protobuf.Timestamp expiration_date = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"3019-04-01T08:45:00.000000Z\""; + } + ]; +} + +enum AuthNKeyType { + AUTHN_KEY_TYPE_UNSPECIFIED = 0; + AUTHN_KEY_TYPE_JSON = 1; +} + +message IdentityProvider { + // IDP ID is the read-only unique identifier of the identity provider in ZITADEL. + string idp_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629023906488334\""; + } + ]; + // IDP name is the name of the identity provider in ZITADEL. + string idp_name = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"google\""; + } + ]; + // The user ID represents the ID provided by the identity provider. + // This ID is used to link the user in ZITADEL with the identity provider. + string user_id = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"as-12-df-89\""; + } + ]; + // The username represents the username provided by the identity provider. + string username = 5 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"gigi.long-neck@gmail.com\""; + } + ]; +} + +message SetAuthenticators { + repeated SetUsername usernames = 1; + SetPassword password = 2; +} + +message SetPassword { + oneof type { + // Provide the plain text password. ZITADEL will take care to store it in a secure way (hash). + string password = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"Secr3tP4ssw0rd!\""; + min_length: 1, + max_length: 200; + } + ]; + // Encoded hash of a password in Modular Crypt Format: + // https://zitadel.com/docs/concepts/architecture/secrets#hashed-secrets. + string hash = 2 [ + (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: "\"$2a$12$lJ08fqVr8bFJilRVnDT9QeULI7YW.nT3iwUv6dyg0aCrfm3UY8XR2\""; + } + ]; + } + // Provide if the user needs to change the password on the next use. + bool change_required = 3; +} + +message SendPasswordResetEmail { + // Optionally set a url_template, which will be used in the password reset mail + // sent by ZITADEL to guide the user to your password change page. + // If no template is set, the default ZITADEL url will be used. + optional string url_template = 2 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"https://example.com/password/changey?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}\""; + } + ]; +} + +message SendPasswordResetSMS {} + +message ReturnPasswordResetCode {} + +enum WebAuthNAuthenticatorType { + WEB_AUTH_N_AUTHENTICATOR_UNSPECIFIED = 0; + WEB_AUTH_N_AUTHENTICATOR_PLATFORM = 1; + WEB_AUTH_N_AUTHENTICATOR_CROSS_PLATFORM = 2; +} + +message AuthenticatorRegistrationCode { + // ID to the one time code generated by ZITADEL. + 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: "\"e2a48d6a-362b-4db6-a1fb-34feab84dc62\""; + } + ]; + // one time code generated by ZITADEL. + string code = 2 [ + (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: "\"SKJd342k\""; + } + ]; +} + +message SendWebAuthNRegistrationLink { + // Optionally set a url_template, which will be used in the mail sent by ZITADEL + // to guide the user to your passkey registration page. + // If no template is set, the default ZITADEL url will be used. + optional string url_template = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"https://example.com/passkey/register?userID={{.UserID}}&orgID={{.OrgID}}&codeID={{.CodeID}}&code={{.Code}}\""; + } + ]; +} + +message ReturnWebAuthNRegistrationCode {} + + +message RedirectURLs { + // URL to which the user will be redirected after a successful login. + string success_url = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200, uri_ref: true}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"https://custom.com/login/idp/success\""; + } + ]; + // URL to which the user will be redirected after a failed login. + string failure_url = 2 [ + (validate.rules).string = {min_len: 1, max_len: 200, uri_ref: true}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"https://custom.com/login/idp/fail\""; + } + ]; +} + +message LDAPCredentials { + // Username used to login through LDAP. + string username = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200, uri_ref: true}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"username\""; + } + ]; + // Password used to login through LDAP. + string password = 2 [ + (validate.rules).string = {min_len: 1, max_len: 200, uri_ref: true}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"Password1!\""; + } + ]; +} + + +message IdentityProviderIntent { + // ID of the identity provider (IDP) intent. + string idp_intent_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"163840776835432705\""; + } + ]; + // Token of the identity provider (IDP) intent. + string idp_intent_token = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"SJKL3ioIDpo342ioqw98fjp3sdf32wahb=\""; + } + ]; + // If the user was already federated and linked to a ZITADEL user, it's id will be returned. + optional string user_id = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"163840776835432345\""; + } + ]; +} + +message IDPInformation{ + // ID of the identity provider. + string idp_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629026806489455\""; + } + ]; + // ID of the user provided by the identity provider. + string user_id = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + // Username of the user provided by the identity provider. + string user_name = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"user@external.com\""; + } + ]; + // Complete information returned by the identity provider. + google.protobuf.Struct raw_information = 4; + // additional access information returned by the identity provider. + oneof access{ + // OAuth/OIDC access (and id_token) returned by the identity provider. + IDPOAuthAccessInformation oauth = 5; + // LDAP entity attributes returned by the identity provider + IDPLDAPAccessInformation ldap = 6; + // SAMLResponse returned by the identity provider + IDPSAMLAccessInformation saml = 7; + } +} + +message IDPOAuthAccessInformation{ + // The access_token returned by the identity provider. + string access_token = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"JWLKFSJlijorifjOJOIehjt8jOIEWJGh3tgiEN3WIUGH8Ehgiewhg\""; + } + ]; + // In case the provider returned an id_token. + optional string id_token = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c\""; + } + ]; +} + +message IDPLDAPAccessInformation{ + // The attributes of the user returned by the identity provider. + google.protobuf.Struct attributes = 1; +} + +message IDPSAMLAccessInformation{ + // The SAML assertion returned by the identity provider. + bytes assertion = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"PEFzc2VydGlvbiB4bWxucz11cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIElEPV9mNjc5NDE5MjliZGY5MTcyOTMyMyBJc3N1ZUluc3RhbnQ9MjAyNC0wMi0wOFQxMzo1MTozNy45NDdaIFZlcnNpb249Mi4wPjxJc3N1ZXIgeG1sbnM9dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbiBOYW1lUXVhbGlmaWVyPSBTUE5hbWVRdWFsaWZpZXI9IEZvcm1hdD11cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6bmFtZWlkLWZvcm1hdDplbnRpdHkgU1BQcm92aWRlZElEPT5odHRwczovL3NhbWwuZXhhbXBsZS5jb20vZW50aXR5aWRcPC9Jc3N1ZXJcPlw8U2lnbmF0dXJlXD5cPFNwYWNlXD5cPC9TcGFjZVw+XDxUYWdcPlw8L1RhZ1w+XDwvU2lnbmF0dXJlXD5cPFN1YmplY3QgeG1sbnM9dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmFzc2VydGlvbj48TmFtZUlEIE5hbWVRdWFsaWZpZXI9IFNQTmFtZVF1YWxpZmllcj0gRm9ybWF0PXVybjpvYXNpczpuYW1lczp0YzpTQU1MOjEuMTpuYW1laWQtZm9ybWF0OmVtYWlsQWRkcmVzcyBTUFByb3ZpZGVkSUQ9PmphY2tzb25AZXhhbXBsZS5jb208L05hbWVJRD48U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmNtOmJlYXJlcj48U3ViamVjdENvbmZpcm1hdGlvbkRhdGEgTm90T25PckFmdGVyPTIwMjQtMDItMDhUMTM6NTY6MzcuOTQ3WiBOb3RCZWZvcmU9MDAwMS0wMS0wMVQwMDowMDowMFogUmVjaXBpZW50PWh0dHBzOi8vZGVtby56aXRhZGVsLmNsb3VkL2lkcHMvMjUyODM0OTQ3NjU4NzA5NzYyL3NhbWwvYWNzIEluUmVzcG9uc2VUbz1pZC0yMGIxZGEyNWUzNzVhYWQyYmZmNjIxOGY2ZmUzMWRmMzYzNTRjMmI2IEFkZHJlc3M9PjwvU3ViamVjdENvbmZpcm1hdGlvbkRhdGE+PC9TdWJqZWN0Q29uZmlybWF0aW9uPjwvU3ViamVjdD48Q29uZGl0aW9ucyBOb3RCZWZvcmU9MjAyNC0wMi0wOFQxMzo0NjozNy45NDdaIE5vdE9uT3JBZnRlcj0yMDI0LTAyLTA4VDEzOjU2OjM3Ljk0N1o+PEF1ZGllbmNlUmVzdHJpY3Rpb24+PEF1ZGllbmNlPmh0dHBzOi8vZGVtby56aXRhZGVsLmNsb3VkL2lkcHMvMjUyODM0OTQ3NjU4NzA5NzYyL3NhbWwvbWV0YWRhdGFcPC9BdWRpZW5jZVw+XDwvQXVkaWVuY2VSZXN0cmljdGlvblw+XDwvQ29uZGl0aW9uc1w+XDxBdXRoblN0YXRlbWVudCBBdXRobkluc3RhbnQ9MjAyNC0wMi0wOFQxMzo1MTozNy45NDdaIFNlc3Npb25JbmRleD1pZC0yMGIxZGEyNWUzNzVhYWQyYmZmNjIxOGY2ZmUzMWRmMzYzNTRjMmI2PjxBdXRobkNvbnRleHQ+PEF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkUHJvdGVjdGVkVHJhbnNwb3J0PC9BdXRobkNvbnRleHRDbGFzc1JlZj48L0F1dGhuQ29udGV4dD48L0F1dGhuU3RhdGVtZW50PjxBdHRyaWJ1dGVTdGF0ZW1lbnQ+PEF0dHJpYnV0ZSBGcmllbmRseU5hbWU9IE5hbWU9aWQgTmFtZUZvcm1hdD11cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OnVuc3BlY2lmaWVkPjxBdHRyaWJ1dGVWYWx1ZSB4bWxuczpfWE1MU2NoZW1hLWluc3RhbmNlPWh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIF9YTUxTY2hlbWEtaW5zdGFuY2U6dHlwZT14czpzdHJpbmc+MWRkYTlmYjQ5MWRjMDFiZDI0ZDI0MjNiYTJmMjJhZTU2MWY1NmRkZjIzNzZiMjlhMTFjODAyODFkMjEyMDFmOTwvQXR0cmlidXRlVmFsdWU+PC9BdHRyaWJ1dGU+PEF0dHJpYnV0ZSBGcmllbmRseU5hbWU9IE5hbWU9ZW1haWwgTmFtZUZvcm1hdD11cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXR0cm5hbWUtZm9ybWF0OnVuc3BlY2lmaWVkPjxBdHRyaWJ1dGVWYWx1ZSB4bWxuczpfWE1MU2NoZW1hLWluc3RhbmNlPWh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIF9YTUxTY2hlbWEtaW5zdGFuY2U6dHlwZT14czpzdHJpbmc+amFja3NvbkBleGFtcGxlLmNvbTwvQXR0cmlidXRlVmFsdWU+PC9BdHRyaWJ1dGU+PEF0dHJpYnV0ZSBGcmllbmRseU5hbWU9IE5hbWU9Zmlyc3ROYW1lIE5hbWVGb3JtYXQ9dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDp1bnNwZWNpZmllZD48QXR0cmlidXRlVmFsdWUgeG1sbnM6X1hNTFNjaGVtYS1pbnN0YW5jZT1odHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSBfWE1MU2NoZW1hLWluc3RhbmNlOnR5cGU9eHM6c3RyaW5nPmphY2tzb248L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjxBdHRyaWJ1dGUgRnJpZW5kbHlOYW1lPSBOYW1lPWxhc3ROYW1lIE5hbWVGb3JtYXQ9dXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOmF0dHJuYW1lLWZvcm1hdDp1bnNwZWNpZmllZD48QXR0cmlidXRlVmFsdWUgeG1sbnM6X1hNTFNjaGVtYS1pbnN0YW5jZT1odHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSBfWE1MU2NoZW1hLWluc3RhbmNlOnR5cGU9eHM6c3RyaW5nPmphY2tzb248L0F0dHJpYnV0ZVZhbHVlPjwvQXR0cmlidXRlPjwvQXR0cmlidXRlU3RhdGVtZW50PjwvQXNzZXJ0aW9uPg==\"" + } + ]; +} + + +message IDPAuthenticator { + // ID of the identity provider + string idp_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\""; + } + ]; + // ID of the user provided by the identity provider + string user_id = 2 [ + (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: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; + } + ]; + // Username of the user provided by the identity provider. + string user_name = 3 [ + (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: "\"user@external.com\""; + } + ]; +} diff --git a/proto/zitadel/user/v3alpha/communication.proto b/proto/zitadel/user/v3alpha/communication.proto new file mode 100644 index 0000000000..af799f411d --- /dev/null +++ b/proto/zitadel/user/v3alpha/communication.proto @@ -0,0 +1,109 @@ +syntax = "proto3"; + +package zitadel.user.v3alpha; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v3alpha"; + +import "google/api/field_behavior.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; + +message Contact { + // Email contact information of the user. + Email email = 1; + // Phone contact information of the user. + Phone phone = 2; +} + +message Email { + // Email address of the user. + string address = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"mini@mouse.com\""; + } + ]; + // IsVerified states if the email address has been verified to belong to the user. + bool is_verified = 2; +} + +message Phone { + // Phone number of the user. + string number = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"+41791234567\""; + } + ]; + // IsVerified states if the phone number has been verified to belong to the user. + bool is_verified = 2; +} + +message SetContact { + optional SetEmail email = 1; + optional SetPhone phone = 2; +} + +message SetEmail { + // Set the email address. + string address = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200, email: true}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"mini@mouse.com\""; + } + ]; + // if no verification is specified, an email is sent with the default url + oneof verification { + // Let ZITADEL send the link to the user via email. + SendEmailVerificationCode send_code = 2; + // Get the code back to provide it to the user in your preferred mechanism. + ReturnEmailVerificationCode return_code = 3; + // Set the email as already verified. + bool is_verified = 4 [(validate.rules).bool.const = true]; + } +} + +message SendEmailVerificationCode { + // Optionally set a url_template, which will be used in the verification mail sent by ZITADEL + // to guide the user to your verification page. + // If no template is set, the default ZITADEL url will be used. + optional string url_template = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 200; + example: "\"https://example.com/email/verify?userID={{.UserID}}&code={{.Code}}&orgID={{.OrgID}}\""; + } + ]; +} + +message ReturnEmailVerificationCode {} + +message SetPhone { + // Set the user's phone number. + string number = 1 [ + (validate.rules).string = {min_len: 1, max_len: 20}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 20; + example: "\"+41791234567\""; + } + ]; + // if no verification is specified, a SMS is sent + oneof verification { + // Let ZITADEL send the link to the user via SMS. + SendPhoneVerificationCode send_code = 2; + // Get the code back to provide it to the user in your preferred mechanism. + ReturnPhoneVerificationCode return_code = 3; + // Set the phone as already verified. + bool is_verified = 4 [(validate.rules).bool.const = true]; + } +} + +message SendPhoneVerificationCode {} + +message ReturnPhoneVerificationCode {} + + diff --git a/proto/zitadel/user/v3alpha/query.proto b/proto/zitadel/user/v3alpha/query.proto new file mode 100644 index 0000000000..aa0fffbd91 --- /dev/null +++ b/proto/zitadel/user/v3alpha/query.proto @@ -0,0 +1,207 @@ +syntax = "proto3"; + +package zitadel.user.v3alpha; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v3alpha"; + +import "google/api/field_behavior.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; +import "zitadel/user/v3alpha/user.proto"; +import "zitadel/object/v2beta/object.proto"; + +message SearchQuery { + oneof query { + option (validate.required) = true; + + + // Union the results of each sub query ('OR'). + OrQuery or_query = 1; + // Limit the result to match all sub queries ('AND'). + // Note that if you specify multiple queries, they will be implicitly used as andQueries. + // Use the andQuery in combination with orQuery and notQuery. + AndQuery and_query = 2; + // Exclude / Negate the result of the sub query ('NOT'). + NotQuery not_query = 3; + + // Limit the result to a specific user ID. + UserIDQuery user_id_query = 4; + // Limit the result to a specific organization. + OrganizationIDQuery organization_id_query = 5; + // Limit the result to a specific username. + UsernameQuery username_query = 6; + // Limit the result to a specific contact email. + EmailQuery email_query = 7; + // Limit the result to a specific contact phone. + PhoneQuery phone_query = 8; + // Limit the result to a specific state of the user. + StateQuery state_query = 9; + // Limit the result to a specific schema ID. + SchemaIDQuery schema_ID_query = 10; + // Limit the result to a specific schema type. + SchemaTypeQuery schema_type_query = 11; + } +} + +message OrQuery { + repeated SearchQuery queries = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "[{\"userIdQuery\": {\"id\": \"163840776835432705\",\"method\": \"TEXT_QUERY_METHOD_EQUALS\"}},{\"userIdQuery\": {\"id\": \"163840776835943483\",\"method\": \"TEXT_QUERY_METHOD_EQUALS\"}}]" + } + ]; +} +message AndQuery { + repeated SearchQuery queries = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "[{\"organizationIdQuery\": {\"id\": \"163840776835432705\",\"method\": \"TEXT_QUERY_METHOD_EQUALS\"}},{\"usernameQuery\": {\"username\": \"gigi\",\"method\": \"TEXT_QUERY_METHOD_EQUALS\"}}]" + } + ]; +} + +message NotQuery { + SearchQuery query = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "{\"schemaIDQuery\": {\"id\": \"163840776835432705\"}}" + } + ]; +} + +message UserIDQuery { + // Defines the ID of the user to query for. + 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: "\"163840776835432705\""; + } + ]; + // Defines which text comparison method used for the id query. + zitadel.object.v2beta.TextQueryMethod method = 2 [ + (validate.rules).enum.defined_only = true + ]; +} + +message OrganizationIDQuery { + // Defines the ID of the organization to query for. + 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: "\"163840776835432705\""; + } + ]; + // Defines which text comparison method used for the id query. + zitadel.object.v2beta.TextQueryMethod method = 2 [ + (validate.rules).enum.defined_only = true + ]; +} + +message UsernameQuery { + // Defines the username to query for. + string username = 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: "\"gigi-giraffe\""; + } + ]; + // Defines which text comparison method used for the username query. + zitadel.object.v2beta.TextQueryMethod method = 2 [ + (validate.rules).enum.defined_only = true + ]; + // Defines that the username must only be unique in the organisation. + bool is_organization_specific = 3; +} + +message EmailQuery { + // Defines the email of the user to query for. + string address = 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: "\"gigi@zitadel.com\""; + } + ]; + // Defines which text comparison method used for the email query. + zitadel.object.v2beta.TextQueryMethod method = 2 [ + (validate.rules).enum.defined_only = true + ]; +} + +message PhoneQuery { + // Defines the phone of the user to query for. + string number = 1 [ + (validate.rules).string = {min_len: 1, max_len: 20}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 20; + example: "\"+41791234567\""; + } + ]; + // Defines which text comparison method used for the phone query. + zitadel.object.v2beta.TextQueryMethod method = 2 [ + (validate.rules).enum.defined_only = true + ]; +} + + +message StateQuery { + // Defines the state to query for. + State state = 1 [ + (validate.rules).enum.defined_only = true, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"STATE_ACTIVE\"" + } + ]; +} + +message SchemaIDQuery { + // Defines the ID of the schema to query for. + 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: "\"163840776835432705\""; + } + ]; +} + +message SchemaTypeQuery { + // Defines which type to query for. + string type = 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: "\"employees\""; + } + ]; + // Defines which text comparison method used for the type query. + zitadel.object.v2beta.TextQueryMethod method = 2 [ + (validate.rules).enum.defined_only = true + ]; +} + +enum FieldName { + FIELD_NAME_UNSPECIFIED = 0; + FIELD_NAME_ID = 1; + FIELD_NAME_CREATION_DATE = 2; + FIELD_NAME_CHANGE_DATE = 3; + FIELD_NAME_EMAIL = 4; + FIELD_NAME_PHONE = 5; + FIELD_NAME_STATE = 6; + FIELD_NAME_SCHEMA_ID = 7; + FIELD_NAME_SCHEMA_TYPE = 8; +} diff --git a/proto/zitadel/user/v3alpha/user.proto b/proto/zitadel/user/v3alpha/user.proto new file mode 100644 index 0000000000..244c9a87e9 --- /dev/null +++ b/proto/zitadel/user/v3alpha/user.proto @@ -0,0 +1,66 @@ +syntax = "proto3"; + +package zitadel.user.v3alpha; + +import "google/api/field_behavior.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/timestamp.proto"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "validate/validate.proto"; +import "zitadel/object/v2beta/object.proto"; +import "zitadel/user/v3alpha/authenticator.proto"; +import "zitadel/user/v3alpha/communication.proto"; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v3alpha"; + +message User { + + // ID is the read-only unique identifier of the user. + string user_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629012906488334\""; + } + ]; + // Details provide some base information (such as the last change date) of the user. + zitadel.object.v2beta.Details details = 2; + // The user's authenticators. They are used to identify and authenticate the user + // during the authentication process. + Authenticators authenticators = 3; + // Contact information for the user. ZITADEL will use this in case of internal notifications. + Contact contact = 4; + // State of the user. + State state = 5; + // The schema the user and it's data is based on. + Schema schema = 6; + // The user's data based on the provided schema. + google.protobuf.Struct data = 7; +} + +enum State { + USER_STATE_UNSPECIFIED = 0; + USER_STATE_ACTIVE = 1; + USER_STATE_INACTIVE = 2; + USER_STATE_DELETED = 3; + USER_STATE_LOCKED = 4; +} + +message Schema { + // The unique identifier of the user schema. + string id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629026806489455\"" + } + ]; + // The human readable name of the user schema. + string type = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"employees\""; + } + ]; + // The revision the user's data is based on of the revision. + uint32 revision = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "7"; + } + ]; +} diff --git a/proto/zitadel/user/v3alpha/user_service.proto b/proto/zitadel/user/v3alpha/user_service.proto new file mode 100644 index 0000000000..0e42460ae1 --- /dev/null +++ b/proto/zitadel/user/v3alpha/user_service.proto @@ -0,0 +1,2099 @@ +syntax = "proto3"; + +package zitadel.user.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/object/v2beta/object.proto"; +import "zitadel/protoc_gen_zitadel/v2/options.proto"; +import "zitadel/user/v3alpha/authenticator.proto"; +import "zitadel/user/v3alpha/communication.proto"; +import "zitadel/user/v3alpha/query.proto"; +import "zitadel/user/v3alpha/user.proto"; + +option go_package = "github.com/zitadel/zitadel/pkg/grpc/user/v3alpha"; + + +option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { + info: { + title: "User Service"; + version: "3.0-alpha"; + description: "This API is intended to manage users with your own data schema in a ZITADEL instance. This project is in alpha state. It can AND will continue breaking until the service provides the same functionality as the v1 and v2 user services."; + 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"; + produces: "application/json"; + + consumes: "application/grpc"; + produces: "application/grpc"; + + consumes: "application/grpc-web+proto"; + produces: "application/grpc-web+proto"; + + host: "$CUSTOM-DOMAIN"; + base_path: "/"; + + 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 UserService { + + // List users + // + // List all matching users. By default, we will return all users of your instance. + // Make sure to include a limit and sorting for pagination. + rpc ListUsers (ListUsersRequest) returns (ListUsersResponse) { + option (google.api.http) = { + post: "/v3alpha/users/search" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "A list of all users matching the query"; + }; + }; + responses: { + key: "400"; + value: { + description: "invalid list query"; + schema: { + json_schema: { + ref: "#/definitions/rpcStatus"; + }; + }; + }; + }; + }; + } + + // User by ID + // + // Returns the user identified by the requested ID. + rpc GetUserByID (GetUserByIDRequest) returns (GetUserByIDResponse) { + option (google.api.http) = { + get: "/v3alpha/users/{user_id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "User successfully retrieved"; + } + }; + }; + } + + // Create a user + // + // Create a new user with an optional data schema. + rpc CreateUser (CreateUserRequest) returns (CreateUserResponse) { + option (google.api.http) = { + post: "/v3alpha/users" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "user.write" + org_field: "organization" + } + http_response: { + success_code: 201 + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "201"; + value: { + description: "User successfully created"; + schema: { + json_schema: { + ref: "#/definitions/v3alphaCreateUserResponse"; + }; + }; + }; + }; + }; + } + + // Update a user + // + // Update an existing user with data based on a user schema. + rpc UpdateUser (UpdateUserRequest) returns (UpdateUserResponse) { + option (google.api.http) = { + put: "/v3alpha/users/{user_id}" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "User successfully updated"; + }; + }; + }; + } + + // Deactivate a user + // + // Deactivate an existing user and change the state 'deactivated'. + // The user will not be able to log in anymore. + // Use deactivate user when the user should not be able to use the account anymore, + // but you still need access to the user data. + // + // The endpoint returns an error if the user is already in the state 'deactivated'. + rpc DeactivateUser (DeactivateUserRequest) returns (DeactivateUserResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/deactivate" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "User successfully deactivated"; + }; + }; + }; + } + + // Reactivate a user + // + // Reactivate a previously deactivated user and change the state to 'active'. + // The user will be able to log in again. + // + // The endpoint returns an error if the user is not in the state 'deactivated'. + rpc ReactivateUser (ReactivateUserRequest) returns (ReactivateUserResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/reactivate" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "User successfully reactivated"; + }; + }; + }; + } + + // Lock a user + // + // Lock an existing user and change the state 'locked'. + // The user will not be able to log in anymore. + // Use lock user when the user should temporarily not be able to log in + // because of an event that happened (wrong password, etc.) + // + // The endpoint returns an error if the user is already in the state 'locked'. + rpc LockUser (LockUserRequest) returns (LockUserResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/lock" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "User successfully locked"; + }; + }; + }; + } + + // Unlock a user + // + // Unlock a previously locked user and change the state to 'active'. + // The user will be able to log in again. + // + // The endpoint returns an error if the user is not in the state 'locked'. + rpc UnlockUser (UnlockUserRequest) returns (UnlockUserResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/unlock" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "User successfully unlocked"; + }; + }; + }; + } + + // Delete a user + // + // Delete an existing user and change the state to 'deleted'. + // The user will be able to log in anymore. + rpc DeleteUser (DeleteUserRequest) returns (DeleteUserResponse) { + option (google.api.http) = { + delete: "/v3alpha/users/{user_id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200"; + value: { + description: "User successfully deleted"; + }; + }; + }; + } + + // Set contact email + // + // Add or update the contact email address of a user. + // If the email is not passed as verified, a verification code will be generated, + // which can be either returned or will be sent to the user by email. + rpc SetContactEmail (SetContactEmailRequest) returns (SetContactEmailResponse) { + option (google.api.http) = { + put: "/v3alpha/users/{user_id}/email" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Email successfully set"; + } + }; + }; + } + + // Verify the contact email + // + // Verify the contact email with the provided code. + rpc VerifyContactEmail (VerifyContactEmailRequest) returns (VerifyContactEmailResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/email/verify" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Email successfully verified"; + } + }; + }; + } + + // Resend the contact email code + // + // Resend the email with the verification code for the contact email address. + rpc ResendContactEmailCode (ResendContactEmailCodeRequest) returns (ResendContactEmailCodeResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/email/resend" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Code resend successfully requested"; + } + }; + }; + } + + // Set contact phone + // + // Add or update the contact phone number of a user. + // If the phone is not passed as verified, a verification code will be generated, + // which can be either returned or will be sent to the user by SMS. + rpc SetContactPhone (SetContactPhoneRequest) returns (SetContactPhoneResponse) { + option (google.api.http) = { + put: "/v3alpha/users/{user_id}/phone" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Contact phone successfully set"; + } + }; + }; + } + + // Verify the contact phone + // + // Verify the contact phone with the provided code. + rpc VerifyContactPhone (VerifyContactPhoneRequest) returns (VerifyContactPhoneResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/phone/verify" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Contact phone successfully verified"; + } + }; + }; + } + + // Resend the contact phone code + // + // Resend the phone with the verification code for the contact phone number. + rpc ResendContactPhoneCode (ResendContactPhoneCodeRequest) returns (ResendContactPhoneCodeResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/phone/resend" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Code resend successfully requested"; + } + }; + }; + } + + // Add a username + // + // Add a new unique username to a user. The username will be used to identify the user on authentication. + rpc AddUsername (AddUsernameRequest) returns (AddUsernameResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/username" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Username successfully added"; + } + }; + }; + } + + // Remove a username + // + // Remove an existing username of a user, so it cannot be used for authentication anymore. + rpc RemoveUsername (RemoveUsernameRequest) returns (RemoveUsernameResponse) { + option (google.api.http) = { + delete: "/v3alpha/users/{user_id}/username/{username_id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Username successfully removed"; + } + }; + }; + } + + // Set a password + // + // Add, update or reset a user's password with either a verification code or the current password. + rpc SetPassword (SetPasswordRequest) returns (SetPasswordResponse) { + option (google.api.http) = { + post: "/v2beta/users/{user_id}/password" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Password successfully set"; + } + }; + }; + } + + // Request password reset + // + // Request a code to be able to set a new password. + rpc RequestPasswordReset (RequestPasswordResetRequest) returns (RequestPasswordResetResponse) { + option (google.api.http) = { + post: "/v2beta/users/{user_id}/password/reset" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "Password reset successfully requested"; + } + }; + }; + } + + // Start a WebAuthN registration + // + // Start the registration of a new WebAuthN device (e.g. Passkeys) for a user. + // As a response the public key credential creation options are returned, + // which are used to verify the device. + rpc StartWebAuthNRegistration (StartWebAuthNRegistrationRequest) returns (StartWebAuthNRegistrationResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/webauthn" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "WebAuthN registration successfully started"; + } + }; + }; + } + + // Verify a WebAuthN registration + // + // Verify the WebAuthN registration started by StartWebAuthNRegistration with the public key credential. + rpc VerifyWebAuthNRegistration (VerifyWebAuthNRegistrationRequest) returns (VerifyWebAuthNRegistrationResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/webauthn/{web_auth_n_id}" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "WebAuthN registration successfully verified"; + } + }; + }; + } + + // Create a WebAuthN registration link + // + // Create a link, which includes a code, that can either be returned or directly sent to the user. + // The code will allow the user to start a new WebAuthN registration. + rpc CreateWebAuthNRegistrationLink (CreateWebAuthNRegistrationLinkRequest) returns (CreateWebAuthNRegistrationLinkResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/webauthn/registration_link" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "WebAuthN registration successfully created"; + } + }; + }; + } + + // Remove a WebAuthN authenticator + // + // Remove an existing WebAuthN authenticator from a user, so it cannot be used for authentication anymore. + rpc RemoveWebAuthNAuthenticator (RemoveWebAuthNAuthenticatorRequest) returns (RemoveWebAuthNAuthenticatorResponse) { + option (google.api.http) = { + delete: "/v3alpha/users/{user_id}/webauthn/{web_auth_n_id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "WebAuthN authenticator successfully removed"; + } + }; + }; + } + + // Start a TOTP registration + // + // Start the registration of a new time-based one-time-password (TOTP) generator for a user. + // As a response a secret is returned, which is used to initialize a TOTP app or device. + rpc StartTOTPRegistration (StartTOTPRegistrationRequest) returns (StartTOTPRegistrationResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/totp" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "TOTP registration successfully started"; + } + }; + }; + } + + // Verify a TOTP registration + // + // Verify the time-based one-time-password (TOTP) registration with the generated code. + rpc VerifyTOTPRegistration (VerifyTOTPRegistrationRequest) returns (VerifyTOTPRegistrationResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/totp/{totp_id}/verify" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "TOTP registration successfully verified"; + } + }; + }; + } + + // Remove a TOTP authenticator + // + // Remove an existing time-based one-time-password (TOTP) authenticator from a user, so it cannot be used for authentication anymore. + rpc RemoveTOTPAuthenticator (RemoveTOTPAuthenticatorRequest) returns (RemoveTOTPAuthenticatorResponse) { + option (google.api.http) = { + delete: "/v3alpha/users/{user_id}/totp/{totp_id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "TOTP authenticator successfully removed"; + } + }; + }; + } + + // Add a OTP SMS authenticator + // + // Add a new one-time-password (OTP) SMS authenticator to a user. + // If the phone is not passed as verified, a verification code will be generated, + // which can be either returned or will be sent to the user by SMS. + rpc AddOTPSMSAuthenticator (AddOTPSMSAuthenticatorRequest) returns (AddOTPSMSAuthenticatorResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/otp_sms" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "OTP SMS authenticator successfully added"; + } + }; + }; + } + + // Verify OTP SMS registration + // + // Verify the OTP SMS registration with the provided code. + rpc VerifyOTPSMSRegistration (VerifyOTPSMSRegistrationRequest) returns (VerifyOTPSMSRegistrationResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/otp_sms/{otp_sms_id}/verify" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "OTP SMS authenticator successfully verified"; + } + }; + }; + } + + // Remove a OTP SMS authenticator + // + // Remove an existing one-time-password (OTP) SMS authenticator from a user, so it cannot be used for authentication anymore. + rpc RemoveOTPSMSAuthenticator (RemoveOTPSMSAuthenticatorRequest) returns (RemoveOTPSMSAuthenticatorResponse) { + option (google.api.http) = { + delete: "/v3alpha/users/{user_id}/otp_sms/{otp_sms_id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "OTP SMS authenticator successfully removed"; + } + }; + }; + } + + // Add a OTP Email authenticator + // + // Add a new one-time-password (OTP) Email authenticator to a user. + // If the email is not passed as verified, a verification code will be generated, + // which can be either returned or will be sent to the user by email. + rpc AddOTPEmailAuthenticator (AddOTPEmailAuthenticatorRequest) returns (AddOTPEmailAuthenticatorResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/otp_email" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "OTP Email authenticator successfully added"; + } + }; + }; + } + + // Verify OTP Email registration + // + // Verify the OTP Email registration with the provided code. + rpc VerifyOTPEmailRegistration (VerifyOTPEmailRegistrationRequest) returns (VerifyOTPEmailRegistrationResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/otp_email/{otp_email_id}/verify" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "OTP Email authenticator successfully verified"; + } + }; + }; + } + + // Remove a OTP Email authenticator + // + // Remove an existing one-time-password (OTP) Email authenticator from a user, so it cannot be used for authentication anymore. + rpc RemoveOTPEmailAuthenticator (RemoveOTPEmailAuthenticatorRequest) returns (RemoveOTPEmailAuthenticatorResponse) { + option (google.api.http) = { + delete: "/v3alpha/users/{user_id}/otp_email/{otp_email_id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "OTP Email authenticator successfully removed"; + } + }; + }; + } + + // Start an IDP authentication intent + // + // Start a new authentication intent on configured identity provider (IDP) for external login, registration or linking. + rpc StartIdentityProviderIntent (StartIdentityProviderIntentRequest) returns (StartIdentityProviderIntentResponse) { + option (google.api.http) = { + post: "/v3alpha/idp_intents" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "IDP intent successfully started"; + } + }; + }; + } + + // Retrieve the information of the IDP authentication intent + // + // Retrieve the information returned by the identity provider (IDP) for registration or updating an existing user with new information. + rpc RetrieveIdentityProviderIntent (RetrieveIdentityProviderIntentRequest) returns (RetrieveIdentityProviderIntentResponse) { + option (google.api.http) = { + post: "/v3alpha/idp_intents/{idp_intent_id}" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "IDP intent successfully retrieved"; + } + }; + }; + } + + // Add an IDP authenticator to a user + // + // Add a new identity provider (IDP) authenticator to an existing user. + // This will allow the user to authenticate with the provided IDP. + rpc AddIDPAuthenticator (AddIDPAuthenticatorRequest) returns (AddIDPAuthenticatorResponse) { + option (google.api.http) = { + post: "/v3alpha/users/{user_id}/idps" + body: "*" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "IDP authenticator successfully added"; + } + }; + }; + } + + // Remove an IDP authenticator + // + // Remove an existing identity provider (IDP) authenticator from a user, so it cannot be used for authentication anymore. + rpc RemoveIDPAuthenticator (RemoveIDPAuthenticatorRequest) returns (RemoveIDPAuthenticatorResponse) { + option (google.api.http) = { + delete: "/v3alpha/users/{user_id}/idps/{idp_id}" + }; + + option (zitadel.protoc_gen_zitadel.v2.options) = { + auth_option: { + permission: "authenticated" + } + }; + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + responses: { + key: "200" + value: { + description: "IDP authenticator successfully removed"; + } + }; + }; + } + +} + +message ListUsersRequest { + // list limitations and ordering. + zitadel.object.v2beta.ListQuery query = 1; + // the field the result is sorted. + zitadel.user.v3alpha.FieldName sorting_column = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"FIELD_NAME_SCHEMA_TYPE\"" + } + ]; + // Define the criteria to query for. + repeated zitadel.user.v3alpha.SearchQuery queries = 3; +} + +message ListUsersResponse { + // Details provides information about the returned result including total amount found. + zitadel.object.v2beta.ListDetails details = 1; + // States by which field the results are sorted. + zitadel.user.v3alpha.FieldName sorting_column = 2; + // The result contains the user schemas, which matched the queries. + repeated zitadel.user.v3alpha.User result = 3; +} + +message GetUserByIDRequest { + // unique identifier of the user. + string user_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 GetUserByIDResponse { + zitadel.user.v3alpha.User user = 1; +} + +message CreateUserRequest { + // Optionally set a unique identifier of the user. If unset, ZITADEL will take care of it. + optional string user_id = 1 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 200, + example: "\"69629026806489455\""; + } + ]; + // Set the organization the user belongs to. + zitadel.object.v2beta.Organization organization = 2 [ + (validate.rules).message = {required: true}, + (google.api.field_behavior) = REQUIRED + ]; + // Set the initial authenticators of the user. + SetAuthenticators authenticators = 3; + // Set the contact information (email, phone) for the user. + SetContact contact = 4; + // Define the schema the user's data schema by providing it's ID. + string schema_id = 5 [ + (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\""; + } + ]; + // Provide data about the user. It will be validated based on the specified schema. + google.protobuf.Struct data = 6 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "{\"name\":\"Gigi\",\"description\":\"the giraffe\"}" + } + ]; +} + +message CreateUserResponse { + string user_id = 1; + zitadel.object.v2beta.Details details = 2; + // The email code will be set if a contact email was set with a return_code verification option. + optional string email_code = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"SKJd342k\""; + } + ]; + // The phone code will be set if a contact phone was set with a return_code verification option. + optional string phone_code = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"IFi39dk2\""; + } + ]; +} + +message UpdateUserRequest { + // unique identifier of the user. + string user_id = 1 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629012906488334\""; + } + ]; + // Add or update the contact information (email, phone) for the user if needed. + optional SetContact contact = 4; + // Change the schema the user's data schema by providing it's ID if needed. + optional string schema_id = 5 [ + (validate.rules).string = {min_len: 1, max_len: 200}, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1, + max_length: 200, + example: "\"69629026806489455\""; + } + ]; + // Update the user data if needed. It will be validated based on the specified schema. + optional google.protobuf.Struct data = 6 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "{\"name\":\"Gigi\",\"description\":\"the giraffe\"}" + } + ]; +} + +message UpdateUserResponse { + zitadel.object.v2beta.Details details = 1; + // The email code will be set if a contact email was set with a return_code verification option. + optional string email_code = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"SKJd342k\""; + } + ]; + // The phone code will be set if a contact phone was set with a return_code verification option. + optional string phone_code = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"IFi39dk2\""; + } + ]; +} + +message DeactivateUserRequest { + // unique identifier of the user. + string user_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 DeactivateUserResponse { + zitadel.object.v2beta.Details details = 1; +} + + +message ReactivateUserRequest { + // unique identifier of the user. + string user_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 ReactivateUserResponse { + zitadel.object.v2beta.Details details = 1; +} + +message LockUserRequest { + // unique identifier of the user. + string user_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 LockUserResponse { + zitadel.object.v2beta.Details details = 1; +} + +message UnlockUserRequest { + // unique identifier of the user. + string user_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 UnlockUserResponse { + zitadel.object.v2beta.Details details = 1; +} + +message DeleteUserRequest { + // unique identifier of the user. + string user_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 DeleteUserResponse { + zitadel.object.v2beta.Details details = 1; +} + +message SetContactEmailRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // Set the user's contact email and it's verification state. + SetEmail email = 2; +} + +message SetContactEmailResponse { + zitadel.object.v2beta.Details details = 1; + // The verification code will be set if a contact email was set with a return_code verification option. + optional string verification_code = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"SKJd342k\""; + } + ]; +} + +message VerifyContactEmailRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // Set the verification code generated during the set contact email request. + string verification_code = 2 [ + (validate.rules).string = {min_len: 1, max_len: 20}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 20; + example: "\"SKJd342k\""; + } + ]; +} + +message VerifyContactEmailResponse { + zitadel.object.v2beta.Details details = 1; +} + +message ResendContactEmailCodeRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // if no verification is specified, an email is sent + oneof verification { + // Let ZITADEL send the link to the user via email. + SendEmailVerificationCode send_code = 2; + // Get the code back to provide it to the user in your preferred mechanism. + ReturnEmailVerificationCode return_code = 3; + } +} + +message ResendContactEmailCodeResponse { + zitadel.object.v2beta.Details details = 1; + // in case the verification was set to return_code, the code will be returned. + optional string verification_code = 2; +} + +message SetContactPhoneRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // Set the user's contact phone and it's verification state. + SetPhone phone = 2; +} + +message SetContactPhoneResponse { + zitadel.object.v2beta.Details details = 1; + // The phone verification code will be set if a contact phone was set with a return_code verification option. + optional string email_code = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"SKJd342k\""; + } + ]; +} + +message VerifyContactPhoneRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // Set the verification code generated during the set contact phone request. + string verification_code = 2 [ + (validate.rules).string = {min_len: 1, max_len: 20}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 20; + example: "\"SKJd342k\""; + } + ]; +} + +message VerifyContactPhoneResponse { + zitadel.object.v2beta.Details details = 1; +} + +message ResendContactPhoneCodeRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // if no verification is specified, a SMS is sent + oneof verification { + // Let ZITADEL send the link to the user via SMS. + SendPhoneVerificationCode send_code = 2; + // Get the code back to provide it to the user in your preferred mechanism. + ReturnPhoneVerificationCode return_code = 3; + } +} + +message ResendContactPhoneCodeResponse { + zitadel.object.v2beta.Details details = 1; + // in case the verification was set to return_code, the code will be returned. + optional string verification_code = 2; +} + +message AddUsernameRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // Set the user's new username. + SetUsername username = 2; +} + +message AddUsernameResponse { + zitadel.object.v2beta.Details details = 1; + // unique identifier of the username. + string username_id = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"69629023906488334\""; + } + ]; +} + +message RemoveUsernameRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the username. + string username_id = 2 [ + (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: "\"69629023906488334\""; + } + ]; +} + +message RemoveUsernameResponse { + zitadel.object.v2beta.Details details = 1; +} + +message SetPasswordRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // Provide the new password (in plain text or as hash). + SetPassword new_password = 2; + // If neither, the current password nor a verification code generated by the PasswordReset is provided, + // the user must be granted permission to set a password. + oneof verification { + // Provide the current password to verify you're allowed to change the password. + string current_password = 3 [ + (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: "\"Secr3tP4ssw0rd!\""; + } + ]; + // Or provider the verification code generated during password reset request. + string verification_code = 4 [ + (validate.rules).string = {min_len: 1, max_len: 20}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 1; + max_length: 20; + example: "\"SKJd342k\""; + } + ]; + } +} + +message SetPasswordResponse { + zitadel.object.v2beta.Details details = 1; +} + +message RequestPasswordResetRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // If no medium is specified, an email is sent with the default url. + oneof medium { + // Let ZITADEL send the link to the user via email. + SendPasswordResetEmail send_email = 2; + // Let ZITADEL send the link to the user via SMS. + SendPasswordResetSMS send_sms = 3; + // Get the code back to provide it to the user in your preferred mechanism. + ReturnPasswordResetCode return_code = 4; + } +} + +message RequestPasswordResetResponse { + zitadel.object.v2beta.Details details = 1; + // In case the medium was set to return_code, the code will be returned. + optional string verification_code = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"SKJd342k\""; + } + ]; +} + +message StartWebAuthNRegistrationRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // Domain on which the user currently is or will be authenticated. + string domain = 4 [ + (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: "\"my-domain.zitadel.cloud\""; + } + ]; + // Optionally specify the authenticator type of the passkey device (platform or cross-platform). + // If none is provided, both values are allowed. + WebAuthNAuthenticatorType authenticator_type = 3; + // Optionally provide a one time code generated by ZITADEL. + // This is required to start the passkey registration without user authentication. + optional AuthenticatorRegistrationCode code = 2; +} + +message StartWebAuthNRegistrationResponse { + zitadel.object.v2beta.Details details = 1; + // unique identifier of the WebAuthN registration. + string web_auth_n_id = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"163840776835432705\"" + } + ]; + // Options for Credential Creation (dictionary PublicKeyCredentialCreationOptions). + // Generated helper methods transform the field to JSON, for use in a WebauthN client. + // See also: https://www.w3.org/TR/webauthn/#dictdef-publickeycredentialcreationoptions + google.protobuf.Struct public_key_credential_creation_options = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "{\"publicKey\":{\"attestation\":\"none\",\"authenticatorSelection\":{\"userVerification\":\"required\"},\"challenge\":\"XaMYwWOZ5hj6pwtwJJlpcI-ExkO5TxevBMG4R8DoKQQ\",\"excludeCredentials\":[{\"id\":\"tVp1QfYhT8DkyEHVrv7blnpAo2YJzbZgZNBf7zPs6CI\",\"type\":\"public-key\"}],\"pubKeyCredParams\":[{\"alg\":-7,\"type\":\"public-key\"}],\"rp\":{\"id\":\"localhost\",\"name\":\"ZITADEL\"},\"timeout\":300000,\"user\":{\"displayName\":\"Tim Mohlmann\",\"id\":\"MjE1NTk4MDAwNDY0OTk4OTQw\",\"name\":\"tim\"}}}" + } + ]; +} + +message VerifyWebAuthNRegistrationRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the WebAuthN registration, which was returned in the start webauthn registration. + string web_auth_n_id = 2 [ + (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: "\"163840776835432705\""; + } + ]; + // PublicKeyCredential Interface. + // Generated helper methods populate the field from JSON created by a WebAuthN client. + // See also: https://www.w3.org/TR/webauthn/#publickeycredential + google.protobuf.Struct public_key_credential = 3 [ + (validate.rules).message.required = true, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "{\"type\":\"public-key\",\"id\":\"pawVarF4xPxLFmfCnRkwXWeTrKGzabcAi92LEI1WC00\",\"rawId\":\"pawVarF4xPxLFmfCnRkwXWeTrKGzabcAi92LEI1WC00\",\"response\":{\"attestationObject\":\"o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZyZjc2lnWEcwRQIgRKS3VpeE9tfExXRzkoUKnG4rQWPvtSSt4YtDGgTx32oCIQDPey-2YJ4uIg-QCM4jj6aE2U3tgMFM_RP7Efx6xRu3JGhhdXRoRGF0YVikSZYN5YgOjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NFAAAAADju76085Yhmlt1CEOHkwLQAIKWsFWqxeMT8SxZnwp0ZMF1nk6yhs2m3AIvdixCNVgtNpQECAyYgASFYIMGUDSP2FAQn2MIfPMy7cyB_Y30VqixVgGULTBtFjfRiIlggjUGfQo3_-CrMmH3S-ZQkFKWKnNBQEAMkFtG-9A4zqW0\",\"clientDataJSON\":\"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoiQlhXdHh0WGxJeFZZa0pHT1dVaUVmM25zby02aXZKdWw2YmNmWHdMVlFIayIsIm9yaWdpbiI6Imh0dHBzOi8vbG9jYWxob3N0OjgwODAifQ\"}}"; + min_length: 55; + max_length: 1048576; //1 MB + } + ]; + // Provide a name for the WebAuthN device. This will help identify it in the future. + string web_auth_n_name = 4 [ + (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: "\"fido key\"" + } + ]; +} + +message VerifyWebAuthNRegistrationResponse { + zitadel.object.v2beta.Details details = 1; +} + +message CreateWebAuthNRegistrationLinkRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // if no medium is specified, an email is sent with the default url. + oneof medium { + // Let ZITADEL send the link to the user via email. + SendWebAuthNRegistrationLink send_link = 2; + // Get the code back to provide it to the user in your preferred mechanism. + ReturnWebAuthNRegistrationCode return_code = 3; + } +} + +message CreateWebAuthNRegistrationLinkResponse { + zitadel.object.v2beta.Details details = 1; + // In case the medium was set to return_code, the code will be returned. + optional AuthenticatorRegistrationCode code = 2; +} + +message RemoveWebAuthNAuthenticatorRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the WebAuthN authenticator. + string web_auth_n_id = 2 [ + (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: "\"163840776835432705\""; + } + ]; +} + +message RemoveWebAuthNAuthenticatorResponse { + zitadel.object.v2beta.Details details = 1; +} + +message StartTOTPRegistrationRequest { + // unique identifier of the user. + string user_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 StartTOTPRegistrationResponse { + zitadel.object.v2beta.Details details = 1; + // unique identifier of the TOTP registration. + string totp_id = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"163840776835432705\""; + } + ]; + // The TOTP URI, which can be used to create a QR Code for scanning with an authenticator app. + string uri = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"otpauth://totp/ZITADEL:gigi@acme.zitadel.cloud?algorithm=SHA1&digits=6&issuer=ZITADEL&period=30&secret=TJOPWSDYILLHXFV4MLKNNJOWFG7VSDCK\""; + } + ]; + // The TOTP secret, which can be used for manually adding in an authenticator app. + string secret = 4 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"TJOPWSDYILLHXFV4MLKNNJOWFG7VSDCK\""; + } + ]; +} + +message VerifyTOTPRegistrationRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the TOTP registration, which was returned in the start TOTP registration. + string totp_id = 2 [ + (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: "\"163840776835432705\""; + } + ]; + // Code generated by TOTP app or device. + string code = 3 [ + (validate.rules).string = {min_len: 6, max_len: 9}, + (google.api.field_behavior) = REQUIRED, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + min_length: 6, + max_length: 9, + example: "\"123456\""; + } + ]; +} + +message VerifyTOTPRegistrationResponse { + zitadel.object.v2beta.Details details = 1; +} + +message RemoveTOTPAuthenticatorRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the TOTP authenticator. + string totp_id = 2 [ + (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: "\"163840776835432705\""; + } + ]; +} + +message RemoveTOTPAuthenticatorResponse { + zitadel.object.v2beta.Details details = 1; +} + +message AddOTPSMSAuthenticatorRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // Set the user's phone for the OTP SMS authenticator and it's verification state. + SetPhone phone = 2; +} + +message AddOTPSMSAuthenticatorResponse { + zitadel.object.v2beta.Details details = 1; + // unique identifier of the OTP SMS registration. + string otp_sms_id = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"163840776835432705\""; + } + ]; + // The OTP verification code will be set if a phone was set with a return_code verification option. + optional string verification_code = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"SKJd342k\""; + } + ]; + +} + +message VerifyOTPSMSRegistrationRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the OTP SMS registration, which was returned in the add OTP SMS. + string otp_sms_id = 2 [ + (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: "\"163840776835432705\""; + } + ]; + // Set the verification code generated during the add OTP SMS request. + string code = 3 [ + (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: "\"SKJd342k\""; + } + ]; +} + +message VerifyOTPSMSRegistrationResponse { + zitadel.object.v2beta.Details details = 1; +} + +message RemoveOTPSMSAuthenticatorRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the OTP SMS authenticator. + string otp_sms_id = 2 [ + (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: "\"163840776835432705\""; + } + ]; +} + +message RemoveOTPSMSAuthenticatorResponse { + zitadel.object.v2beta.Details details = 1; +} + +message AddOTPEmailAuthenticatorRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // Set the user's email for the OTP Email authenticator and it's verification state. + SetEmail email = 2; +} + +message AddOTPEmailAuthenticatorResponse { + zitadel.object.v2beta.Details details = 1; + // unique identifier of the OTP Email registration. + string otp_email_id = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"163840776835432705\""; + } + ]; + // The OTP verification code will be set if a email was set with a return_code verification option. + optional string verification_code = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"SKJd342k\""; + } + ]; +} + +message VerifyOTPEmailRegistrationRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the OTP Email registration, which was returned in the add OTP Email. + string otp_email_id = 2 [ + (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: "\"163840776835432705\""; + } + ]; + // Set the verification code generated during the add OTP Email request. + string code = 3 [ + (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: "\"SKJd342k\""; + } + ]; +} + +message VerifyOTPEmailRegistrationResponse { + zitadel.object.v2beta.Details details = 1; +} + +message RemoveOTPEmailAuthenticatorRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the OTP Email authenticator. + string otp_email_id = 2 [ + (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: "\"163840776835432705\""; + } + ]; +} + +message RemoveOTPEmailAuthenticatorResponse { + zitadel.object.v2beta.Details details = 1; +} + +message StartIdentityProviderIntentRequest { + // ID of an existing identity provider (IDP). + string idp_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: "\"163840776835432705\""; + } + ]; + + oneof content { + RedirectURLs urls = 2; + LDAPCredentials ldap = 3; + } +} + +message StartIdentityProviderIntentResponse { + zitadel.object.v2beta.Details details = 1; + // the next step to take in the idp intent flow. + oneof next_step { + // The authentication URL to which the client should redirect. + string auth_url = 2 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"https://accounts.google.com/o/oauth2/v2/auth?client_id=clientID&callback=https%3A%2F%2Fzitadel.cloud%2Fidps%2Fcallback\""; + } + ]; + // The Start Intent directly succeeded and returned the IDP Intent. + // Further information can be retrieved by using the retrieve identity provider intent request. + IdentityProviderIntent idp_intent = 3; + // The HTML form with the embedded POST call information to render and execute. + bytes post_form = 4; + } +} + +message RetrieveIdentityProviderIntentRequest { + // ID of the identity provider (IDP) intent, previously returned on the success response of the start identity provider intent. + string idp_intent_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: "\"163840776835432705\""; + } + ]; + // Token of the identity provider (IDP) intent, previously returned on the success response of the start identity provider intent. + string idp_intent_token = 2 [ + (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: "\"SJKL3ioIDpo342ioqw98fjp3sdf32wahb=\""; + } + ]; +} + +message RetrieveIdentityProviderIntentResponse { + zitadel.object.v2beta.Details details = 1; + // Information returned by the identity provider (IDP) such as the identification of the user + // and detailed / profile information. + IDPInformation idp_information = 2; + // If the user was already federated and linked to a ZITADEL user, it's id will be returned. + optional string user_id = 3 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + example: "\"163840776835432345\""; + } + ]; +} + +message AddIDPAuthenticatorRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + IDPAuthenticator idp_authenticator = 2; +} + +message AddIDPAuthenticatorResponse { + zitadel.object.v2beta.Details details = 1; +} + +message RemoveIDPAuthenticatorRequest { + // unique identifier of the user. + string user_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\""; + } + ]; + // unique identifier of the identity provider (IDP) authenticator. + string idp_id = 2 [ + (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: "\"163840776835432705\""; + } + ]; +} + +message RemoveIDPAuthenticatorResponse { + zitadel.object.v2beta.Details details = 1; +} +