feat(api): move organization api (#11045)

# Which Problems Are Solved

As part of our efforts to simplify the structure and versions of our
APIs, were moving all existing v2beta endpoints to v2 and deprecate
them. They will be removed in Zitadel V5.

# How the Problems Are Solved

- This PR moves the remaining organization v2beta service endpoints to a
corresponding v2 version. The v2beta service and all endpoints are
deprecated.
- The v2beta endpoints are removed from the docs.
- The comments and have been improved and, where not already done, moved
from swagger annotations to proto.
- When listing Organizations can now be sorted by creation date as well.
- The custom `org_id` parameter in the `AddOrganizationRequest` message
has been deprecated in favor of `organization_id`

# Additional Changes

None

# Additional Context

- relates to #10772 
- Directly targeting v4.x since main needs to be cleaned up first with
the relation table and permission checks.
This commit is contained in:
Livio Spring
2025-11-13 08:43:38 +01:00
committed by GitHub
parent a20dbc4ac8
commit 6b407ab8f2
15 changed files with 2973 additions and 534 deletions

View File

@@ -522,7 +522,7 @@ func startAPIs(
if err := apis.RegisterService(ctx, settings_v2.CreateServer(commands, queries)); err != nil { if err := apis.RegisterService(ctx, settings_v2.CreateServer(commands, queries)); err != nil {
return nil, err return nil, err
} }
if err := apis.RegisterService(ctx, org_v2.CreateServer(commands, queries, permissionCheck)); err != nil { if err := apis.RegisterService(ctx, org_v2.CreateServer(config.SystemDefaults, commands, queries, permissionCheck)); err != nil {
return nil, err return nil, err
} }
if err := apis.RegisterService(ctx, feature_v2.CreateServer(commands, queries)); err != nil { if err := apis.RegisterService(ctx, feature_v2.CreateServer(commands, queries)); err != nil {

View File

@@ -366,7 +366,7 @@ module.exports = {
}, },
org_v2: { org_v2: {
specPath: specPath:
".artifacts/openapi/zitadel/org/v2/org_service.swagger.json", ".artifacts/openapi3/zitadel/org/v2/org_service.openapi.yaml",
outputDir: "docs/apis/resources/org_service_v2", outputDir: "docs/apis/resources/org_service_v2",
sidebarOptions: { sidebarOptions: {
groupPathsBy: "tag", groupPathsBy: "tag",
@@ -382,15 +382,6 @@ module.exports = {
categoryLinkSource: "auto", categoryLinkSource: "auto",
}, },
}, },
org_v2beta: {
specPath:
".artifacts/openapi3/zitadel/org/v2beta/org_service.openapi.yaml",
outputDir: "docs/apis/resources/org_service_v2beta",
sidebarOptions: {
groupPathsBy: "tag",
categoryLinkSource: "auto",
},
},
project_v2: { project_v2: {
specPath: specPath:
".artifacts/openapi3/zitadel/project/v2/project_service.openapi.yaml", ".artifacts/openapi3/zitadel/project/v2/project_service.openapi.yaml",

View File

@@ -11,7 +11,6 @@ const sidebar_api_saml_service_v2 = require("./docs/apis/resources/saml_service_
const sidebar_api_settings_service_v2 = require("./docs/apis/resources/settings_service_v2/sidebar.ts").default const sidebar_api_settings_service_v2 = require("./docs/apis/resources/settings_service_v2/sidebar.ts").default
const sidebar_api_feature_service_v2 = require("./docs/apis/resources/feature_service_v2/sidebar.ts").default const sidebar_api_feature_service_v2 = require("./docs/apis/resources/feature_service_v2/sidebar.ts").default
const sidebar_api_org_service_v2 = require("./docs/apis/resources/org_service_v2/sidebar.ts").default const sidebar_api_org_service_v2 = require("./docs/apis/resources/org_service_v2/sidebar.ts").default
const sidebar_api_org_service_v2beta = require("./docs/apis/resources/org_service_v2beta/sidebar.ts").default
const sidebar_api_idp_service_v2 = require("./docs/apis/resources/idp_service_v2/sidebar.ts").default const sidebar_api_idp_service_v2 = require("./docs/apis/resources/idp_service_v2/sidebar.ts").default
const sidebar_api_actions_v2 = require("./docs/apis/resources/action_service_v2/sidebar.ts").default const sidebar_api_actions_v2 = require("./docs/apis/resources/action_service_v2/sidebar.ts").default
const sidebar_api_project_service_v2 = require("./docs/apis/resources/project_service_v2/sidebar.ts").default const sidebar_api_project_service_v2 = require("./docs/apis/resources/project_service_v2/sidebar.ts").default
@@ -764,18 +763,6 @@ module.exports = {
}, },
items: sidebar_api_org_service_v2, items: sidebar_api_org_service_v2,
}, },
{
type: "category",
label: "Organization (Beta)",
link: {
type: "generated-index",
title: "Organization Service Beta API",
slug: "/apis/resources/org_service/v2beta",
description:
"This beta API is intended to manage organizations for ZITADEL. Expect breaking changes to occur. Please use the v2 version for a stable API. \n",
},
items: sidebar_api_org_service_v2beta,
},
{ {
type: "category", type: "category",
label: "Identity Provider", label: "Identity Provider",

View File

@@ -45,3 +45,40 @@ func UserMetadataFilterToQuery(filter *meta_pb.MetadataSearchFilter) (query.Sear
return nil, zerrors.ThrowInvalidArgument(nil, "METAD-fdg23", "List.Query.Invalid") return nil, zerrors.ThrowInvalidArgument(nil, "METAD-fdg23", "List.Query.Invalid")
} }
} }
func OrgMetadataListToPb(dataList []*query.OrgMetadata) []*meta_pb.Metadata {
mds := make([]*meta_pb.Metadata, len(dataList))
for i, data := range dataList {
mds[i] = OrgMetadataToPb(data)
}
return mds
}
func OrgMetadataToPb(data *query.OrgMetadata) *meta_pb.Metadata {
return &meta_pb.Metadata{
Key: data.Key,
Value: data.Value,
CreationDate: timestamppb.New(data.CreationDate),
ChangeDate: timestamppb.New(data.ChangeDate),
}
}
func OrgMetadataQueriesToQuery(queries []*meta_pb.MetadataSearchFilter) (_ []query.SearchQuery, err error) {
q := make([]query.SearchQuery, len(queries))
for i, query := range queries {
q[i], err = OrgMetadataFilterToQuery(query)
if err != nil {
return nil, err
}
}
return q, nil
}
func OrgMetadataFilterToQuery(filter *meta_pb.MetadataSearchFilter) (query.SearchQuery, error) {
switch q := filter.Filter.(type) {
case *meta_pb.MetadataSearchFilter_KeyFilter:
return query.NewOrgMetadataKeySearchQuery(q.KeyFilter.Key, filter_v2.TextMethodPbToQuery(q.KeyFilter.Method))
default:
return nil, zerrors.ThrowInvalidArgument(nil, "METAD-fdg23", "List.Query.Invalid")
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -4,10 +4,13 @@ import (
"context" "context"
"connectrpc.com/connect" "connectrpc.com/connect"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/api/grpc/object/v2"
"github.com/zitadel/zitadel/internal/api/grpc/user/v2" "github.com/zitadel/zitadel/internal/api/grpc/user/v2"
"github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
"github.com/zitadel/zitadel/internal/zerrors" "github.com/zitadel/zitadel/internal/zerrors"
"github.com/zitadel/zitadel/pkg/grpc/org/v2" "github.com/zitadel/zitadel/pkg/grpc/org/v2"
) )
@@ -24,6 +27,116 @@ func (s *Server) AddOrganization(ctx context.Context, request *connect.Request[o
return createdOrganizationToPb(createdOrg) return createdOrganizationToPb(createdOrg)
} }
func (s *Server) UpdateOrganization(ctx context.Context, request *connect.Request[org.UpdateOrganizationRequest]) (*connect.Response[org.UpdateOrganizationResponse], error) {
organization, err := s.command.ChangeOrg(ctx, request.Msg.GetOrganizationId(), request.Msg.GetName(), s.command.CheckPermissionOrganizationWrite)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.UpdateOrganizationResponse{
ChangeDate: timestamppb.New(organization.EventDate),
}), nil
}
func (s *Server) DeleteOrganization(ctx context.Context, request *connect.Request[org.DeleteOrganizationRequest]) (*connect.Response[org.DeleteOrganizationResponse], error) {
details, err := s.command.RemoveOrg(ctx, request.Msg.GetOrganizationId(), s.command.CheckPermissionOrganizationDelete, false)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.DeleteOrganizationResponse{
DeletionDate: timestamppb.New(details.EventDate),
}), nil
}
func (s *Server) SetOrganizationMetadata(ctx context.Context, request *connect.Request[org.SetOrganizationMetadataRequest]) (*connect.Response[org.SetOrganizationMetadataResponse], error) {
result, err := s.command.BulkSetOrgMetadata(ctx, request.Msg.GetOrganizationId(), s.command.CheckPermissionOrganizationWrite, bulkSetOrgMetadataToDomain(request.Msg)...)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.SetOrganizationMetadataResponse{
SetDate: timestamppb.New(result.EventDate),
}), nil
}
func (s *Server) DeleteOrganizationMetadata(ctx context.Context, request *connect.Request[org.DeleteOrganizationMetadataRequest]) (*connect.Response[org.DeleteOrganizationMetadataResponse], error) {
result, err := s.command.BulkRemoveOrgMetadata(ctx, request.Msg.GetOrganizationId(), s.command.CheckPermissionOrganizationWrite, request.Msg.Keys...)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.DeleteOrganizationMetadataResponse{
DeletionDate: timestamppb.New(result.EventDate),
}), nil
}
func (s *Server) DeactivateOrganization(ctx context.Context, request *connect.Request[org.DeactivateOrganizationRequest]) (*connect.Response[org.DeactivateOrganizationResponse], error) {
objectDetails, err := s.command.DeactivateOrg(ctx, request.Msg.GetOrganizationId(), s.command.CheckPermissionOrganizationWrite)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.DeactivateOrganizationResponse{
ChangeDate: timestamppb.New(objectDetails.EventDate),
}), nil
}
func (s *Server) ActivateOrganization(ctx context.Context, request *connect.Request[org.ActivateOrganizationRequest]) (*connect.Response[org.ActivateOrganizationResponse], error) {
objectDetails, err := s.command.ReactivateOrg(ctx, request.Msg.GetOrganizationId(), s.command.CheckPermissionOrganizationWrite)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.ActivateOrganizationResponse{
ChangeDate: timestamppb.New(objectDetails.EventDate),
}), err
}
func (s *Server) AddOrganizationDomain(ctx context.Context, request *connect.Request[org.AddOrganizationDomainRequest]) (*connect.Response[org.AddOrganizationDomainResponse], error) {
userIDs, err := s.getClaimedUserIDsOfOrgDomain(ctx, request.Msg.GetDomain(), request.Msg.GetOrganizationId())
if err != nil {
return nil, err
}
details, err := s.command.AddOrgDomain(ctx, request.Msg.GetOrganizationId(), request.Msg.GetDomain(), userIDs, s.command.CheckPermissionOrganizationWrite)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.AddOrganizationDomainResponse{
CreationDate: timestamppb.New(details.EventDate),
}), nil
}
func (s *Server) DeleteOrganizationDomain(ctx context.Context, req *connect.Request[org.DeleteOrganizationDomainRequest]) (*connect.Response[org.DeleteOrganizationDomainResponse], error) {
details, err := s.command.RemoveOrgDomain(ctx, removeOrgDomainRequestToDomain(req.Msg), s.command.CheckPermissionOrganizationWrite)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.DeleteOrganizationDomainResponse{
DeletionDate: timestamppb.New(details.EventDate),
}), err
}
func (s *Server) GenerateOrganizationDomainValidation(ctx context.Context, req *connect.Request[org.GenerateOrganizationDomainValidationRequest]) (*connect.Response[org.GenerateOrganizationDomainValidationResponse], error) {
token, url, err := s.command.GenerateOrgDomainValidation(ctx, generateOrgDomainValidationRequestToDomain(req.Msg), s.command.CheckPermissionOrganizationWrite)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.GenerateOrganizationDomainValidationResponse{
Token: token,
Url: url,
}), nil
}
func (s *Server) VerifyOrganizationDomain(ctx context.Context, request *connect.Request[org.VerifyOrganizationDomainRequest]) (*connect.Response[org.VerifyOrganizationDomainResponse], error) {
userIDs, err := s.getClaimedUserIDsOfOrgDomain(ctx, request.Msg.GetDomain(), request.Msg.GetOrganizationId())
if err != nil {
return nil, err
}
details, err := s.command.ValidateOrgDomain(ctx, validateOrgDomainRequestToDomain(request.Msg), userIDs, s.command.CheckPermissionOrganizationWrite)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.VerifyOrganizationDomainResponse{
ChangeDate: timestamppb.New(details.EventDate),
}), nil
}
func addOrganizationRequestToCommand(request *org.AddOrganizationRequest) (*command.OrgSetup, error) { func addOrganizationRequestToCommand(request *org.AddOrganizationRequest) (*command.OrgSetup, error) {
admins, err := addOrganizationRequestAdminsToCommand(request.GetAdmins()) admins, err := addOrganizationRequestAdminsToCommand(request.GetAdmins())
if err != nil { if err != nil {
@@ -88,3 +201,59 @@ func createdOrganizationToPb(createdOrg *command.CreatedOrg) (_ *connect.Respons
CreatedAdmins: admins, CreatedAdmins: admins,
}), nil }), nil
} }
func (s *Server) getClaimedUserIDsOfOrgDomain(ctx context.Context, orgDomain, orgID string) ([]string, error) {
return s.query.SearchClaimedUserIDsOfOrgDomain(ctx, orgDomain, orgID)
}
func bulkSetOrgMetadataToDomain(req *org.SetOrganizationMetadataRequest) []*domain.Metadata {
metadata := make([]*domain.Metadata, len(req.Metadata))
for i, data := range req.Metadata {
metadata[i] = &domain.Metadata{
Key: data.Key,
Value: data.Value,
}
}
return metadata
}
func removeOrgDomainRequestToDomain(req *org.DeleteOrganizationDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: req.OrganizationId,
},
Domain: req.Domain,
}
}
func generateOrgDomainValidationRequestToDomain(req *org.GenerateOrganizationDomainValidationRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: req.OrganizationId,
},
Domain: req.Domain,
ValidationType: domainValidationTypeToDomain(req.Type),
}
}
func domainValidationTypeToDomain(validationType org.DomainValidationType) domain.OrgDomainValidationType {
switch validationType {
case org.DomainValidationType_DOMAIN_VALIDATION_TYPE_HTTP:
return domain.OrgDomainValidationTypeHTTP
case org.DomainValidationType_DOMAIN_VALIDATION_TYPE_DNS:
return domain.OrgDomainValidationTypeDNS
case org.DomainValidationType_DOMAIN_VALIDATION_TYPE_UNSPECIFIED:
return domain.OrgDomainValidationTypeUnspecified
default:
return domain.OrgDomainValidationTypeUnspecified
}
}
func validateOrgDomainRequestToDomain(req *org.VerifyOrganizationDomainRequest) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: models.ObjectRoot{
AggregateID: req.OrganizationId,
},
Domain: req.Domain,
}
}

View File

@@ -6,10 +6,14 @@ import (
"connectrpc.com/connect" "connectrpc.com/connect"
"github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/filter/v2"
"github.com/zitadel/zitadel/internal/api/grpc/metadata/v2"
"github.com/zitadel/zitadel/internal/api/grpc/object/v2" "github.com/zitadel/zitadel/internal/api/grpc/object/v2"
"github.com/zitadel/zitadel/internal/config/systemdefaults"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/internal/zerrors" "github.com/zitadel/zitadel/internal/zerrors"
filter_pb "github.com/zitadel/zitadel/pkg/grpc/filter/v2"
"github.com/zitadel/zitadel/pkg/grpc/org/v2" "github.com/zitadel/zitadel/pkg/grpc/org/v2"
) )
@@ -28,6 +32,81 @@ func (s *Server) ListOrganizations(ctx context.Context, req *connect.Request[org
}), nil }), nil
} }
func (s *Server) ListOrganizationMetadata(ctx context.Context, request *connect.Request[org.ListOrganizationMetadataRequest]) (*connect.Response[org.ListOrganizationMetadataResponse], error) {
metadataQueries, err := listOrgMetadataToDomain(s.systemDefaults, request.Msg)
if err != nil {
return nil, err
}
res, err := s.query.SearchOrgMetadata(ctx, true, request.Msg.GetOrganizationId(), metadataQueries, false, true)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.ListOrganizationMetadataResponse{
Metadata: metadata.OrgMetadataListToPb(res.Metadata),
Pagination: &filter_pb.PaginationResponse{
TotalResult: res.Count,
AppliedLimit: uint64(request.Msg.GetPagination().GetLimit()),
},
}), nil
}
func (s *Server) ListOrganizationDomains(ctx context.Context, req *connect.Request[org.ListOrganizationDomainsRequest]) (*connect.Response[org.ListOrganizationDomainsResponse], error) {
queries, err := listOrgDomainsRequestToDomain(s.systemDefaults, req.Msg)
if err != nil {
return nil, err
}
orgIDQuery, err := query.NewOrgDomainOrgIDSearchQuery(req.Msg.GetOrganizationId())
if err != nil {
return nil, err
}
queries.Queries = append(queries.Queries, orgIDQuery)
domains, err := s.query.SearchOrgDomains(ctx, queries, false, true)
if err != nil {
return nil, err
}
return connect.NewResponse(&org.ListOrganizationDomainsResponse{
Domains: domainsToPb(domains.Domains),
Pagination: &filter_pb.PaginationResponse{
TotalResult: domains.Count,
AppliedLimit: uint64(req.Msg.GetPagination().GetLimit()),
},
}), nil
}
func listOrgDomainsRequestToDomain(systemDefaults systemdefaults.SystemDefaults, request *org.ListOrganizationDomainsRequest) (*query.OrgDomainSearchQueries, error) {
offset, limit, asc, err := filter.PaginationPbToQuery(systemDefaults, request.Pagination)
if err != nil {
return nil, err
}
queries, err := DomainQueriesToModel(request.Filters)
if err != nil {
return nil, err
}
return &query.OrgDomainSearchQueries{
SearchRequest: query.SearchRequest{
Offset: offset,
Limit: limit,
Asc: asc,
SortingColumn: fieldNameToOrganizationDomainColumn(request.GetSortingColumn()),
},
Queries: queries,
}, nil
}
func fieldNameToOrganizationDomainColumn(column org.DomainFieldName) query.Column {
switch column {
case org.DomainFieldName_DOMAIN_FIELD_NAME_NAME:
return query.OrgDomainDomainCol
case org.DomainFieldName_DOMAIN_FIELD_NAME_CREATION_DATE:
return query.OrgDomainCreationDateCol
case org.DomainFieldName_DOMAIN_FIELD_NAME_UNSPECIFIED:
return query.Column{}
default:
return query.Column{}
}
}
func listOrgRequestToModel(ctx context.Context, req *connect.Request[org.ListOrganizationsRequest]) (*connect.Response[query.OrgSearchQueries], error) { func listOrgRequestToModel(ctx context.Context, req *connect.Request[org.ListOrganizationsRequest]) (*connect.Response[query.OrgSearchQueries], error) {
offset, limit, asc := object.ListQueryToQuery(req.Msg.Query) offset, limit, asc := object.ListQueryToQuery(req.Msg.Query)
queries, err := orgQueriesToQuery(ctx, req.Msg.Queries) queries, err := orgQueriesToQuery(ctx, req.Msg.Queries)
@@ -107,6 +186,8 @@ func fieldNameToOrganizationColumn(fieldName org.OrganizationFieldName) query.Co
switch fieldName { switch fieldName {
case org.OrganizationFieldName_ORGANIZATION_FIELD_NAME_NAME: case org.OrganizationFieldName_ORGANIZATION_FIELD_NAME_NAME:
return query.OrgColumnName return query.OrgColumnName
case org.OrganizationFieldName_ORGANIZATION_FIELD_NAME_CREATION_DATE:
return query.OrgColumnCreationDate
case org.OrganizationFieldName_ORGANIZATION_FIELD_NAME_UNSPECIFIED: case org.OrganizationFieldName_ORGANIZATION_FIELD_NAME_UNSPECIFIED:
return query.Column{} return query.Column{}
default: default:
@@ -136,3 +217,73 @@ func organizationToPb(organization *query.Org) *org.Organization {
State: orgStateToPb(organization.State), State: orgStateToPb(organization.State),
} }
} }
func listOrgMetadataToDomain(systemDefaults systemdefaults.SystemDefaults, request *org.ListOrganizationMetadataRequest) (*query.OrgMetadataSearchQueries, error) {
offset, limit, asc, err := filter.PaginationPbToQuery(systemDefaults, request.Pagination)
if err != nil {
return nil, err
}
queries, err := metadata.OrgMetadataQueriesToQuery(request.GetFilters())
if err != nil {
return nil, err
}
return &query.OrgMetadataSearchQueries{
SearchRequest: query.SearchRequest{
Offset: offset,
Limit: limit,
Asc: asc,
},
Queries: queries,
}, nil
}
func DomainQueriesToModel(queries []*org.DomainSearchFilter) (_ []query.SearchQuery, err error) {
q := make([]query.SearchQuery, len(queries))
for i, query := range queries {
q[i], err = DomainQueryToModel(query)
if err != nil {
return nil, err
}
}
return q, nil
}
func DomainQueryToModel(searchQuery *org.DomainSearchFilter) (query.SearchQuery, error) {
switch q := searchQuery.Filter.(type) {
case *org.DomainSearchFilter_DomainFilter:
return query.NewOrgDomainDomainSearchQuery(object.TextMethodToQuery(q.DomainFilter.Method), q.DomainFilter.GetDomain())
default:
return nil, zerrors.ThrowInvalidArgument(nil, "ORG-Ags89", "List.Query.Invalid")
}
}
func domainsToPb(domains []*query.Domain) []*org.Domain {
d := make([]*org.Domain, len(domains))
for i, domain := range domains {
d[i] = domainToPb(domain)
}
return d
}
func domainToPb(d *query.Domain) *org.Domain {
return &org.Domain{
OrganizationId: d.OrgID,
Domain: d.Domain,
IsVerified: d.IsVerified,
IsPrimary: d.IsPrimary,
ValidationType: domainValidationTypeToPb(d.ValidationType),
}
}
func domainValidationTypeToPb(validationType domain.OrgDomainValidationType) org.DomainValidationType {
switch validationType {
case domain.OrgDomainValidationTypeDNS:
return org.DomainValidationType_DOMAIN_VALIDATION_TYPE_DNS
case domain.OrgDomainValidationTypeHTTP:
return org.DomainValidationType_DOMAIN_VALIDATION_TYPE_HTTP
case domain.OrgDomainValidationTypeUnspecified:
return org.DomainValidationType_DOMAIN_VALIDATION_TYPE_UNSPECIFIED
default:
return org.DomainValidationType_DOMAIN_VALIDATION_TYPE_UNSPECIFIED
}
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/authz"
"github.com/zitadel/zitadel/internal/api/grpc/server" "github.com/zitadel/zitadel/internal/api/grpc/server"
"github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/command"
"github.com/zitadel/zitadel/internal/config/systemdefaults"
"github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/query" "github.com/zitadel/zitadel/internal/query"
"github.com/zitadel/zitadel/pkg/grpc/org/v2" "github.com/zitadel/zitadel/pkg/grpc/org/v2"
@@ -18,19 +19,20 @@ import (
var _ orgconnect.OrganizationServiceHandler = (*Server)(nil) var _ orgconnect.OrganizationServiceHandler = (*Server)(nil)
type Server struct { type Server struct {
systemDefaults systemdefaults.SystemDefaults
command *command.Commands command *command.Commands
query *query.Queries query *query.Queries
checkPermission domain.PermissionCheck checkPermission domain.PermissionCheck
} }
type Config struct{}
func CreateServer( func CreateServer(
systemDefaults systemdefaults.SystemDefaults,
command *command.Commands, command *command.Commands,
query *query.Queries, query *query.Queries,
checkPermission domain.PermissionCheck, checkPermission domain.PermissionCheck,
) *Server { ) *Server {
return &Server{ return &Server{
systemDefaults: systemDefaults,
command: command, command: command,
query: query, query: query,
checkPermission: checkPermission, checkPermission: checkPermission,

View File

@@ -1175,7 +1175,7 @@ service AdminService {
// Get Organization By ID // Get Organization By ID
// //
// Deprecated: use [organization service v2 ListOrganizations](apis/resources/org_service_v2/organization-service-list-organizations.api.mdx) instead. // Deprecated: use [organization service v2 ListOrganizations](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-list-organizations.api.mdx) instead.
// //
// Returns an organization by its ID. Make sure the user has the permissions to access the organization. // Returns an organization by its ID. Make sure the user has the permissions to access the organization.
rpc GetOrgByID(GetOrgByIDRequest) returns (GetOrgByIDResponse) { rpc GetOrgByID(GetOrgByIDRequest) returns (GetOrgByIDResponse) {
@@ -1201,7 +1201,7 @@ service AdminService {
// Is Organization Unique // Is Organization Unique
// //
// Deprecated: use [organization service v2 ListOrganizations](apis/resources/org_service_v2/organization-service-list-organizations.api.mdx) instead. // Deprecated: use [organization service v2 ListOrganizations](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-list-organizations.api.mdx) instead.
// //
// Checks if an organization with the searched parameters already exists or not. // Checks if an organization with the searched parameters already exists or not.
rpc IsOrgUnique(IsOrgUniqueRequest) returns (IsOrgUniqueResponse) { rpc IsOrgUnique(IsOrgUniqueRequest) returns (IsOrgUniqueResponse) {
@@ -1250,7 +1250,7 @@ service AdminService {
// Get Default Organization // Get Default Organization
// //
// Deprecated: use [organization service v2 ListOrganizations](apis/resources/org_service_v2/organization-service-list-organizations.api.mdx) instead. // Deprecated: use [organization service v2 ListOrganizations](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-list-organizations.api.mdx) instead.
// //
// Get the default organization of the ZITADEL instance. If no specific organization is given on the register form, a user will be registered to the default organization. // Get the default organization of the ZITADEL instance. If no specific organization is given on the register form, a user will be registered to the default organization.
rpc GetDefaultOrg(GetDefaultOrgRequest) returns (GetDefaultOrgResponse) { rpc GetDefaultOrg(GetDefaultOrgRequest) returns (GetDefaultOrgResponse) {
@@ -1271,7 +1271,7 @@ service AdminService {
// Search Organizations // Search Organizations
// //
// Deprecated: use [organization service v2 ListOrganizations](apis/resources/org_service_v2/organization-service-list-organizations.api.mdx) instead. // Deprecated: use [organization service v2 ListOrganizations](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-list-organizations.api.mdx) instead.
// //
// Returns a list of organizations that match the requesting filters. All filters are applied with an AND condition. // Returns a list of organizations that match the requesting filters. All filters are applied with an AND condition.
rpc ListOrgs(ListOrgsRequest) returns (ListOrgsResponse) { rpc ListOrgs(ListOrgsRequest) returns (ListOrgsResponse) {
@@ -1309,7 +1309,7 @@ service AdminService {
// Setup Organization // Setup Organization
// //
// Deprecated: use [organization service v2 CreateOrganization](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-create-organization.api.mdx) instead. // Deprecated: use [organization service v2 AddOrganization](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-add-organization.api.mdx) instead.
// //
// Create a new organization with an administrative user. If no specific roles are sent for the first user, the user will get the role ORG_OWNER. // Create a new organization with an administrative user. If no specific roles are sent for the first user, the user will get the role ORG_OWNER.
rpc SetUpOrg(SetUpOrgRequest) returns (SetUpOrgResponse) { rpc SetUpOrg(SetUpOrgRequest) returns (SetUpOrgResponse) {
@@ -1347,7 +1347,7 @@ service AdminService {
// Remove Organization // Remove Organization
// //
// Deprecated: use [organization service v2 DeleteOrganization](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-delete-organization.api.mdx) instead. // Deprecated: use [organization service v2 DeleteOrganization](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-delete-organization.api.mdx) instead.
// //
// Deletes the organization and all its resources (Users, Projects, Grants to and from the org). Users of this organization will not be able to log in. // Deletes the organization and all its resources (Users, Projects, Grants to and from the org). Users of this organization will not be able to log in.
rpc RemoveOrg(RemoveOrgRequest) returns (RemoveOrgResponse) { rpc RemoveOrg(RemoveOrgRequest) returns (RemoveOrgResponse) {

View File

@@ -2238,7 +2238,7 @@ service ManagementService {
// Get Organization By Domain // Get Organization By Domain
// //
// Deprecated: use [organization v2 service ListOrganizations](apis/resources/org_service_v2/organization-service-list-organizations.api.mdx) instead. // Deprecated: use [organization v2 service ListOrganizations](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-list-organizations.api.mdx) instead.
// //
// Search an organization by the domain, overall organizations. The domain must match exactly. // Search an organization by the domain, overall organizations. The domain must match exactly.
rpc GetOrgByDomainGlobal(GetOrgByDomainGlobalRequest) returns (GetOrgByDomainGlobalResponse) { rpc GetOrgByDomainGlobal(GetOrgByDomainGlobalRequest) returns (GetOrgByDomainGlobalResponse) {
@@ -2283,7 +2283,7 @@ service ManagementService {
// Create Organization // Create Organization
// //
// Deprecated: use [organization service v2 CreateOrganization](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-create-organization.api.mdx) instead // Deprecated: use [organization service v2 CreateOrganization](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-add-organization.api.mdx) instead
// //
// Create a new organization. Based on the given name a domain will be generated to be able to identify users within an organization. // Create a new organization. Based on the given name a domain will be generated to be able to identify users within an organization.
rpc AddOrg(AddOrgRequest) returns (AddOrgResponse) { rpc AddOrg(AddOrgRequest) returns (AddOrgResponse) {
@@ -2312,7 +2312,7 @@ service ManagementService {
// Update Organization // Update Organization
// //
// Deprecated: use [organization service v2 UpdateOrganization](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-update-organization.api.mdx) instead. // Deprecated: use [organization service v2 UpdateOrganization](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-update-organization.api.mdx) instead.
// //
// Change the name of the organization. // Change the name of the organization.
rpc UpdateOrg(UpdateOrgRequest) returns (UpdateOrgResponse) { rpc UpdateOrg(UpdateOrgRequest) returns (UpdateOrgResponse) {
@@ -2341,7 +2341,7 @@ service ManagementService {
// Deactivate Organization // Deactivate Organization
// //
// Deprecated: use [organization service v2 DeactivateOrganization](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-deactivate-organization.api.mdx) instead. // Deprecated: use [organization service v2 DeactivateOrganization](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-deactivate-organization.api.mdx) instead.
// //
// Sets the state of my organization to deactivated. Users of this organization will not be able to log in. // Sets the state of my organization to deactivated. Users of this organization will not be able to log in.
rpc DeactivateOrg(DeactivateOrgRequest) returns (DeactivateOrgResponse) { rpc DeactivateOrg(DeactivateOrgRequest) returns (DeactivateOrgResponse) {
@@ -2370,7 +2370,7 @@ service ManagementService {
// Reactivate Organization // Reactivate Organization
// //
// Deprecated: use [organization service v2 ActivateOrganization](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-activate-organization.api.mdx) instead. // Deprecated: use [organization service v2 ActivateOrganization](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-activate-organization.api.mdx) instead.
// //
// Set the state of my organization to active. The state of the organization has to be deactivated to perform the request. Users of this organization will be able to log in again. // Set the state of my organization to active. The state of the organization has to be deactivated to perform the request. Users of this organization will be able to log in again.
rpc ReactivateOrg(ReactivateOrgRequest) returns (ReactivateOrgResponse) { rpc ReactivateOrg(ReactivateOrgRequest) returns (ReactivateOrgResponse) {
@@ -2399,7 +2399,7 @@ service ManagementService {
// Delete Organization // Delete Organization
// //
// Deprecated: use [organization service v2 DeleteOrganization](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-delete-organization.api.mdx) instead. // Deprecated: use [organization service v2 DeleteOrganization](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-delete-organization.api.mdx) instead.
// //
// Deletes my organization and all its resources (Users, Projects, Grants to and from the org). Users of this organization will not be able to log in. // Deletes my organization and all its resources (Users, Projects, Grants to and from the org). Users of this organization will not be able to log in.
rpc RemoveOrg(RemoveOrgRequest) returns (RemoveOrgResponse) { rpc RemoveOrg(RemoveOrgRequest) returns (RemoveOrgResponse) {
@@ -2427,7 +2427,7 @@ service ManagementService {
// Set Organization Metadata // Set Organization Metadata
// //
// Deprecated: use [organization service v2 SetOrganizationMetadata](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-set-organization-metadata.api.mdx) instead. // Deprecated: use [organization service v2 SetOrganizationMetadata](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-set-organization-metadata.api.mdx) instead.
// //
// This endpoint either adds or updates a metadata value for the requested key. Make sure the value is base64 encoded. // This endpoint either adds or updates a metadata value for the requested key. Make sure the value is base64 encoded.
rpc SetOrgMetadata(SetOrgMetadataRequest) returns (SetOrgMetadataResponse) { rpc SetOrgMetadata(SetOrgMetadataRequest) returns (SetOrgMetadataResponse) {
@@ -2457,7 +2457,7 @@ service ManagementService {
// Bulk Set Organization Metadata // Bulk Set Organization Metadata
// //
// Deprecated: use [organization service v2 SetOrganizationMetadata](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-set-organization-metadata.api.mdx) instead. // Deprecated: use [organization service v2 SetOrganizationMetadata](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-set-organization-metadata.api.mdx) instead.
// //
// This endpoint sets a list of metadata to the organization. Make sure the values are base64 encoded. // This endpoint sets a list of metadata to the organization. Make sure the values are base64 encoded.
rpc BulkSetOrgMetadata(BulkSetOrgMetadataRequest) returns (BulkSetOrgMetadataResponse) { rpc BulkSetOrgMetadata(BulkSetOrgMetadataRequest) returns (BulkSetOrgMetadataResponse) {
@@ -2487,7 +2487,7 @@ service ManagementService {
// Search Organization Metadata // Search Organization Metadata
// //
// Deprecated: use [organization service v2 ListOrganizationMetadata](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-list-organization-metadata.api.mdx) instead. // Deprecated: use [organization service v2 ListOrganizationMetadata](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-list-organization-metadata.api.mdx) instead.
// //
// Get the metadata of an organization filtered by your query. // Get the metadata of an organization filtered by your query.
rpc ListOrgMetadata(ListOrgMetadataRequest) returns (ListOrgMetadataResponse) { rpc ListOrgMetadata(ListOrgMetadataRequest) returns (ListOrgMetadataResponse) {
@@ -2517,7 +2517,7 @@ service ManagementService {
// Get Organization Metadata By Key // Get Organization Metadata By Key
// //
// Deprecated: use [organization service v2 ListOrganizationMetadata](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-list-organization-metadata.api.mdx) instead. // Deprecated: use [organization service v2 ListOrganizationMetadata](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-list-organization-metadata.api.mdx) instead.
// //
// Get a metadata object from an organization by a specific key. // Get a metadata object from an organization by a specific key.
rpc GetOrgMetadata(GetOrgMetadataRequest) returns (GetOrgMetadataResponse) { rpc GetOrgMetadata(GetOrgMetadataRequest) returns (GetOrgMetadataResponse) {
@@ -2546,7 +2546,7 @@ service ManagementService {
// Delete Organization Metadata By Key // Delete Organization Metadata By Key
// //
// Deprecated: use [organization service v2 DeleteOrganizationMetadata](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-delete-organization-metadata.api.mdx) instead. // Deprecated: use [organization service v2 DeleteOrganizationMetadata](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-delete-organization-metadata.api.mdx) instead.
// //
// Remove a metadata object from an organization with a specific key. // Remove a metadata object from an organization with a specific key.
rpc RemoveOrgMetadata(RemoveOrgMetadataRequest) returns (RemoveOrgMetadataResponse) { rpc RemoveOrgMetadata(RemoveOrgMetadataRequest) returns (RemoveOrgMetadataResponse) {
@@ -2575,7 +2575,7 @@ service ManagementService {
// Bulk Delete Metadata // Bulk Delete Metadata
// //
// Deprecated: use [organization service v2 DeleteOrganizationMetadata](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-delete-organization-metadata.api.mdx) instead. // Deprecated: use [organization service v2 DeleteOrganizationMetadata](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-delete-organization-metadata.api.mdx) instead.
// //
// Remove a list of metadata objects from an organization with a list of keys. // Remove a list of metadata objects from an organization with a list of keys.
rpc BulkRemoveOrgMetadata(BulkRemoveOrgMetadataRequest) returns (BulkRemoveOrgMetadataResponse) { rpc BulkRemoveOrgMetadata(BulkRemoveOrgMetadataRequest) returns (BulkRemoveOrgMetadataResponse) {
@@ -2605,7 +2605,7 @@ service ManagementService {
// Add Domain // Add Domain
// //
// Deprecated: use [organization service v2 AddOrganizationDomain](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-add-organization-domain.api.mdx) instead. // Deprecated: use [organization service v2 AddOrganizationDomain](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-add-organization-domain.api.mdx) instead.
// //
// Add a new domain to an organization. The domains are used to identify to which organization a user belongs. // Add a new domain to an organization. The domains are used to identify to which organization a user belongs.
rpc AddOrgDomain(AddOrgDomainRequest) returns (AddOrgDomainResponse) { rpc AddOrgDomain(AddOrgDomainRequest) returns (AddOrgDomainResponse) {
@@ -2634,7 +2634,7 @@ service ManagementService {
// Search Domains // Search Domains
// //
// Deprecated: use [organization service v2 ListOrganizationDomains](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-list-organization-domains.api.mdx) instead. // Deprecated: use [organization service v2 ListOrganizationDomains](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-list-organization-domains.api.mdx) instead.
// //
// Returns the list of registered domains of an organization. The domains are used to identify to which organization a user belongs. // Returns the list of registered domains of an organization. The domains are used to identify to which organization a user belongs.
rpc ListOrgDomains(ListOrgDomainsRequest) returns (ListOrgDomainsResponse) { rpc ListOrgDomains(ListOrgDomainsRequest) returns (ListOrgDomainsResponse) {
@@ -2663,7 +2663,7 @@ service ManagementService {
// Remove Domain // Remove Domain
// //
// Deprecated: use [organization service v2 DeleteOrganizationDomain](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-delete-organization-domain.api.mdx) instead. // Deprecated: use [organization service v2 DeleteOrganizationDomain](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-delete-organization-domain.api.mdx) instead.
// //
// Delete a new domain from an organization. The domains are used to identify to which organization a user belongs. If the uses use the domain for login, this will not be possible afterwards. They have to use another domain instead. // Delete a new domain from an organization. The domains are used to identify to which organization a user belongs. If the uses use the domain for login, this will not be possible afterwards. They have to use another domain instead.
rpc RemoveOrgDomain(RemoveOrgDomainRequest) returns (RemoveOrgDomainResponse) { rpc RemoveOrgDomain(RemoveOrgDomainRequest) returns (RemoveOrgDomainResponse) {
@@ -2691,7 +2691,7 @@ service ManagementService {
// Generate Domain Verification // Generate Domain Verification
// //
// Deprecated: use [organization service v2 GenerateOrganizationDomainValidation](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-generate-organization-domain-validation.api.mdx) instead. // Deprecated: use [organization service v2 GenerateOrganizationDomainValidation](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-generate-organization-domain-validation.api.mdx) instead.
// //
// Generate a new file to be able to verify your domain with DNS or HTTP challenge. // Generate a new file to be able to verify your domain with DNS or HTTP challenge.
rpc GenerateOrgDomainValidation(GenerateOrgDomainValidationRequest) returns (GenerateOrgDomainValidationResponse) { rpc GenerateOrgDomainValidation(GenerateOrgDomainValidationRequest) returns (GenerateOrgDomainValidationResponse) {
@@ -2720,7 +2720,7 @@ service ManagementService {
// Verify Domain // Verify Domain
// //
// Deprecated: use [organization service v2 VerifyOrganizationDomain](apis/resources/org_service_v2beta/zitadel-org-v-2-beta-organization-service-verify-organization-domain.api.mdx) instead. // Deprecated: use [organization service v2 VerifyOrganizationDomain](apis/resources/org_service_v2/zitadel-org-v-2-organization-service-verify-organization-domain.api.mdx) instead.
// //
// Make sure you have added the required verification to your domain, depending on the method you have chosen (HTTP or DNS challenge). ZITADEL will check it and set the domain as verified if it was successful. A verify domain has to be unique. // Make sure you have added the required verification to your domain, depending on the method you have chosen (HTTP or DNS challenge). ZITADEL will check it and set the domain as verified if it was successful. A verify domain has to be unique.
rpc ValidateOrgDomain(ValidateOrgDomainRequest) returns (ValidateOrgDomainResponse) { rpc ValidateOrgDomain(ValidateOrgDomainRequest) returns (ValidateOrgDomainResponse) {

View File

@@ -12,21 +12,26 @@ import "zitadel/object/v2/object.proto";
message Organization { message Organization {
// Unique identifier of the organization. // ID is the unique identifier of the organization.
string id = 1 [ string id = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"69629023906488334\"" example: "\"69629023906488334\""
} }
]; ];
// Details about the organizations' creation and change date.
zitadel.object.v2.Details details = 2; zitadel.object.v2.Details details = 2;
// Current state of the organization, for example active, inactive and deleted.
// Current state of the organization, for example active, inactive or deleted.
OrganizationState state = 3; OrganizationState state = 3;
// Name of the organization. // Name of the organization.
string name = 4 [ string name = 4 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"ZITADEL\""; example: "\"ZITADEL\"";
} }
]; ];
// Primary domain used in the organization. // Primary domain used in the organization.
string primary_domain = 5 [ string primary_domain = 5 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@@ -40,4 +45,39 @@ enum OrganizationState {
ORGANIZATION_STATE_ACTIVE = 1; ORGANIZATION_STATE_ACTIVE = 1;
ORGANIZATION_STATE_INACTIVE = 2; ORGANIZATION_STATE_INACTIVE = 2;
ORGANIZATION_STATE_REMOVED = 3; ORGANIZATION_STATE_REMOVED = 3;
} }
enum DomainValidationType {
DOMAIN_VALIDATION_TYPE_UNSPECIFIED = 0;
// HTTP validation requires you to host a specific file on your domain.
// This file is checked by us to verify that you own the domain.
DOMAIN_VALIDATION_TYPE_HTTP = 1;
// DNS validation requires you to create a specific TXT record in your domain's DNS settings.
// This record is checked by us to verify that you own the domain.
DOMAIN_VALIDATION_TYPE_DNS = 2;
}
message Domain {
// OrganizationID is the unique identifier of the organization the domain belongs to.
string organization_id = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"69629023906488334\""
}
];
// Domain is the fully qualified domain name.
string domain = 2 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"zitadel.com\"";
}
];
// IsVerified is a boolean flag indicating if the domain has been verified.
bool is_verified = 3;
// IsPrimary is a boolean flag indicating if the domain is the primary domain of the organization.
bool is_primary = 4;
// ValidationType indicates the protocol used to validate the domain ownership.
DomainValidationType validation_type = 5;
}

View File

@@ -14,11 +14,14 @@ import "zitadel/user/v2/user_service.proto";
import "google/api/annotations.proto"; import "google/api/annotations.proto";
import "google/api/field_behavior.proto"; import "google/api/field_behavior.proto";
import "google/protobuf/duration.proto"; import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/struct.proto"; import "google/protobuf/struct.proto";
import "protoc-gen-openapiv2/options/annotations.proto"; import "protoc-gen-openapiv2/options/annotations.proto";
import "validate/validate.proto"; import "validate/validate.proto";
import "zitadel/org/v2/org.proto"; import "zitadel/org/v2/org.proto";
import "zitadel/org/v2/query.proto"; import "zitadel/org/v2/query.proto";
import "zitadel/filter/v2/filter.proto";
import "zitadel/metadata/v2/metadata.proto";
option go_package = "github.com/zitadel/zitadel/pkg/grpc/org/v2;org"; option go_package = "github.com/zitadel/zitadel/pkg/grpc/org/v2;org";
@@ -110,11 +113,15 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
} }
}; };
// This service is intended to manage organizations in a ZITADEL instance.
service OrganizationService { service OrganizationService {
// Create an Organization // Add Organization
// //
// Create a new organization with an administrative user. If no specific roles are sent for the users, they will be granted the role ORG_OWNER. // Create a new organization with an administrative user. If no specific roles are sent for the users, they will be granted the role ORG_OWNER.
//
// Required permission:
// - `org.create`
rpc AddOrganization(AddOrganizationRequest) returns (AddOrganizationResponse) { rpc AddOrganization(AddOrganizationRequest) returns (AddOrganizationResponse) {
option (google.api.http) = { option (google.api.http) = {
post: "/v2/organizations" post: "/v2/organizations"
@@ -140,9 +147,54 @@ service OrganizationService {
}; };
} }
// Search Organizations
// Update Organization
// //
// Search for Organizations. By default, we will return all organization of the instance. Make sure to include a limit and sorting for pagination.. // Change the name of the organization.
//
// Required permission:
// - `org.write`
rpc UpdateOrganization(UpdateOrganizationRequest) returns (UpdateOrganizationResponse) {
option (google.api.http) = {
post: "/v2/organizations/{organization_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: "Organization updated successfully";
};
};
responses: {
key: "404"
value: {
description: "Organisation's not found";
}
};
responses: {
key: "409"
value: {
description: "Organisation's name already taken";
}
};
};
}
// List Organizations
//
// Search for Organizations. By default, we will return all organization of the instance that you have permission to read.
// Make sure to include a limit and sorting for pagination.
//
// Required permission:
// - `org.read`
rpc ListOrganizations(ListOrganizationsRequest) returns (ListOrganizationsResponse) { rpc ListOrganizations(ListOrganizationsRequest) returns (ListOrganizationsResponse) {
option (google.api.http) = { option (google.api.http) = {
post: "/v2/organizations/_search"; post: "/v2/organizations/_search";
@@ -175,6 +227,311 @@ service OrganizationService {
}; };
}; };
} }
// Delete Organization
//
// Deletes the organization and all its resources (Users, Projects, Grants to and from the org). Users of this organization will not be able to log in.
//
// Required permission:
// - `org.delete`
rpc DeleteOrganization(DeleteOrganizationRequest) returns (DeleteOrganizationResponse) {
option (google.api.http) = {
delete: "/v2/organizations/{organization_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: "Organization created successfully";
};
};
responses: {
key: "404"
value: {
description: "Organisation's not found";
}
};
};
}
// Set Organization Metadata
//
// Adds or updates a metadata value for the requested key. Make sure the value is base64 encoded.
//
// Required permission:
// - `org.write`
rpc SetOrganizationMetadata(SetOrganizationMetadataRequest) returns (SetOrganizationMetadataResponse) {
option (google.api.http) = {
post: "/v2/organizations/{organization_id}/metadata"
body: "*"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
responses: {
key: "200";
};
responses: {
key: "400"
value: {
description: "Organisation's not found";
}
};
};
}
// List Organization Metadata
//
// List metadata of an organization filtered by query.
//
// Required permission:
// - `org.read`
rpc ListOrganizationMetadata(ListOrganizationMetadataRequest) returns (ListOrganizationMetadataResponse ) {
option (google.api.http) = {
post: "/v2/organizations/{organization_id}/metadata/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";
};
};
}
// Delete Organization Metadata
//
// Delete metadata objects from an organization with a specific key.
//
// Required permission:
// - `org.write`
rpc DeleteOrganizationMetadata(DeleteOrganizationMetadataRequest) returns (DeleteOrganizationMetadataResponse) {
option (google.api.http) = {
delete: "/v2/organizations/{organization_id}/metadata"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
responses: {
key: "200";
};
};
}
// Add Organization Domain
//
// Add a new domain to an organization. The domains are used to identify to which organization a user belongs.
//
// Required permission:
// - `org.write`
rpc AddOrganizationDomain(AddOrganizationDomainRequest) returns (AddOrganizationDomainResponse) {
option (google.api.http) = {
post: "/v2/organizations/{organization_id}/domains"
body: "*"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
responses: {
key: "200";
};
responses: {
key: "409"
value: {
description: "Domain already exists";
}
};
};
}
// List Organization Domains
//
// Returns the list of registered domains of an organization. The domains are used to identify to which organization a user belongs.
//
// Required permission:
// - `org.read`
rpc ListOrganizationDomains(ListOrganizationDomainsRequest) returns (ListOrganizationDomainsResponse) {
option (google.api.http) = {
post: "/v2/organizations/{organization_id}/domains/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";
};
};
}
// Delete Organization Domain
//
// Delete a new domain from an organization. The domains are used to identify to which organization a user belongs. If the uses use the domain for login, this will not be possible afterwards. They have to use another domain instead.
//
// Required permission:
// - `org.write`
rpc DeleteOrganizationDomain(DeleteOrganizationDomainRequest) returns (DeleteOrganizationDomainResponse) {
option (google.api.http) = {
delete: "/v2/organizations/{organization_id}/domains"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
responses: {
key: "200";
};
};
}
// Generate Organization Domain Validation
//
// Generate a new file to be able to verify your domain with DNS or HTTP challenge.
//
// Required permission:
// - `org.write`
rpc GenerateOrganizationDomainValidation(GenerateOrganizationDomainValidationRequest) returns (GenerateOrganizationDomainValidationResponse) {
option (google.api.http) = {
post: "/v2/organizations/{organization_id}/domains/validation/generate"
body: "*"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
responses: {
key: "200";
};
responses: {
key: "404"
value: {
description: "Domain doesn't exist on organization";
}
};
};
}
// Verify Organization Domain
//
// Make sure you have added the required verification to your domain, depending on the method you have chosen (HTTP or DNS challenge). ZITADEL will check it and set the domain as verified if it was successful. A verify domain has to be unique.
//
// Required permission:
// - `org.write`
rpc VerifyOrganizationDomain(VerifyOrganizationDomainRequest) returns (VerifyOrganizationDomainResponse) {
option (google.api.http) = {
post: "/v2/organizations/{organization_id}/domains/validation/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";
};
};
}
// Deactivate Organization
//
// Sets the state of my organization to deactivated. Users of this organization will not be able to log in.
//
// Required permission:
// - `org.write`
rpc DeactivateOrganization(DeactivateOrganizationRequest) returns (DeactivateOrganizationResponse) {
option (google.api.http) = {
post: "/v2/organizations/{organization_id}/deactivate"
body: "*"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
responses: {
key: "200";
};
};
}
// Activate Organization
//
// Set the state of my organization to active. The state of the organization has to be deactivated to perform the request. Users of this organization will be able to log in again.
//
// Required permission:
// - `org.write`
rpc ActivateOrganization(ActivateOrganizationRequest) returns (ActivateOrganizationResponse) {
option (google.api.http) = {
post: "/v2/organizations/{organization_id}/activate"
body: "*"
};
option (zitadel.protoc_gen_zitadel.v2.options) = {
auth_option: {
permission: "authenticated"
}
};
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
responses: {
key: "200";
};
};
}
} }
message AddOrganizationRequest{ message AddOrganizationRequest{
@@ -187,6 +544,8 @@ message AddOrganizationRequest{
repeated string roles = 3; repeated string roles = 3;
} }
// Name is the unique name of the organization to be created.
// This must be unique across the instance.
string name = 1 [ string name = 1 [
(validate.rules).string = {min_len: 1, max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED, (google.api.field_behavior) = REQUIRED,
@@ -196,9 +555,30 @@ message AddOrganizationRequest{
example: "\"ZITADEL\""; example: "\"ZITADEL\"";
} }
]; ];
// Specify users to be assigned as organization admins.
// If no users are specified here, the organization will be created without any admin users.
// The organization can still be managed by any instance administrator.
// If no roles are specified for a user, they will be assigned the role ORG_OWNER.
repeated Admin admins = 2; repeated Admin admins = 2;
// optionally set your own id unique for the organization.
// OrganizationID is the unique identifier of the organization. This field is optional.
// If omitted, the system will generate one,
// which is the recommended way. The generated ID will be returned in the response.
optional string organization_id = 4 [
(validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_length: 200;
example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\"";
}
];
// Optionally, set a unique id for the organization. If omitted, the system will generate one,
// which is the recommended way. The generated ID will be returned in the response.
//
// Deprecated: use 'organization_id' field instead.
optional string org_id = 3 [ optional string org_id = 3 [
deprecated = true,
(validate.rules).string = {min_len: 1, max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
max_length: 200; max_length: 200;
@@ -218,17 +598,403 @@ message AddOrganizationResponse{
repeated CreatedAdmin created_admins = 3; repeated CreatedAdmin created_admins = 3;
} }
message UpdateOrganizationRequest {
// OrganizationID is the unique identifier of the organization to be updated.
string organization_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: "\"69629012906488334\"";
}
];
// Name is the new name for the organization to be set.
// Note that since the name is used to generate the organization's default domain,
// changing the name will also change the domain.
// Additionally, if the domain is used as suffix for user logins,
// their login names will also change accordingly.
// It will not affect any custom domains added to the organization.
string name = 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: "\"Customer 1\"";
}
];
}
message UpdateOrganizationResponse {
// ChangeDate is the timestamp of the update to the organization.
google.protobuf.Timestamp change_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2025-01-23T10:34:18.051Z\"";
}
];
}
message ListOrganizationsRequest { message ListOrganizationsRequest {
//list limitations and ordering //list limitations and ordering
zitadel.object.v2.ListQuery query = 1; zitadel.object.v2.ListQuery query = 1;
// the field the result is sorted // the field the result is sorted
zitadel.org.v2.OrganizationFieldName sorting_column = 2; zitadel.org.v2.OrganizationFieldName sorting_column = 2;
//criteria the client is looking for
// criteria the client is looking for
repeated zitadel.org.v2.SearchQuery queries = 3; repeated zitadel.org.v2.SearchQuery queries = 3;
} }
message ListOrganizationsResponse { message ListOrganizationsResponse {
// Details of organizations results.
zitadel.object.v2.ListDetails details = 1; zitadel.object.v2.ListDetails details = 1;
// The sorting columns the result is sorted.
zitadel.org.v2.OrganizationFieldName sorting_column = 2; zitadel.org.v2.OrganizationFieldName sorting_column = 2;
// The Result is a list of organizations matching the query.
repeated zitadel.org.v2.Organization result = 3; repeated zitadel.org.v2.Organization result = 3;
} }
message DeleteOrganizationRequest {
// OrganizationID is the unique identifier of the organization to be deleted.
string organization_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"69629023906488334\"";
min_length: 1;
max_length: 200;
}
];
}
message DeleteOrganizationResponse {
// DeletionDate is the timestamp of the deletion of the organization.
google.protobuf.Timestamp deletion_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2025-01-23T10:34:18.051Z\"";
}
];
}
message DeactivateOrganizationRequest {
// OrganizationID is the unique identifier of the organization to be deactivated.
string organization_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"69629023906488334\"";
min_length: 1;
max_length: 200;
},
(google.api.field_behavior) = REQUIRED
];
}
message DeactivateOrganizationResponse {
// ChangeDate is the timestamp of the deactivation of the organization.
google.protobuf.Timestamp change_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2025-01-23T10:34:18.051Z\"";
}
];
}
message ActivateOrganizationRequest {
// OrganizationID is the unique identifier of the organization to be activated.
string organization_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"69629023906488334\"";
min_length: 1;
max_length: 200;
},
(google.api.field_behavior) = REQUIRED
];
}
message ActivateOrganizationResponse {
// ChangeDate is the timestamp of the activation of the organization.
google.protobuf.Timestamp change_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2025-01-23T10:34:18.051Z\"";
}
];
}
message AddOrganizationDomainRequest {
// OrganizationID is the unique identifier of the organization to which the domain is to be added.
string organization_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: "\"69629012906488334\"";
}
];
// Domain is the full qualified domain name to be added to the organization.
// Note that the domain has to be unique across the instance.
// Depending on the settings, you might have to verify the domain before it can be used.
string domain = 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: "\"testdomain.com\"";
}
];
}
message AddOrganizationDomainResponse {
// CreationDate is the timestamp when the organization domain was created.
google.protobuf.Timestamp creation_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2024-12-18T07:50:47.492Z\"";
}
];
}
message ListOrganizationDomainsRequest {
// OrganizationID is the unique identifier of the organization from which the domains are to be listed.
string organization_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: "\"69629012906488334\"";
}
];
// List limitations and ordering.
optional zitadel.filter.v2.PaginationRequest pagination = 2;
// Filters define the criteria to query for.
repeated DomainSearchFilter filters = 3;
// SortingColumn is the field the result is sorted by.
// Beware that if you change this, your result pagination might be inconsistent.
DomainFieldName sorting_column = 4;
}
message ListOrganizationDomainsResponse {
// Pagination of the organizations domain results.
zitadel.filter.v2.PaginationResponse pagination = 1;
// Domains is a list of fully qualified domain names registered to the organization matching the query.
repeated Domain domains = 2;
}
message DeleteOrganizationDomainRequest {
// OrganizationID is the unique identifier of the organization from which the domain is to be deleted.
string organization_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: "\"69629012906488334\"";
}
];
// Domain is the full qualified domain name to be deleted from the organization.
// Note that if the domain is used as suffix for user logins,
// those users will not be able to log in anymore. They have to use another domain instead.
// Also if the domain was used for domain discovery,
// users will not be able to find the organization by the domain anymore.
string domain = 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: "\"testdomain.com\"";
}
];
}
message DeleteOrganizationDomainResponse {
// DeletionDate is the timestamp of the deletion of the organization domain.
google.protobuf.Timestamp deletion_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2025-01-23T10:34:18.051Z\"";
}
];
}
message GenerateOrganizationDomainValidationRequest {
// OrganizationID is the unique identifier of the organization for which the domain validation is to be generated.
string organization_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: "\"69629012906488334\"";
}
];
// Domain is the full qualified domain name for which the validation is to be generated.
string domain = 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: "\"testdomain.com\"";
}
];
// Type is the domain validation type to be generated.
// Depending on the type, you will have to add a DNS record or a file to your webserver.
// Make sure that the challenge is reachable via the chosen method.
// The validation has to be done within one hour, otherwise the token will expire and you will have to generate a new one.
// After you have added the record or the file, you can verify the domain via the VerifyOrganizationDomain endpoint.
// You can check the status of the domain via the ListOrganizationDomains endpoint.
// The domain will be marked as verified after a successful verification.
DomainValidationType type = 3 [(validate.rules).enum = {defined_only: true, not_in: [0]}];
}
message GenerateOrganizationDomainValidationResponse {
// Token is a verification token that needs to be added to the DNS records or as a file to the webserver.
// Zitadel will check for this token to verify the domain.
string token = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"ofSBHsSAVHAoTIE4Iv2gwhaYhTjcY5QX\"";
}
];
// URL is the location where the token needs to be placed for HTTP challenge.
string url = 2 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"https://testdomain.com/.well-known/zitadel-challenge/ofSBHsSAVHAoTIE4Iv2gwhaYhTjcY5QX\"";
}
];
}
message VerifyOrganizationDomainRequest {
// Organization ID is the unique identifier of the organization whose domain is to be verified.
string organization_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: "\"69629012906488334\"";
}
];
// Domain is the full qualified domain name to be verified.
string domain = 2 [
(validate.rules).string = {min_len: 1, max_len: 253},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 253;
example: "\"testdomain.com\"";
}
];
}
message VerifyOrganizationDomainResponse {
// ChangeDate is the timestamp of the verification of the organization domain.
google.protobuf.Timestamp change_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2025-01-23T10:34:18.051Z\"";
}
];
}
message Metadata {
// Key is identifier of the metadata entry.
string key = 1 [(validate.rules).string = {min_len: 1, max_len: 200}];
// Value is the values of the metadata entry.
bytes value = 2 [(validate.rules).bytes = {min_len: 1, max_len: 500000}];
}
message SetOrganizationMetadataRequest{
// Organization ID is the unique identifier of the organization whose metadata is to be set.
string organization_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: "\"69629012906488334\"";
}
];
// Metadata is a list of metadata entries to set.
repeated Metadata metadata = 2 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "[{\"key\": \"test1\", \"value\": \"VGhpcyBpcyBteSBmaXJzdCB2YWx1ZQ==\"}, {\"key\": \"test2\", \"value\": \"VGhpcyBpcyBteSBzZWNvbmQgdmFsdWU=\"}]"
}
];
}
message SetOrganizationMetadataResponse{
// The timestamp of the update of the organization metadata.
google.protobuf.Timestamp set_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2025-01-23T10:34:18.051Z\"";
}
];
}
message ListOrganizationMetadataRequest {
// Organization ID is the unique identifier of the organization whose metadata is to be listed.
string organization_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: "\"69629012906488334\"";
}
];
// List limitations and ordering.
optional zitadel.filter.v2.PaginationRequest pagination = 2;
// Filters define the criteria to query the metadata for.
repeated zitadel.metadata.v2.MetadataSearchFilter filters = 3;
}
message ListOrganizationMetadataResponse {
// Pagination of the Organizations metadata results.
zitadel.filter.v2.PaginationResponse pagination = 1;
// Metadata is a list of organization metadata that matched the query.
repeated zitadel.metadata.v2.Metadata metadata = 2;
}
message DeleteOrganizationMetadataRequest {
// Organization ID is the unique identifier of the organization whose metadata is to be deleted.
string organization_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: "\"69629012906488334\"";
}
];
// Keys are the organization metadata entries to be deleted by their key.
repeated string keys = 2 [(validate.rules).repeated.items.string = {min_len: 1, max_len: 200}];
}
message DeleteOrganizationMetadataResponse{
// DeletionDate is the timestamp of the deletion of the organization metadata.
google.protobuf.Timestamp deletion_date = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
example: "\"2025-01-23T10:34:18.051Z\"";
}
];
}

View File

@@ -16,10 +16,19 @@ message SearchQuery {
oneof query { oneof query {
option (validate.required) = true; option (validate.required) = true;
// Filter organizations by their name.
OrganizationNameQuery name_query = 1; OrganizationNameQuery name_query = 1;
// Filter organizations by their domain.
OrganizationDomainQuery domain_query = 2; OrganizationDomainQuery domain_query = 2;
// Filter organizations by their state.
OrganizationStateQuery state_query = 3; OrganizationStateQuery state_query = 3;
// Filter organizations by their id.
OrganizationIDQuery id_query = 4; OrganizationIDQuery id_query = 4;
// Filter for the default organization.
DefaultOrganizationQuery default_query = 5; DefaultOrganizationQuery default_query = 5;
} }
} }
@@ -35,6 +44,7 @@ message OrganizationNameQuery {
example: "\"gigi-giraffe\""; example: "\"gigi-giraffe\"";
} }
]; ];
// Defines which text equality method is used. // Defines which text equality method is used.
zitadel.object.v2.TextQueryMethod method = 2 [ zitadel.object.v2.TextQueryMethod method = 2 [
(validate.rules).enum.defined_only = true (validate.rules).enum.defined_only = true
@@ -52,6 +62,7 @@ message OrganizationDomainQuery {
example: "\"citadel.cloud\""; example: "\"citadel.cloud\"";
} }
]; ];
// Defines which text equality method is used. // Defines which text equality method is used.
zitadel.object.v2.TextQueryMethod method = 2 [ zitadel.object.v2.TextQueryMethod method = 2 [
(validate.rules).enum.defined_only = true (validate.rules).enum.defined_only = true
@@ -81,6 +92,22 @@ message OrganizationIDQuery {
enum OrganizationFieldName { enum OrganizationFieldName {
ORGANIZATION_FIELD_NAME_UNSPECIFIED = 0; ORGANIZATION_FIELD_NAME_UNSPECIFIED = 0;
ORGANIZATION_FIELD_NAME_NAME = 1; ORGANIZATION_FIELD_NAME_NAME = 1;
ORGANIZATION_FIELD_NAME_CREATION_DATE = 2;
} }
message DefaultOrganizationQuery {} message DefaultOrganizationQuery {}
message DomainSearchFilter {
oneof filter {
option (validate.required) = true;
// Filter organization domains by their domain name.
OrganizationDomainQuery domain_filter = 1;
}
}
enum DomainFieldName {
DOMAIN_FIELD_NAME_UNSPECIFIED = 0;
DOMAIN_FIELD_NAME_NAME = 1;
DOMAIN_FIELD_NAME_CREATION_DATE = 2;
}

View File

@@ -107,6 +107,9 @@ option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
} }
}; };
// This service is intended to manage organizations in a ZITADEL instance.
//
// Deprecated: use organization service v2 instead. This service will be removed in the next major version of ZITADEL.
service OrganizationService { service OrganizationService {
// Create Organization // Create Organization
@@ -148,6 +151,8 @@ service OrganizationService {
// Update Organization // Update Organization
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Change the name of the organization. // Change the name of the organization.
// //
// Required permission: // Required permission:
@@ -189,6 +194,8 @@ service OrganizationService {
// List Organizations // List Organizations
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Returns a list of organizations that match the requesting filters. All filters are applied with an AND condition. // Returns a list of organizations that match the requesting filters. All filters are applied with an AND condition.
// //
// Required permission: // Required permission:
@@ -217,6 +224,8 @@ service OrganizationService {
// Delete Organization // Delete Organization
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Deletes the organization and all its resources (Users, Projects, Grants to and from the org). Users of this organization will not be able to log in. // Deletes the organization and all its resources (Users, Projects, Grants to and from the org). Users of this organization will not be able to log in.
// //
// Required permission: // Required permission:
@@ -250,6 +259,8 @@ service OrganizationService {
// Set Organization Metadata // Set Organization Metadata
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Adds or updates a metadata value for the requested key. Make sure the value is base64 encoded. // Adds or updates a metadata value for the requested key. Make sure the value is base64 encoded.
// //
// Required permission: // Required permission:
@@ -282,6 +293,8 @@ service OrganizationService {
// List Organization Metadata // List Organization Metadata
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// List metadata of an organization filtered by query. // List metadata of an organization filtered by query.
// //
// Required permission: // Required permission:
@@ -307,6 +320,8 @@ service OrganizationService {
// Delete Organization Metadata // Delete Organization Metadata
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Delete metadata objects from an organization with a specific key. // Delete metadata objects from an organization with a specific key.
// //
// Required permission: // Required permission:
@@ -332,6 +347,8 @@ service OrganizationService {
// Add Organization Domain // Add Organization Domain
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Add a new domain to an organization. The domains are used to identify to which organization a user belongs. // Add a new domain to an organization. The domains are used to identify to which organization a user belongs.
// //
// Required permission: // Required permission:
@@ -364,6 +381,8 @@ service OrganizationService {
// List Organization Domains // List Organization Domains
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Returns the list of registered domains of an organization. The domains are used to identify to which organization a user belongs. // Returns the list of registered domains of an organization. The domains are used to identify to which organization a user belongs.
// //
// Required permission: // Required permission:
@@ -390,6 +409,8 @@ service OrganizationService {
// Delete Organization Domain // Delete Organization Domain
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Delete a new domain from an organization. The domains are used to identify to which organization a user belongs. If the uses use the domain for login, this will not be possible afterwards. They have to use another domain instead. // Delete a new domain from an organization. The domains are used to identify to which organization a user belongs. If the uses use the domain for login, this will not be possible afterwards. They have to use another domain instead.
// //
// Required permission: // Required permission:
@@ -415,6 +436,8 @@ service OrganizationService {
// Generate Organization Domain Validation // Generate Organization Domain Validation
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Generate a new file to be able to verify your domain with DNS or HTTP challenge. // Generate a new file to be able to verify your domain with DNS or HTTP challenge.
// //
// Required permission: // Required permission:
@@ -446,6 +469,8 @@ service OrganizationService {
// Verify Organization Domain // Verify Organization Domain
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Make sure you have added the required verification to your domain, depending on the method you have chosen (HTTP or DNS challenge). ZITADEL will check it and set the domain as verified if it was successful. A verify domain has to be unique. // Make sure you have added the required verification to your domain, depending on the method you have chosen (HTTP or DNS challenge). ZITADEL will check it and set the domain as verified if it was successful. A verify domain has to be unique.
// //
// Required permission: // Required permission:
@@ -471,6 +496,8 @@ service OrganizationService {
// Deactivate Organization // Deactivate Organization
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Sets the state of my organization to deactivated. Users of this organization will not be able to log in. // Sets the state of my organization to deactivated. Users of this organization will not be able to log in.
// //
// Required permission: // Required permission:
@@ -497,6 +524,8 @@ service OrganizationService {
// Activate Organization // Activate Organization
// //
// Deprecated: please move to the corresponding endpoint under organization service v2. This endpoint will be removed with the next major version of ZITADEL.
//
// Set the state of my organization to active. The state of the organization has to be deactivated to perform the request. Users of this organization will be able to log in again. // Set the state of my organization to active. The state of the organization has to be deactivated to perform the request. Users of this organization will be able to log in again.
// //
// Required permission: // Required permission: