diff --git a/buf.gen.yaml b/buf.gen.yaml index eca5ada..7384dfd 100644 --- a/buf.gen.yaml +++ b/buf.gen.yaml @@ -11,7 +11,7 @@ plugins: out: "src" inputs: # NOTE: this references a variant of 1.41.0 that includes the protovalidate code. - - module: "buf.build/authzed/api:v1.53.0" + - module: "buf.build/authzed/api:v1.57.0" # NOTE: this brings in definitions that protovalidate-python depends on that may or may not # have been provided by the `include_imports` logic from the generation of our library. - module: "buf.build/bufbuild/protovalidate" diff --git a/src/authzed/api/materialize/v0/roaringlookupresources_pb2.py b/src/authzed/api/materialize/v0/roaringlookupresources_pb2.py new file mode 100644 index 0000000..741663f --- /dev/null +++ b/src/authzed/api/materialize/v0/roaringlookupresources_pb2.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# NO CHECKED-IN PROTOBUF GENCODE +# source: authzed/api/materialize/v0/roaringlookupresources.proto +# Protobuf Python Version: 5.28.3 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 5, + 28, + 3, + '', + 'authzed/api/materialize/v0/roaringlookupresources.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from authzed.api.v1 import core_pb2 as authzed_dot_api_dot_v1_dot_core__pb2 +from authzed.api.v1 import permission_service_pb2 as authzed_dot_api_dot_v1_dot_permission__service__pb2 +from buf.validate import validate_pb2 as buf_dot_validate_dot_validate__pb2 +from validate import validate_pb2 as validate_dot_validate__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n7authzed/api/materialize/v0/roaringlookupresources.proto\x12\x1a\x61uthzed.api.materialize.v0\x1a\x19\x61uthzed/api/v1/core.proto\x1a\'authzed/api/v1/permission_service.proto\x1a\x1b\x62uf/validate/validate.proto\x1a\x17validate/validate.proto\"\xec\x03\n)ExperimentalRoaringLookupResourcesRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12\xc3\x01\n\x14resource_object_type\x18\x02 \x01(\tB\x90\x01\xfa\x42\x45rC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaHErC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$R\x12resourceObjectType\x12n\n\npermission\x18\x03 \x01(\tBN\xfa\x42$r\"(@2\x1e^[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaH$r\"(@2\x1e^[a-z][a-z0-9_]{1,62}[a-z0-9]$R\npermission\x12J\n\x07subject\x18\x04 \x01(\x0b\x32 .authzed.api.v1.SubjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x07subject\"\xb1\x01\n*ExperimentalRoaringLookupResourcesResponse\x12\x16\n\x06\x62itmap\x18\x01 \x01(\x0cR\x06\x62itmap\x12 \n\x0b\x63\x61rdinality\x18\x02 \x01(\x04R\x0b\x63\x61rdinality\x12I\n\x0b\x61t_revision\x18\x03 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\natRevision2\xd7\x01\n\x1dRoaringLookupResourcesService\x12\xb5\x01\n\"ExperimentalRoaringLookupResources\x12\x45.authzed.api.materialize.v0.ExperimentalRoaringLookupResourcesRequest\x1a\x46.authzed.api.materialize.v0.ExperimentalRoaringLookupResourcesResponse\"\x00\x42\x62\n\x1e\x63om.authzed.api.materialize.v0P\x01Z>github.com/authzed/authzed-go/proto/authzed/api/materialize/v0b\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'authzed.api.materialize.v0.roaringlookupresources_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\036com.authzed.api.materialize.v0P\001Z>github.com/authzed/authzed-go/proto/authzed/api/materialize/v0' + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESREQUEST'].fields_by_name['resource_object_type']._loaded_options = None + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESREQUEST'].fields_by_name['resource_object_type']._serialized_options = b'\372BErC(\200\0012>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$\272HErC(\200\0012>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$' + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESREQUEST'].fields_by_name['permission']._loaded_options = None + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESREQUEST'].fields_by_name['permission']._serialized_options = b'\372B$r\"(@2\036^[a-z][a-z0-9_]{1,62}[a-z0-9]$\272H$r\"(@2\036^[a-z][a-z0-9_]{1,62}[a-z0-9]$' + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESREQUEST'].fields_by_name['subject']._loaded_options = None + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESREQUEST'].fields_by_name['subject']._serialized_options = b'\372B\005\212\001\002\020\001\272H\003\310\001\001' + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESRESPONSE'].fields_by_name['at_revision']._loaded_options = None + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESRESPONSE'].fields_by_name['at_revision']._serialized_options = b'\372B\005\212\001\002\020\001\272H\003\310\001\001' + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESREQUEST']._serialized_start=210 + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESREQUEST']._serialized_end=702 + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESRESPONSE']._serialized_start=705 + _globals['_EXPERIMENTALROARINGLOOKUPRESOURCESRESPONSE']._serialized_end=882 + _globals['_ROARINGLOOKUPRESOURCESSERVICE']._serialized_start=885 + _globals['_ROARINGLOOKUPRESOURCESSERVICE']._serialized_end=1100 +# @@protoc_insertion_point(module_scope) diff --git a/src/authzed/api/materialize/v0/roaringlookupresources_pb2.pyi b/src/authzed/api/materialize/v0/roaringlookupresources_pb2.pyi new file mode 100644 index 0000000..4ae1214 --- /dev/null +++ b/src/authzed/api/materialize/v0/roaringlookupresources_pb2.pyi @@ -0,0 +1,78 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" + +import authzed.api.v1.core_pb2 +import authzed.api.v1.permission_service_pb2 +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import typing + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +@typing.final +class ExperimentalRoaringLookupResourcesRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + CONSISTENCY_FIELD_NUMBER: builtins.int + RESOURCE_OBJECT_TYPE_FIELD_NUMBER: builtins.int + PERMISSION_FIELD_NUMBER: builtins.int + SUBJECT_FIELD_NUMBER: builtins.int + resource_object_type: builtins.str + """resource_object_type is the type of resource over which to look up access.""" + permission: builtins.str + """permission is the name of the permission or relation to look up.""" + @property + def consistency(self) -> authzed.api.v1.permission_service_pb2.Consistency: + """consistency selects the snapshot at which the lookup is performed. If + unspecified, minimize_latency is used. + """ + + @property + def subject(self) -> authzed.api.v1.core_pb2.SubjectReference: + """subject is the subject for which access is being looked up.""" + + def __init__( + self, + *, + consistency: authzed.api.v1.permission_service_pb2.Consistency | None = ..., + resource_object_type: builtins.str = ..., + permission: builtins.str = ..., + subject: authzed.api.v1.core_pb2.SubjectReference | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["consistency", b"consistency", "subject", b"subject"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["consistency", b"consistency", "permission", b"permission", "resource_object_type", b"resource_object_type", "subject", b"subject"]) -> None: ... + +global___ExperimentalRoaringLookupResourcesRequest = ExperimentalRoaringLookupResourcesRequest + +@typing.final +class ExperimentalRoaringLookupResourcesResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + + BITMAP_FIELD_NUMBER: builtins.int + CARDINALITY_FIELD_NUMBER: builtins.int + AT_REVISION_FIELD_NUMBER: builtins.int + bitmap: builtins.bytes + """bitmap is the roaring64 bitmap, in RoaringFormatSpec 64-bit portable + format, of the resource object IDs accessible to the subject. The IDs are + the object IDs from the relationships themselves, as 44-bit integers. + """ + cardinality: builtins.int + """cardinality is the number of resource IDs in the bitmap.""" + @property + def at_revision(self) -> authzed.api.v1.core_pb2.ZedToken: + """at_revision is the ZedToken at which the lookup was performed.""" + + def __init__( + self, + *, + bitmap: builtins.bytes = ..., + cardinality: builtins.int = ..., + at_revision: authzed.api.v1.core_pb2.ZedToken | None = ..., + ) -> None: ... + def HasField(self, field_name: typing.Literal["at_revision", b"at_revision"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["at_revision", b"at_revision", "bitmap", b"bitmap", "cardinality", b"cardinality"]) -> None: ... + +global___ExperimentalRoaringLookupResourcesResponse = ExperimentalRoaringLookupResourcesResponse diff --git a/src/authzed/api/materialize/v0/roaringlookupresources_pb2_grpc.py b/src/authzed/api/materialize/v0/roaringlookupresources_pb2_grpc.py new file mode 100644 index 0000000..56fb96d --- /dev/null +++ b/src/authzed/api/materialize/v0/roaringlookupresources_pb2_grpc.py @@ -0,0 +1,117 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from authzed.api.materialize.v0 import roaringlookupresources_pb2 as authzed_dot_api_dot_materialize_dot_v0_dot_roaringlookupresources__pb2 + + +class RoaringLookupResourcesServiceStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.ExperimentalRoaringLookupResources = channel.unary_unary( + '/authzed.api.materialize.v0.RoaringLookupResourcesService/ExperimentalRoaringLookupResources', + request_serializer=authzed_dot_api_dot_materialize_dot_v0_dot_roaringlookupresources__pb2.ExperimentalRoaringLookupResourcesRequest.SerializeToString, + response_deserializer=authzed_dot_api_dot_materialize_dot_v0_dot_roaringlookupresources__pb2.ExperimentalRoaringLookupResourcesResponse.FromString, + _registered_method=True) + + +class RoaringLookupResourcesServiceServicer(object): + """Missing associated documentation comment in .proto file.""" + + def ExperimentalRoaringLookupResources(self, request, context): + """EXPERIMENTAL: RoaringLookupResources returns a roaring64 bitmap of the IDs + of the resources of the given type on which the given subject has the + given permission. This API is experimental and subject to change or + removal. + + The bitmap is serialized in the RoaringFormatSpec 64-bit portable format + (https://github.com/RoaringBitmap/RoaringFormatSpec#extention-for-64-bit-implementations), + which OpenSearch consumes directly via a `"value_type": "bitmap"` terms + query against a `long` field, once Base64-encoded. + + The IDs in the bitmap are the resource object IDs exactly as they appear + in the relationships: no surrogate or internal ID is introduced, so the + caller can use the bitmap directly against its own data (for example, a + search index keyed by the same IDs). + + For this API to be usable, every resource object ID of the requested type + must be a canonical decimal integer that fits in 44 bits -- at most + 17592186044415 (2^44 - 1). Canonical means the string round-trips through + uint64 formatting unchanged: `document:007` and `document:7` are distinct + objects that would collide as the integer 7, so non-canonical IDs are + rejected. If any resource object ID violates either rule, the call fails + with FAILED_PRECONDITION rather than returning a partial bitmap, since a + bitmap that is quietly too small is a wrong authorization answer. When the + permission relates a type to itself (for example `group#member` looked up + for a `group#member` subject), the subject is one of its own resources, so + the subject's object ID is held to the same rules and can itself be the ID + named in that error. + + Response size: the whole bitmap is returned in a single unary message, and + most gRPC clients default to refusing messages larger than 4 MiB. Roaring + is compact -- a million sequential IDs encode in a few hundred bytes -- but + sparse IDs cost close to 10 bytes each, so a result of more than roughly + 400,000 widely-spread IDs can exceed that default and fail on the CLIENT + side with RESOURCE_EXHAUSTED ("received message larger than max"). This is + a limit of the caller's own gRPC configuration, not of the service: raise + it to match the largest result you expect (in Go, + grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(n)); other languages + have an equivalent channel option). The `cardinality` field is returned so + callers can see how large a result is once received; no server-side result + limit is applied. + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_RoaringLookupResourcesServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'ExperimentalRoaringLookupResources': grpc.unary_unary_rpc_method_handler( + servicer.ExperimentalRoaringLookupResources, + request_deserializer=authzed_dot_api_dot_materialize_dot_v0_dot_roaringlookupresources__pb2.ExperimentalRoaringLookupResourcesRequest.FromString, + response_serializer=authzed_dot_api_dot_materialize_dot_v0_dot_roaringlookupresources__pb2.ExperimentalRoaringLookupResourcesResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'authzed.api.materialize.v0.RoaringLookupResourcesService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + server.add_registered_method_handlers('authzed.api.materialize.v0.RoaringLookupResourcesService', rpc_method_handlers) + + + # This class is part of an EXPERIMENTAL API. +class RoaringLookupResourcesService(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def ExperimentalRoaringLookupResources(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary( + request, + target, + '/authzed.api.materialize.v0.RoaringLookupResourcesService/ExperimentalRoaringLookupResources', + authzed_dot_api_dot_materialize_dot_v0_dot_roaringlookupresources__pb2.ExperimentalRoaringLookupResourcesRequest.SerializeToString, + authzed_dot_api_dot_materialize_dot_v0_dot_roaringlookupresources__pb2.ExperimentalRoaringLookupResourcesResponse.FromString, + options, + channel_credentials, + insecure, + call_credentials, + compression, + wait_for_ready, + timeout, + metadata, + _registered_method=True) diff --git a/src/authzed/api/v1/permission_service_pb2.py b/src/authzed/api/v1/permission_service_pb2.py index ad2c2f4..ad14a06 100644 --- a/src/authzed/api/v1/permission_service_pb2.py +++ b/src/authzed/api/v1/permission_service_pb2.py @@ -33,7 +33,7 @@ from validate import validate_pb2 as validate_dot_validate__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'authzed/api/v1/permission_service.proto\x12\x0e\x61uthzed.api.v1\x1a\x19\x61uthzed/api/v1/core.proto\x1a\x1a\x61uthzed/api/v1/debug.proto\x1a\x1b\x62uf/validate/validate.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x17google/rpc/status.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\x1a\x17validate/validate.proto\"\xaf\x02\n\x0b\x43onsistency\x12;\n\x10minimize_latency\x18\x01 \x01(\x08\x42\x0e\xfa\x42\x04j\x02\x08\x01\xbaH\x04j\x02\x08\x01H\x00R\x0fminimizeLatency\x12\x45\n\x11\x61t_least_as_fresh\x18\x02 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenH\x00R\x0e\x61tLeastAsFresh\x12\x46\n\x11\x61t_exact_snapshot\x18\x03 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenH\x00R\x0f\x61tExactSnapshot\x12;\n\x10\x66ully_consistent\x18\x04 \x01(\x08\x42\x0e\xfa\x42\x04j\x02\x08\x01\xbaH\x04j\x02\x08\x01H\x00R\x0f\x66ullyConsistentB\x17\n\x0brequirement\x12\x08\xf8\x42\x01\xbaH\x02\x08\x01\"\xb8\x05\n\x12RelationshipFilter\x12\xbc\x01\n\rresource_type\x18\x01 \x01(\tB\x96\x01\xfa\x42HrF(\x80\x01\x32\x41^(([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaHHrF(\x80\x01\x32\x41^(([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9])?$R\x0cresourceType\x12|\n\x14optional_resource_id\x18\x02 \x01(\tBJ\xfa\x42\"r (\x80\x08\x32\x1b^([a-zA-Z0-9/_|\\-=+]{1,})?$\xbaH\"r (\x80\x08\x32\x1b^([a-zA-Z0-9/_|\\-=+]{1,})?$R\x12optionalResourceId\x12\x89\x01\n\x1boptional_resource_id_prefix\x18\x05 \x01(\tBJ\xfa\x42\"r (\x80\x08\x32\x1b^([a-zA-Z0-9/_|\\-=+]{1,})?$\xbaH\"r (\x80\x08\x32\x1b^([a-zA-Z0-9/_|\\-=+]{1,})?$R\x18optionalResourceIdPrefix\x12\x81\x01\n\x11optional_relation\x18\x03 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\x10optionalRelation\x12U\n\x17optional_subject_filter\x18\x04 \x01(\x0b\x32\x1d.authzed.api.v1.SubjectFilterR\x15optionalSubjectFilter\"\xad\x04\n\rSubjectFilter\x12\xb4\x01\n\x0csubject_type\x18\x01 \x01(\tB\x90\x01\xfa\x42\x45rC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaHErC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$R\x0bsubjectType\x12\x84\x01\n\x13optional_subject_id\x18\x02 \x01(\tBT\xfa\x42\'r%(\x80\x08\x32 ^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)?$\xbaH\'r%(\x80\x08\x32 ^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)?$R\x11optionalSubjectId\x12Y\n\x11optional_relation\x18\x03 \x01(\x0b\x32,.authzed.api.v1.SubjectFilter.RelationFilterR\x10optionalRelation\x1a\x82\x01\n\x0eRelationFilter\x12p\n\x08relation\x18\x01 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\x08relation\"\xb6\x02\n\x18ReadRelationshipsRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12\x63\n\x13relationship_filter\x18\x02 \x01(\x0b\x32\".authzed.api.v1.RelationshipFilterB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x12relationshipFilter\x12\x35\n\x0eoptional_limit\x18\x03 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\roptionalLimit\x12?\n\x0foptional_cursor\x18\x04 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x0eoptionalCursor\"\xf8\x01\n\x19ReadRelationshipsResponse\x12\x41\n\x07read_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x06readAt\x12P\n\x0crelationship\x18\x02 \x01(\x0b\x32\x1c.authzed.api.v1.RelationshipB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x0crelationship\x12\x46\n\x13\x61\x66ter_result_cursor\x18\x03 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x11\x61\x66terResultCursor\"\x96\x02\n\x0cPrecondition\x12Z\n\toperation\x18\x01 \x01(\x0e\x32&.authzed.api.v1.Precondition.OperationB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\toperation\x12J\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\".authzed.api.v1.RelationshipFilterB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x06\x66ilter\"^\n\tOperation\x12\x19\n\x15OPERATION_UNSPECIFIED\x10\x00\x12\x1c\n\x18OPERATION_MUST_NOT_MATCH\x10\x01\x12\x18\n\x14OPERATION_MUST_MATCH\x10\x02\"\xb9\x02\n\x19WriteRelationshipsRequest\x12K\n\x07updates\x18\x01 \x03(\x0b\x32\".authzed.api.v1.RelationshipUpdateB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x07updates\x12\x62\n\x16optional_preconditions\x18\x02 \x03(\x0b\x32\x1c.authzed.api.v1.PreconditionB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x15optionalPreconditions\x12k\n\x1doptional_transaction_metadata\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x1boptionalTransactionMetadata\"U\n\x1aWriteRelationshipsResponse\x12\x37\n\nwritten_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\twrittenAt\"\xd2\x03\n\x1a\x44\x65leteRelationshipsRequest\x12\x63\n\x13relationship_filter\x18\x01 \x01(\x0b\x32\".authzed.api.v1.RelationshipFilterB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x12relationshipFilter\x12\x62\n\x16optional_preconditions\x18\x02 \x03(\x0b\x32\x1c.authzed.api.v1.PreconditionB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x15optionalPreconditions\x12\x35\n\x0eoptional_limit\x18\x03 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\roptionalLimit\x12G\n optional_allow_partial_deletions\x18\x04 \x01(\x08R\x1doptionalAllowPartialDeletions\x12k\n\x1doptional_transaction_metadata\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x1boptionalTransactionMetadata\"\xf7\x02\n\x1b\x44\x65leteRelationshipsResponse\x12\x37\n\ndeleted_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\tdeletedAt\x12i\n\x11\x64\x65letion_progress\x18\x02 \x01(\x0e\x32<.authzed.api.v1.DeleteRelationshipsResponse.DeletionProgressR\x10\x64\x65letionProgress\x12>\n\x1brelationships_deleted_count\x18\x03 \x01(\x04R\x19relationshipsDeletedCount\"t\n\x10\x44\x65letionProgress\x12!\n\x1d\x44\x45LETION_PROGRESS_UNSPECIFIED\x10\x00\x12\x1e\n\x1a\x44\x45LETION_PROGRESS_COMPLETE\x10\x01\x12\x1d\n\x19\x44\x45LETION_PROGRESS_PARTIAL\x10\x02\"\xcc\x03\n\x16\x43heckPermissionRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12K\n\x08resource\x18\x02 \x01(\x0b\x32\x1f.authzed.api.v1.ObjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x08resource\x12t\n\npermission\x18\x03 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\npermission\x12J\n\x07subject\x18\x04 \x01(\x0b\x32 .authzed.api.v1.SubjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x07subject\x12\x41\n\x07\x63ontext\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x07\x63ontext\x12!\n\x0cwith_tracing\x18\x06 \x01(\x08R\x0bwithTracing\"\xed\x04\n\x17\x43heckPermissionResponse\x12G\n\nchecked_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\tcheckedAt\x12t\n\x0epermissionship\x18\x02 \x01(\x0e\x32\x36.authzed.api.v1.CheckPermissionResponse.PermissionshipB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x61\n\x13partial_caveat_info\x18\x03 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\x12\x41\n\x0b\x64\x65\x62ug_trace\x18\x04 \x01(\x0b\x32 .authzed.api.v1.DebugInformationR\ndebugTrace\x12J\n\x13optional_expires_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x11optionalExpiresAt\"\xa0\x01\n\x0ePermissionship\x12\x1e\n\x1aPERMISSIONSHIP_UNSPECIFIED\x10\x00\x12 \n\x1cPERMISSIONSHIP_NO_PERMISSION\x10\x01\x12!\n\x1dPERMISSIONSHIP_HAS_PERMISSION\x10\x02\x12)\n%PERMISSIONSHIP_CONDITIONAL_PERMISSION\x10\x03\"\xd5\x01\n\x1b\x43heckBulkPermissionsRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12T\n\x05items\x18\x02 \x03(\x0b\x32/.authzed.api.v1.CheckBulkPermissionsRequestItemB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x05items\x12!\n\x0cwith_tracing\x18\x03 \x01(\x08R\x0bwithTracing\"\xf3\x02\n\x1f\x43heckBulkPermissionsRequestItem\x12K\n\x08resource\x18\x01 \x01(\x0b\x32\x1f.authzed.api.v1.ObjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x08resource\x12t\n\npermission\x18\x02 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\npermission\x12J\n\x07subject\x18\x03 \x01(\x0b\x32 .authzed.api.v1.SubjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x07subject\x12\x41\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x07\x63ontext\"\xb6\x01\n\x1c\x43heckBulkPermissionsResponse\x12G\n\nchecked_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\tcheckedAt\x12M\n\x05pairs\x18\x02 \x03(\x0b\x32(.authzed.api.v1.CheckBulkPermissionsPairB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x05pairs\"\xe5\x01\n\x18\x43heckBulkPermissionsPair\x12I\n\x07request\x18\x01 \x01(\x0b\x32/.authzed.api.v1.CheckBulkPermissionsRequestItemR\x07request\x12\x46\n\x04item\x18\x02 \x01(\x0b\x32\x30.authzed.api.v1.CheckBulkPermissionsResponseItemH\x00R\x04item\x12*\n\x05\x65rror\x18\x03 \x01(\x0b\x32\x12.google.rpc.StatusH\x00R\x05\x65rrorB\n\n\x08response\"\xbe\x02\n CheckBulkPermissionsResponseItem\x12t\n\x0epermissionship\x18\x01 \x01(\x0e\x32\x36.authzed.api.v1.CheckPermissionResponse.PermissionshipB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x61\n\x13partial_caveat_info\x18\x02 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\x12\x41\n\x0b\x64\x65\x62ug_trace\x18\x03 \x01(\x0b\x32 .authzed.api.v1.DebugInformationR\ndebugTrace\"\x9f\x02\n\x1b\x45xpandPermissionTreeRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12K\n\x08resource\x18\x02 \x01(\x0b\x32\x1f.authzed.api.v1.ObjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x08resource\x12t\n\npermission\x18\x03 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\npermission\"\xa2\x01\n\x1c\x45xpandPermissionTreeResponse\x12\x39\n\x0b\x65xpanded_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\nexpandedAt\x12G\n\ttree_root\x18\x02 \x01(\x0b\x32*.authzed.api.v1.PermissionRelationshipTreeR\x08treeRoot\"\xb3\x05\n\x16LookupResourcesRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12\xc3\x01\n\x14resource_object_type\x18\x02 \x01(\tB\x90\x01\xfa\x42\x45rC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaHErC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$R\x12resourceObjectType\x12n\n\npermission\x18\x03 \x01(\tBN\xfa\x42$r\"(@2\x1e^[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaH$r\"(@2\x1e^[a-z][a-z0-9_]{1,62}[a-z0-9]$R\npermission\x12J\n\x07subject\x18\x04 \x01(\x0b\x32 .authzed.api.v1.SubjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x07subject\x12\x41\n\x07\x63ontext\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x07\x63ontext\x12\x35\n\x0eoptional_limit\x18\x06 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\roptionalLimit\x12?\n\x0foptional_cursor\x18\x07 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x0eoptionalCursor\x12\x1d\n\nwith_debug\x18\x08 \x01(\x08R\twithDebug\"\x92\x03\n\x17LookupResourcesResponse\x12:\n\x0clooked_up_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\nlookedUpAt\x12,\n\x12resource_object_id\x18\x02 \x01(\tR\x10resourceObjectId\x12\x62\n\x0epermissionship\x18\x03 \x01(\x0e\x32$.authzed.api.v1.LookupPermissionshipB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x61\n\x13partial_caveat_info\x18\x04 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\x12\x46\n\x13\x61\x66ter_result_cursor\x18\x05 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x11\x61\x66terResultCursor\"\x9c\x08\n\x15LookupSubjectsRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12K\n\x08resource\x18\x02 \x01(\x0b\x32\x1f.authzed.api.v1.ObjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x08resource\x12t\n\npermission\x18\x03 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\npermission\x12\xc1\x01\n\x13subject_object_type\x18\x04 \x01(\tB\x90\x01\xfa\x42\x45rC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaHErC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$R\x11subjectObjectType\x12\x90\x01\n\x19optional_subject_relation\x18\x05 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\x17optionalSubjectRelation\x12\x41\n\x07\x63ontext\x18\x06 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x07\x63ontext\x12\x46\n\x17optional_concrete_limit\x18\x07 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\x15optionalConcreteLimit\x12?\n\x0foptional_cursor\x18\x08 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x0eoptionalCursor\x12]\n\x0fwildcard_option\x18\t \x01(\x0e\x32\x34.authzed.api.v1.LookupSubjectsRequest.WildcardOptionR\x0ewildcardOption\"\x7f\n\x0eWildcardOption\x12\x1f\n\x1bWILDCARD_OPTION_UNSPECIFIED\x10\x00\x12%\n!WILDCARD_OPTION_INCLUDE_WILDCARDS\x10\x01\x12%\n!WILDCARD_OPTION_EXCLUDE_WILDCARDS\x10\x02\"\xd6\x04\n\x16LookupSubjectsResponse\x12:\n\x0clooked_up_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\nlookedUpAt\x12.\n\x11subject_object_id\x18\x02 \x01(\tB\x02\x18\x01R\x0fsubjectObjectId\x12\x34\n\x14\x65xcluded_subject_ids\x18\x03 \x03(\tB\x02\x18\x01R\x12\x65xcludedSubjectIds\x12\x64\n\x0epermissionship\x18\x04 \x01(\x0e\x32$.authzed.api.v1.LookupPermissionshipB\x16\x18\x01\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x63\n\x13partial_caveat_info\x18\x05 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x10\x18\x01\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\x12\x39\n\x07subject\x18\x06 \x01(\x0b\x32\x1f.authzed.api.v1.ResolvedSubjectR\x07subject\x12L\n\x11\x65xcluded_subjects\x18\x07 \x03(\x0b\x32\x1f.authzed.api.v1.ResolvedSubjectR\x10\x65xcludedSubjects\x12\x46\n\x13\x61\x66ter_result_cursor\x18\x08 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x11\x61\x66terResultCursor\"\x84\x02\n\x0fResolvedSubject\x12*\n\x11subject_object_id\x18\x01 \x01(\tR\x0fsubjectObjectId\x12\x62\n\x0epermissionship\x18\x02 \x01(\x0e\x32$.authzed.api.v1.LookupPermissionshipB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x61\n\x13partial_caveat_info\x18\x03 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\"s\n\x1eImportBulkRelationshipsRequest\x12Q\n\rrelationships\x18\x01 \x03(\x0b\x32\x1c.authzed.api.v1.RelationshipB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\rrelationships\"@\n\x1fImportBulkRelationshipsResponse\x12\x1d\n\nnum_loaded\x18\x01 \x01(\x04R\tnumLoaded\"\xbd\x02\n\x1e\x45xportBulkRelationshipsRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12\x35\n\x0eoptional_limit\x18\x02 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\roptionalLimit\x12?\n\x0foptional_cursor\x18\x03 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x0eoptionalCursor\x12\x64\n\x1coptional_relationship_filter\x18\x04 \x01(\x0b\x32\".authzed.api.v1.RelationshipFilterR\x1aoptionalRelationshipFilter\"\xad\x01\n\x1f\x45xportBulkRelationshipsResponse\x12\x46\n\x13\x61\x66ter_result_cursor\x18\x01 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x11\x61\x66terResultCursor\x12\x42\n\rrelationships\x18\x02 \x03(\x0b\x32\x1c.authzed.api.v1.RelationshipR\rrelationships*\x99\x01\n\x14LookupPermissionship\x12%\n!LOOKUP_PERMISSIONSHIP_UNSPECIFIED\x10\x00\x12(\n$LOOKUP_PERMISSIONSHIP_HAS_PERMISSION\x10\x01\x12\x30\n,LOOKUP_PERMISSIONSHIP_CONDITIONAL_PERMISSION\x10\x02\x32\x8a\r\n\x12PermissionsService\x12\x9d\x01\n\x11ReadRelationships\x12(.authzed.api.v1.ReadRelationshipsRequest\x1a).authzed.api.v1.ReadRelationshipsResponse\"1\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1b\"\x16/v1/relationships/read:\x01*0\x01\x12\x9f\x01\n\x12WriteRelationships\x12).authzed.api.v1.WriteRelationshipsRequest\x1a*.authzed.api.v1.WriteRelationshipsResponse\"2\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1c\"\x17/v1/relationships/write:\x01*\x12\xa3\x01\n\x13\x44\x65leteRelationships\x12*.authzed.api.v1.DeleteRelationshipsRequest\x1a+.authzed.api.v1.DeleteRelationshipsResponse\"3\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1d\"\x18/v1/relationships/delete:\x01*\x12\x94\x01\n\x0f\x43heckPermission\x12&.authzed.api.v1.CheckPermissionRequest\x1a\'.authzed.api.v1.CheckPermissionResponse\"0\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1a\"\x15/v1/permissions/check:\x01*\x12\xa7\x01\n\x14\x43heckBulkPermissions\x12+.authzed.api.v1.CheckBulkPermissionsRequest\x1a,.authzed.api.v1.CheckBulkPermissionsResponse\"4\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1e\"\x19/v1/permissions/checkbulk:\x01*\x12\xa4\x01\n\x14\x45xpandPermissionTree\x12+.authzed.api.v1.ExpandPermissionTreeRequest\x1a,.authzed.api.v1.ExpandPermissionTreeResponse\"1\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1b\"\x16/v1/permissions/expand:\x01*\x12\x9a\x01\n\x0fLookupResources\x12&.authzed.api.v1.LookupResourcesRequest\x1a\'.authzed.api.v1.LookupResourcesResponse\"4\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1e\"\x19/v1/permissions/resources:\x01*0\x01\x12\x96\x01\n\x0eLookupSubjects\x12%.authzed.api.v1.LookupSubjectsRequest\x1a&.authzed.api.v1.LookupSubjectsResponse\"3\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1d\"\x18/v1/permissions/subjects:\x01*0\x01\x12\xb5\x01\n\x17ImportBulkRelationships\x12..authzed.api.v1.ImportBulkRelationshipsRequest\x1a/.authzed.api.v1.ImportBulkRelationshipsResponse\"7\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02!\"\x1c/v1/relationships/importbulk:\x01*(\x01\x12\xb5\x01\n\x17\x45xportBulkRelationships\x12..authzed.api.v1.ExportBulkRelationshipsRequest\x1a/.authzed.api.v1.ExportBulkRelationshipsResponse\"7\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02!\"\x1c/v1/relationships/exportbulk:\x01*0\x01\x42J\n\x12\x63om.authzed.api.v1P\x01Z2github.com/authzed/authzed-go/proto/authzed/api/v1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'authzed/api/v1/permission_service.proto\x12\x0e\x61uthzed.api.v1\x1a\x19\x61uthzed/api/v1/core.proto\x1a\x1a\x61uthzed/api/v1/debug.proto\x1a\x1b\x62uf/validate/validate.proto\x1a\x1cgoogle/api/annotations.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x17google/rpc/status.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\x1a\x17validate/validate.proto\"\xaf\x02\n\x0b\x43onsistency\x12;\n\x10minimize_latency\x18\x01 \x01(\x08\x42\x0e\xfa\x42\x04j\x02\x08\x01\xbaH\x04j\x02\x08\x01H\x00R\x0fminimizeLatency\x12\x45\n\x11\x61t_least_as_fresh\x18\x02 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenH\x00R\x0e\x61tLeastAsFresh\x12\x46\n\x11\x61t_exact_snapshot\x18\x03 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenH\x00R\x0f\x61tExactSnapshot\x12;\n\x10\x66ully_consistent\x18\x04 \x01(\x08\x42\x0e\xfa\x42\x04j\x02\x08\x01\xbaH\x04j\x02\x08\x01H\x00R\x0f\x66ullyConsistentB\x17\n\x0brequirement\x12\x08\xf8\x42\x01\xbaH\x02\x08\x01\"\xb8\x05\n\x12RelationshipFilter\x12\xbc\x01\n\rresource_type\x18\x01 \x01(\tB\x96\x01\xfa\x42HrF(\x80\x01\x32\x41^(([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaHHrF(\x80\x01\x32\x41^(([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9])?$R\x0cresourceType\x12|\n\x14optional_resource_id\x18\x02 \x01(\tBJ\xfa\x42\"r (\x80\x08\x32\x1b^([a-zA-Z0-9/_|\\-=+]{1,})?$\xbaH\"r (\x80\x08\x32\x1b^([a-zA-Z0-9/_|\\-=+]{1,})?$R\x12optionalResourceId\x12\x89\x01\n\x1boptional_resource_id_prefix\x18\x05 \x01(\tBJ\xfa\x42\"r (\x80\x08\x32\x1b^([a-zA-Z0-9/_|\\-=+]{1,})?$\xbaH\"r (\x80\x08\x32\x1b^([a-zA-Z0-9/_|\\-=+]{1,})?$R\x18optionalResourceIdPrefix\x12\x81\x01\n\x11optional_relation\x18\x03 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\x10optionalRelation\x12U\n\x17optional_subject_filter\x18\x04 \x01(\x0b\x32\x1d.authzed.api.v1.SubjectFilterR\x15optionalSubjectFilter\"\xad\x04\n\rSubjectFilter\x12\xb4\x01\n\x0csubject_type\x18\x01 \x01(\tB\x90\x01\xfa\x42\x45rC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaHErC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$R\x0bsubjectType\x12\x84\x01\n\x13optional_subject_id\x18\x02 \x01(\tBT\xfa\x42\'r%(\x80\x08\x32 ^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)?$\xbaH\'r%(\x80\x08\x32 ^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)?$R\x11optionalSubjectId\x12Y\n\x11optional_relation\x18\x03 \x01(\x0b\x32,.authzed.api.v1.SubjectFilter.RelationFilterR\x10optionalRelation\x1a\x82\x01\n\x0eRelationFilter\x12p\n\x08relation\x18\x01 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\x08relation\"\xb6\x02\n\x18ReadRelationshipsRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12\x63\n\x13relationship_filter\x18\x02 \x01(\x0b\x32\".authzed.api.v1.RelationshipFilterB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x12relationshipFilter\x12\x35\n\x0eoptional_limit\x18\x03 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\roptionalLimit\x12?\n\x0foptional_cursor\x18\x04 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x0eoptionalCursor\"\xf8\x01\n\x19ReadRelationshipsResponse\x12\x41\n\x07read_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x06readAt\x12P\n\x0crelationship\x18\x02 \x01(\x0b\x32\x1c.authzed.api.v1.RelationshipB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x0crelationship\x12\x46\n\x13\x61\x66ter_result_cursor\x18\x03 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x11\x61\x66terResultCursor\"\x96\x02\n\x0cPrecondition\x12Z\n\toperation\x18\x01 \x01(\x0e\x32&.authzed.api.v1.Precondition.OperationB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\toperation\x12J\n\x06\x66ilter\x18\x02 \x01(\x0b\x32\".authzed.api.v1.RelationshipFilterB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x06\x66ilter\"^\n\tOperation\x12\x19\n\x15OPERATION_UNSPECIFIED\x10\x00\x12\x1c\n\x18OPERATION_MUST_NOT_MATCH\x10\x01\x12\x18\n\x14OPERATION_MUST_MATCH\x10\x02\"\xb9\x02\n\x19WriteRelationshipsRequest\x12K\n\x07updates\x18\x01 \x03(\x0b\x32\".authzed.api.v1.RelationshipUpdateB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x07updates\x12\x62\n\x16optional_preconditions\x18\x02 \x03(\x0b\x32\x1c.authzed.api.v1.PreconditionB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x15optionalPreconditions\x12k\n\x1doptional_transaction_metadata\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x1boptionalTransactionMetadata\"U\n\x1aWriteRelationshipsResponse\x12\x37\n\nwritten_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\twrittenAt\"\x93\x04\n\x1a\x44\x65leteRelationshipsRequest\x12\x63\n\x13relationship_filter\x18\x01 \x01(\x0b\x32\".authzed.api.v1.RelationshipFilterB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x12relationshipFilter\x12\x62\n\x16optional_preconditions\x18\x02 \x03(\x0b\x32\x1c.authzed.api.v1.PreconditionB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x15optionalPreconditions\x12\x35\n\x0eoptional_limit\x18\x03 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\roptionalLimit\x12G\n optional_allow_partial_deletions\x18\x04 \x01(\x08R\x1doptionalAllowPartialDeletions\x12k\n\x1doptional_transaction_metadata\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x1boptionalTransactionMetadata\x12?\n\x0foptional_cursor\x18\x06 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x0eoptionalCursor\"\xbf\x03\n\x1b\x44\x65leteRelationshipsResponse\x12\x37\n\ndeleted_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\tdeletedAt\x12i\n\x11\x64\x65letion_progress\x18\x02 \x01(\x0e\x32<.authzed.api.v1.DeleteRelationshipsResponse.DeletionProgressR\x10\x64\x65letionProgress\x12>\n\x1brelationships_deleted_count\x18\x03 \x01(\x04R\x19relationshipsDeletedCount\x12\x46\n\x13\x61\x66ter_result_cursor\x18\x04 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x11\x61\x66terResultCursor\"t\n\x10\x44\x65letionProgress\x12!\n\x1d\x44\x45LETION_PROGRESS_UNSPECIFIED\x10\x00\x12\x1e\n\x1a\x44\x45LETION_PROGRESS_COMPLETE\x10\x01\x12\x1d\n\x19\x44\x45LETION_PROGRESS_PARTIAL\x10\x02\"\xcc\x03\n\x16\x43heckPermissionRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12K\n\x08resource\x18\x02 \x01(\x0b\x32\x1f.authzed.api.v1.ObjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x08resource\x12t\n\npermission\x18\x03 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\npermission\x12J\n\x07subject\x18\x04 \x01(\x0b\x32 .authzed.api.v1.SubjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x07subject\x12\x41\n\x07\x63ontext\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x07\x63ontext\x12!\n\x0cwith_tracing\x18\x06 \x01(\x08R\x0bwithTracing\"\xed\x04\n\x17\x43heckPermissionResponse\x12G\n\nchecked_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\tcheckedAt\x12t\n\x0epermissionship\x18\x02 \x01(\x0e\x32\x36.authzed.api.v1.CheckPermissionResponse.PermissionshipB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x61\n\x13partial_caveat_info\x18\x03 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\x12\x41\n\x0b\x64\x65\x62ug_trace\x18\x04 \x01(\x0b\x32 .authzed.api.v1.DebugInformationR\ndebugTrace\x12J\n\x13optional_expires_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\x11optionalExpiresAt\"\xa0\x01\n\x0ePermissionship\x12\x1e\n\x1aPERMISSIONSHIP_UNSPECIFIED\x10\x00\x12 \n\x1cPERMISSIONSHIP_NO_PERMISSION\x10\x01\x12!\n\x1dPERMISSIONSHIP_HAS_PERMISSION\x10\x02\x12)\n%PERMISSIONSHIP_CONDITIONAL_PERMISSION\x10\x03\"\xd5\x01\n\x1b\x43heckBulkPermissionsRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12T\n\x05items\x18\x02 \x03(\x0b\x32/.authzed.api.v1.CheckBulkPermissionsRequestItemB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x05items\x12!\n\x0cwith_tracing\x18\x03 \x01(\x08R\x0bwithTracing\"\xf3\x02\n\x1f\x43heckBulkPermissionsRequestItem\x12K\n\x08resource\x18\x01 \x01(\x0b\x32\x1f.authzed.api.v1.ObjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x08resource\x12t\n\npermission\x18\x02 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\npermission\x12J\n\x07subject\x18\x03 \x01(\x0b\x32 .authzed.api.v1.SubjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x07subject\x12\x41\n\x07\x63ontext\x18\x04 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x07\x63ontext\"\xb6\x01\n\x1c\x43heckBulkPermissionsResponse\x12G\n\nchecked_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\tcheckedAt\x12M\n\x05pairs\x18\x02 \x03(\x0b\x32(.authzed.api.v1.CheckBulkPermissionsPairB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\x05pairs\"\xe5\x01\n\x18\x43heckBulkPermissionsPair\x12I\n\x07request\x18\x01 \x01(\x0b\x32/.authzed.api.v1.CheckBulkPermissionsRequestItemR\x07request\x12\x46\n\x04item\x18\x02 \x01(\x0b\x32\x30.authzed.api.v1.CheckBulkPermissionsResponseItemH\x00R\x04item\x12*\n\x05\x65rror\x18\x03 \x01(\x0b\x32\x12.google.rpc.StatusH\x00R\x05\x65rrorB\n\n\x08response\"\xbe\x02\n CheckBulkPermissionsResponseItem\x12t\n\x0epermissionship\x18\x01 \x01(\x0e\x32\x36.authzed.api.v1.CheckPermissionResponse.PermissionshipB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x61\n\x13partial_caveat_info\x18\x02 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\x12\x41\n\x0b\x64\x65\x62ug_trace\x18\x03 \x01(\x0b\x32 .authzed.api.v1.DebugInformationR\ndebugTrace\"\x9f\x02\n\x1b\x45xpandPermissionTreeRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12K\n\x08resource\x18\x02 \x01(\x0b\x32\x1f.authzed.api.v1.ObjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x08resource\x12t\n\npermission\x18\x03 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\npermission\"\xa2\x01\n\x1c\x45xpandPermissionTreeResponse\x12\x39\n\x0b\x65xpanded_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\nexpandedAt\x12G\n\ttree_root\x18\x02 \x01(\x0b\x32*.authzed.api.v1.PermissionRelationshipTreeR\x08treeRoot\"\xb3\x05\n\x16LookupResourcesRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12\xc3\x01\n\x14resource_object_type\x18\x02 \x01(\tB\x90\x01\xfa\x42\x45rC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaHErC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$R\x12resourceObjectType\x12n\n\npermission\x18\x03 \x01(\tBN\xfa\x42$r\"(@2\x1e^[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaH$r\"(@2\x1e^[a-z][a-z0-9_]{1,62}[a-z0-9]$R\npermission\x12J\n\x07subject\x18\x04 \x01(\x0b\x32 .authzed.api.v1.SubjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x07subject\x12\x41\n\x07\x63ontext\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x07\x63ontext\x12\x35\n\x0eoptional_limit\x18\x06 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\roptionalLimit\x12?\n\x0foptional_cursor\x18\x07 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x0eoptionalCursor\x12\x1d\n\nwith_debug\x18\x08 \x01(\x08R\twithDebug\"\x92\x03\n\x17LookupResourcesResponse\x12:\n\x0clooked_up_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\nlookedUpAt\x12,\n\x12resource_object_id\x18\x02 \x01(\tR\x10resourceObjectId\x12\x62\n\x0epermissionship\x18\x03 \x01(\x0e\x32$.authzed.api.v1.LookupPermissionshipB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x61\n\x13partial_caveat_info\x18\x04 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\x12\x46\n\x13\x61\x66ter_result_cursor\x18\x05 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x11\x61\x66terResultCursor\"\x9c\x08\n\x15LookupSubjectsRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12K\n\x08resource\x18\x02 \x01(\x0b\x32\x1f.authzed.api.v1.ObjectReferenceB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x01\xbaH\x03\xc8\x01\x01R\x08resource\x12t\n\npermission\x18\x03 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\npermission\x12\xc1\x01\n\x13subject_object_type\x18\x04 \x01(\tB\x90\x01\xfa\x42\x45rC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$\xbaHErC(\x80\x01\x32>^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$R\x11subjectObjectType\x12\x90\x01\n\x19optional_subject_relation\x18\x05 \x01(\tBT\xfa\x42\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$\xbaH\'r%(@2!^([a-z][a-z0-9_]{1,62}[a-z0-9])?$R\x17optionalSubjectRelation\x12\x41\n\x07\x63ontext\x18\x06 \x01(\x0b\x32\x17.google.protobuf.StructB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x07\x63ontext\x12\x46\n\x17optional_concrete_limit\x18\x07 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\x15optionalConcreteLimit\x12?\n\x0foptional_cursor\x18\x08 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x0eoptionalCursor\x12]\n\x0fwildcard_option\x18\t \x01(\x0e\x32\x34.authzed.api.v1.LookupSubjectsRequest.WildcardOptionR\x0ewildcardOption\"\x7f\n\x0eWildcardOption\x12\x1f\n\x1bWILDCARD_OPTION_UNSPECIFIED\x10\x00\x12%\n!WILDCARD_OPTION_INCLUDE_WILDCARDS\x10\x01\x12%\n!WILDCARD_OPTION_EXCLUDE_WILDCARDS\x10\x02\"\xd6\x04\n\x16LookupSubjectsResponse\x12:\n\x0clooked_up_at\x18\x01 \x01(\x0b\x32\x18.authzed.api.v1.ZedTokenR\nlookedUpAt\x12.\n\x11subject_object_id\x18\x02 \x01(\tB\x02\x18\x01R\x0fsubjectObjectId\x12\x34\n\x14\x65xcluded_subject_ids\x18\x03 \x03(\tB\x02\x18\x01R\x12\x65xcludedSubjectIds\x12\x64\n\x0epermissionship\x18\x04 \x01(\x0e\x32$.authzed.api.v1.LookupPermissionshipB\x16\x18\x01\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x63\n\x13partial_caveat_info\x18\x05 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x10\x18\x01\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\x12\x39\n\x07subject\x18\x06 \x01(\x0b\x32\x1f.authzed.api.v1.ResolvedSubjectR\x07subject\x12L\n\x11\x65xcluded_subjects\x18\x07 \x03(\x0b\x32\x1f.authzed.api.v1.ResolvedSubjectR\x10\x65xcludedSubjects\x12\x46\n\x13\x61\x66ter_result_cursor\x18\x08 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x11\x61\x66terResultCursor\"\x84\x02\n\x0fResolvedSubject\x12*\n\x11subject_object_id\x18\x01 \x01(\tR\x0fsubjectObjectId\x12\x62\n\x0epermissionship\x18\x02 \x01(\x0e\x32$.authzed.api.v1.LookupPermissionshipB\x14\xfa\x42\x07\x82\x01\x04\x10\x01 \x00\xbaH\x07\x82\x01\x04\x10\x01 \x00R\x0epermissionship\x12\x61\n\x13partial_caveat_info\x18\x03 \x01(\x0b\x32!.authzed.api.v1.PartialCaveatInfoB\x0e\xfa\x42\x05\x8a\x01\x02\x10\x00\xbaH\x03\xc8\x01\x00R\x11partialCaveatInfo\"s\n\x1eImportBulkRelationshipsRequest\x12Q\n\rrelationships\x18\x01 \x03(\x0b\x32\x1c.authzed.api.v1.RelationshipB\r\xfa\x42\n\x92\x01\x07\"\x05\x8a\x01\x02\x10\x01R\rrelationships\"@\n\x1fImportBulkRelationshipsResponse\x12\x1d\n\nnum_loaded\x18\x01 \x01(\x04R\tnumLoaded\"\xbd\x02\n\x1e\x45xportBulkRelationshipsRequest\x12=\n\x0b\x63onsistency\x18\x01 \x01(\x0b\x32\x1b.authzed.api.v1.ConsistencyR\x0b\x63onsistency\x12\x35\n\x0eoptional_limit\x18\x02 \x01(\rB\x0e\xfa\x42\x04*\x02(\x00\xbaH\x04*\x02(\x00R\roptionalLimit\x12?\n\x0foptional_cursor\x18\x03 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x0eoptionalCursor\x12\x64\n\x1coptional_relationship_filter\x18\x04 \x01(\x0b\x32\".authzed.api.v1.RelationshipFilterR\x1aoptionalRelationshipFilter\"\xad\x01\n\x1f\x45xportBulkRelationshipsResponse\x12\x46\n\x13\x61\x66ter_result_cursor\x18\x01 \x01(\x0b\x32\x16.authzed.api.v1.CursorR\x11\x61\x66terResultCursor\x12\x42\n\rrelationships\x18\x02 \x03(\x0b\x32\x1c.authzed.api.v1.RelationshipR\rrelationships*\x99\x01\n\x14LookupPermissionship\x12%\n!LOOKUP_PERMISSIONSHIP_UNSPECIFIED\x10\x00\x12(\n$LOOKUP_PERMISSIONSHIP_HAS_PERMISSION\x10\x01\x12\x30\n,LOOKUP_PERMISSIONSHIP_CONDITIONAL_PERMISSION\x10\x02\x32\x8a\r\n\x12PermissionsService\x12\x9d\x01\n\x11ReadRelationships\x12(.authzed.api.v1.ReadRelationshipsRequest\x1a).authzed.api.v1.ReadRelationshipsResponse\"1\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1b\"\x16/v1/relationships/read:\x01*0\x01\x12\x9f\x01\n\x12WriteRelationships\x12).authzed.api.v1.WriteRelationshipsRequest\x1a*.authzed.api.v1.WriteRelationshipsResponse\"2\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1c\"\x17/v1/relationships/write:\x01*\x12\xa3\x01\n\x13\x44\x65leteRelationships\x12*.authzed.api.v1.DeleteRelationshipsRequest\x1a+.authzed.api.v1.DeleteRelationshipsResponse\"3\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1d\"\x18/v1/relationships/delete:\x01*\x12\x94\x01\n\x0f\x43heckPermission\x12&.authzed.api.v1.CheckPermissionRequest\x1a\'.authzed.api.v1.CheckPermissionResponse\"0\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1a\"\x15/v1/permissions/check:\x01*\x12\xa7\x01\n\x14\x43heckBulkPermissions\x12+.authzed.api.v1.CheckBulkPermissionsRequest\x1a,.authzed.api.v1.CheckBulkPermissionsResponse\"4\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1e\"\x19/v1/permissions/checkbulk:\x01*\x12\xa4\x01\n\x14\x45xpandPermissionTree\x12+.authzed.api.v1.ExpandPermissionTreeRequest\x1a,.authzed.api.v1.ExpandPermissionTreeResponse\"1\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1b\"\x16/v1/permissions/expand:\x01*\x12\x9a\x01\n\x0fLookupResources\x12&.authzed.api.v1.LookupResourcesRequest\x1a\'.authzed.api.v1.LookupResourcesResponse\"4\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1e\"\x19/v1/permissions/resources:\x01*0\x01\x12\x96\x01\n\x0eLookupSubjects\x12%.authzed.api.v1.LookupSubjectsRequest\x1a&.authzed.api.v1.LookupSubjectsResponse\"3\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02\x1d\"\x18/v1/permissions/subjects:\x01*0\x01\x12\xb5\x01\n\x17ImportBulkRelationships\x12..authzed.api.v1.ImportBulkRelationshipsRequest\x1a/.authzed.api.v1.ImportBulkRelationshipsResponse\"7\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02!\"\x1c/v1/relationships/importbulk:\x01*(\x01\x12\xb5\x01\n\x17\x45xportBulkRelationships\x12..authzed.api.v1.ExportBulkRelationshipsRequest\x1a/.authzed.api.v1.ExportBulkRelationshipsResponse\"7\x92\x41\r\n\x0bPermissions\x82\xd3\xe4\x93\x02!\"\x1c/v1/relationships/exportbulk:\x01*0\x01\x42J\n\x12\x63om.authzed.api.v1P\x01Z2github.com/authzed/authzed-go/proto/authzed/api/v1b\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -185,8 +185,8 @@ _globals['_PERMISSIONSSERVICE'].methods_by_name['ImportBulkRelationships']._serialized_options = b'\222A\r\n\013Permissions\202\323\344\223\002!\"\034/v1/relationships/importbulk:\001*' _globals['_PERMISSIONSSERVICE'].methods_by_name['ExportBulkRelationships']._loaded_options = None _globals['_PERMISSIONSSERVICE'].methods_by_name['ExportBulkRelationships']._serialized_options = b'\222A\r\n\013Permissions\202\323\344\223\002!\"\034/v1/relationships/exportbulk:\001*' - _globals['_LOOKUPPERMISSIONSHIP']._serialized_start=10562 - _globals['_LOOKUPPERMISSIONSHIP']._serialized_end=10715 + _globals['_LOOKUPPERMISSIONSHIP']._serialized_start=10699 + _globals['_LOOKUPPERMISSIONSHIP']._serialized_end=10852 _globals['_CONSISTENCY']._serialized_start=335 _globals['_CONSISTENCY']._serialized_end=638 _globals['_RELATIONSHIPFILTER']._serialized_start=641 @@ -208,51 +208,51 @@ _globals['_WRITERELATIONSHIPSRESPONSE']._serialized_start=3060 _globals['_WRITERELATIONSHIPSRESPONSE']._serialized_end=3145 _globals['_DELETERELATIONSHIPSREQUEST']._serialized_start=3148 - _globals['_DELETERELATIONSHIPSREQUEST']._serialized_end=3614 - _globals['_DELETERELATIONSHIPSRESPONSE']._serialized_start=3617 - _globals['_DELETERELATIONSHIPSRESPONSE']._serialized_end=3992 - _globals['_DELETERELATIONSHIPSRESPONSE_DELETIONPROGRESS']._serialized_start=3876 - _globals['_DELETERELATIONSHIPSRESPONSE_DELETIONPROGRESS']._serialized_end=3992 - _globals['_CHECKPERMISSIONREQUEST']._serialized_start=3995 - _globals['_CHECKPERMISSIONREQUEST']._serialized_end=4455 - _globals['_CHECKPERMISSIONRESPONSE']._serialized_start=4458 - _globals['_CHECKPERMISSIONRESPONSE']._serialized_end=5079 - _globals['_CHECKPERMISSIONRESPONSE_PERMISSIONSHIP']._serialized_start=4919 - _globals['_CHECKPERMISSIONRESPONSE_PERMISSIONSHIP']._serialized_end=5079 - _globals['_CHECKBULKPERMISSIONSREQUEST']._serialized_start=5082 - _globals['_CHECKBULKPERMISSIONSREQUEST']._serialized_end=5295 - _globals['_CHECKBULKPERMISSIONSREQUESTITEM']._serialized_start=5298 - _globals['_CHECKBULKPERMISSIONSREQUESTITEM']._serialized_end=5669 - _globals['_CHECKBULKPERMISSIONSRESPONSE']._serialized_start=5672 - _globals['_CHECKBULKPERMISSIONSRESPONSE']._serialized_end=5854 - _globals['_CHECKBULKPERMISSIONSPAIR']._serialized_start=5857 - _globals['_CHECKBULKPERMISSIONSPAIR']._serialized_end=6086 - _globals['_CHECKBULKPERMISSIONSRESPONSEITEM']._serialized_start=6089 - _globals['_CHECKBULKPERMISSIONSRESPONSEITEM']._serialized_end=6407 - _globals['_EXPANDPERMISSIONTREEREQUEST']._serialized_start=6410 - _globals['_EXPANDPERMISSIONTREEREQUEST']._serialized_end=6697 - _globals['_EXPANDPERMISSIONTREERESPONSE']._serialized_start=6700 - _globals['_EXPANDPERMISSIONTREERESPONSE']._serialized_end=6862 - _globals['_LOOKUPRESOURCESREQUEST']._serialized_start=6865 - _globals['_LOOKUPRESOURCESREQUEST']._serialized_end=7556 - _globals['_LOOKUPRESOURCESRESPONSE']._serialized_start=7559 - _globals['_LOOKUPRESOURCESRESPONSE']._serialized_end=7961 - _globals['_LOOKUPSUBJECTSREQUEST']._serialized_start=7964 - _globals['_LOOKUPSUBJECTSREQUEST']._serialized_end=9016 - _globals['_LOOKUPSUBJECTSREQUEST_WILDCARDOPTION']._serialized_start=8889 - _globals['_LOOKUPSUBJECTSREQUEST_WILDCARDOPTION']._serialized_end=9016 - _globals['_LOOKUPSUBJECTSRESPONSE']._serialized_start=9019 - _globals['_LOOKUPSUBJECTSRESPONSE']._serialized_end=9617 - _globals['_RESOLVEDSUBJECT']._serialized_start=9620 - _globals['_RESOLVEDSUBJECT']._serialized_end=9880 - _globals['_IMPORTBULKRELATIONSHIPSREQUEST']._serialized_start=9882 - _globals['_IMPORTBULKRELATIONSHIPSREQUEST']._serialized_end=9997 - _globals['_IMPORTBULKRELATIONSHIPSRESPONSE']._serialized_start=9999 - _globals['_IMPORTBULKRELATIONSHIPSRESPONSE']._serialized_end=10063 - _globals['_EXPORTBULKRELATIONSHIPSREQUEST']._serialized_start=10066 - _globals['_EXPORTBULKRELATIONSHIPSREQUEST']._serialized_end=10383 - _globals['_EXPORTBULKRELATIONSHIPSRESPONSE']._serialized_start=10386 - _globals['_EXPORTBULKRELATIONSHIPSRESPONSE']._serialized_end=10559 - _globals['_PERMISSIONSSERVICE']._serialized_start=10718 - _globals['_PERMISSIONSSERVICE']._serialized_end=12392 + _globals['_DELETERELATIONSHIPSREQUEST']._serialized_end=3679 + _globals['_DELETERELATIONSHIPSRESPONSE']._serialized_start=3682 + _globals['_DELETERELATIONSHIPSRESPONSE']._serialized_end=4129 + _globals['_DELETERELATIONSHIPSRESPONSE_DELETIONPROGRESS']._serialized_start=4013 + _globals['_DELETERELATIONSHIPSRESPONSE_DELETIONPROGRESS']._serialized_end=4129 + _globals['_CHECKPERMISSIONREQUEST']._serialized_start=4132 + _globals['_CHECKPERMISSIONREQUEST']._serialized_end=4592 + _globals['_CHECKPERMISSIONRESPONSE']._serialized_start=4595 + _globals['_CHECKPERMISSIONRESPONSE']._serialized_end=5216 + _globals['_CHECKPERMISSIONRESPONSE_PERMISSIONSHIP']._serialized_start=5056 + _globals['_CHECKPERMISSIONRESPONSE_PERMISSIONSHIP']._serialized_end=5216 + _globals['_CHECKBULKPERMISSIONSREQUEST']._serialized_start=5219 + _globals['_CHECKBULKPERMISSIONSREQUEST']._serialized_end=5432 + _globals['_CHECKBULKPERMISSIONSREQUESTITEM']._serialized_start=5435 + _globals['_CHECKBULKPERMISSIONSREQUESTITEM']._serialized_end=5806 + _globals['_CHECKBULKPERMISSIONSRESPONSE']._serialized_start=5809 + _globals['_CHECKBULKPERMISSIONSRESPONSE']._serialized_end=5991 + _globals['_CHECKBULKPERMISSIONSPAIR']._serialized_start=5994 + _globals['_CHECKBULKPERMISSIONSPAIR']._serialized_end=6223 + _globals['_CHECKBULKPERMISSIONSRESPONSEITEM']._serialized_start=6226 + _globals['_CHECKBULKPERMISSIONSRESPONSEITEM']._serialized_end=6544 + _globals['_EXPANDPERMISSIONTREEREQUEST']._serialized_start=6547 + _globals['_EXPANDPERMISSIONTREEREQUEST']._serialized_end=6834 + _globals['_EXPANDPERMISSIONTREERESPONSE']._serialized_start=6837 + _globals['_EXPANDPERMISSIONTREERESPONSE']._serialized_end=6999 + _globals['_LOOKUPRESOURCESREQUEST']._serialized_start=7002 + _globals['_LOOKUPRESOURCESREQUEST']._serialized_end=7693 + _globals['_LOOKUPRESOURCESRESPONSE']._serialized_start=7696 + _globals['_LOOKUPRESOURCESRESPONSE']._serialized_end=8098 + _globals['_LOOKUPSUBJECTSREQUEST']._serialized_start=8101 + _globals['_LOOKUPSUBJECTSREQUEST']._serialized_end=9153 + _globals['_LOOKUPSUBJECTSREQUEST_WILDCARDOPTION']._serialized_start=9026 + _globals['_LOOKUPSUBJECTSREQUEST_WILDCARDOPTION']._serialized_end=9153 + _globals['_LOOKUPSUBJECTSRESPONSE']._serialized_start=9156 + _globals['_LOOKUPSUBJECTSRESPONSE']._serialized_end=9754 + _globals['_RESOLVEDSUBJECT']._serialized_start=9757 + _globals['_RESOLVEDSUBJECT']._serialized_end=10017 + _globals['_IMPORTBULKRELATIONSHIPSREQUEST']._serialized_start=10019 + _globals['_IMPORTBULKRELATIONSHIPSREQUEST']._serialized_end=10134 + _globals['_IMPORTBULKRELATIONSHIPSRESPONSE']._serialized_start=10136 + _globals['_IMPORTBULKRELATIONSHIPSRESPONSE']._serialized_end=10200 + _globals['_EXPORTBULKRELATIONSHIPSREQUEST']._serialized_start=10203 + _globals['_EXPORTBULKRELATIONSHIPSREQUEST']._serialized_end=10520 + _globals['_EXPORTBULKRELATIONSHIPSRESPONSE']._serialized_start=10523 + _globals['_EXPORTBULKRELATIONSHIPSRESPONSE']._serialized_end=10696 + _globals['_PERMISSIONSSERVICE']._serialized_start=10855 + _globals['_PERMISSIONSSERVICE']._serialized_end=12529 # @@protoc_insertion_point(module_scope) diff --git a/src/authzed/api/v1/permission_service_pb2.pyi b/src/authzed/api/v1/permission_service_pb2.pyi index 4925493..b92772c 100644 --- a/src/authzed/api/v1/permission_service_pb2.pyi +++ b/src/authzed/api/v1/permission_service_pb2.pyi @@ -413,6 +413,7 @@ class DeleteRelationshipsRequest(google.protobuf.message.Message): OPTIONAL_LIMIT_FIELD_NUMBER: builtins.int OPTIONAL_ALLOW_PARTIAL_DELETIONS_FIELD_NUMBER: builtins.int OPTIONAL_TRANSACTION_METADATA_FIELD_NUMBER: builtins.int + OPTIONAL_CURSOR_FIELD_NUMBER: builtins.int optional_limit: builtins.int """optional_limit, if non-zero, specifies the limit on the number of relationships to be deleted. If there are more matching relationships found to be deleted than the limit specified here, @@ -437,6 +438,19 @@ class DeleteRelationshipsRequest(google.protobuf.message.Message): this transaction. """ + @property + def optional_cursor(self) -> authzed.api.v1.core_pb2.Cursor: + """optional_cursor, if specified, indicates the cursor after which deletion should resume. It is used to + continue a batched, partial deletion where a previous call left off, by passing back the + after_result_cursor returned on the previous DeleteRelationshipsResponse. + + A cursor allows a large deletion to be performed as a series of calls without re-examining the + relationships already deleted by earlier calls. It therefore requires optional_limit and + optional_allow_partial_deletions to be set, and is only supported by datastores whose deletion can be + ordered and resumed; datastores that do not support cursored deletion will return an error if a cursor + is provided. + """ + def __init__( self, *, @@ -445,9 +459,10 @@ class DeleteRelationshipsRequest(google.protobuf.message.Message): optional_limit: builtins.int = ..., optional_allow_partial_deletions: builtins.bool = ..., optional_transaction_metadata: google.protobuf.struct_pb2.Struct | None = ..., + optional_cursor: authzed.api.v1.core_pb2.Cursor | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["optional_transaction_metadata", b"optional_transaction_metadata", "relationship_filter", b"relationship_filter"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["optional_allow_partial_deletions", b"optional_allow_partial_deletions", "optional_limit", b"optional_limit", "optional_preconditions", b"optional_preconditions", "optional_transaction_metadata", b"optional_transaction_metadata", "relationship_filter", b"relationship_filter"]) -> None: ... + def HasField(self, field_name: typing.Literal["optional_cursor", b"optional_cursor", "optional_transaction_metadata", b"optional_transaction_metadata", "relationship_filter", b"relationship_filter"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["optional_allow_partial_deletions", b"optional_allow_partial_deletions", "optional_cursor", b"optional_cursor", "optional_limit", b"optional_limit", "optional_preconditions", b"optional_preconditions", "optional_transaction_metadata", b"optional_transaction_metadata", "relationship_filter", b"relationship_filter"]) -> None: ... global___DeleteRelationshipsRequest = DeleteRelationshipsRequest @@ -489,6 +504,7 @@ class DeleteRelationshipsResponse(google.protobuf.message.Message): DELETED_AT_FIELD_NUMBER: builtins.int DELETION_PROGRESS_FIELD_NUMBER: builtins.int RELATIONSHIPS_DELETED_COUNT_FIELD_NUMBER: builtins.int + AFTER_RESULT_CURSOR_FIELD_NUMBER: builtins.int deletion_progress: global___DeleteRelationshipsResponse.DeletionProgress.ValueType """deletion_progress is an enumeration of the possible outcomes that occurred when attempting to delete the specified relationships.""" relationships_deleted_count: builtins.int @@ -497,15 +513,25 @@ class DeleteRelationshipsResponse(google.protobuf.message.Message): def deleted_at(self) -> authzed.api.v1.core_pb2.ZedToken: """deleted_at is the revision at which the relationships were deleted.""" + @property + def after_result_cursor(self) -> authzed.api.v1.core_pb2.Cursor: + """after_result_cursor holds a cursor that can be used to resume the deletion after the relationships + deleted by this call, by supplying it as the optional_cursor on a subsequent DeleteRelationshipsRequest. + + It is populated only when deletion_progress is DELETION_PROGRESS_PARTIAL and the datastore supports + cursored deletion; it is unset once DELETION_PROGRESS_COMPLETE is returned. + """ + def __init__( self, *, deleted_at: authzed.api.v1.core_pb2.ZedToken | None = ..., deletion_progress: global___DeleteRelationshipsResponse.DeletionProgress.ValueType = ..., relationships_deleted_count: builtins.int = ..., + after_result_cursor: authzed.api.v1.core_pb2.Cursor | None = ..., ) -> None: ... - def HasField(self, field_name: typing.Literal["deleted_at", b"deleted_at"]) -> builtins.bool: ... - def ClearField(self, field_name: typing.Literal["deleted_at", b"deleted_at", "deletion_progress", b"deletion_progress", "relationships_deleted_count", b"relationships_deleted_count"]) -> None: ... + def HasField(self, field_name: typing.Literal["after_result_cursor", b"after_result_cursor", "deleted_at", b"deleted_at"]) -> builtins.bool: ... + def ClearField(self, field_name: typing.Literal["after_result_cursor", b"after_result_cursor", "deleted_at", b"deleted_at", "deletion_progress", b"deletion_progress", "relationships_deleted_count", b"relationships_deleted_count"]) -> None: ... global___DeleteRelationshipsResponse = DeleteRelationshipsResponse diff --git a/src/authzed/api/v1/permission_service_pb2_grpc.py b/src/authzed/api/v1/permission_service_pb2_grpc.py index 8e9ca44..f707997 100644 --- a/src/authzed/api/v1/permission_service_pb2_grpc.py +++ b/src/authzed/api/v1/permission_service_pb2_grpc.py @@ -128,6 +128,11 @@ def ExpandPermissionTree(self, request, context): def LookupResources(self, request, context): """LookupResources returns all the resources of a given type that a subject can access whether via a computed permission or relation membership. + + Results are streamed and **not guaranteed to be unique**: the same resource + may be returned more than once (for example via caveated/conditional + results, or when a limit is set), possibly with differing permissionship. + Callers that require uniqueness should deduplicate results. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') @@ -136,6 +141,10 @@ def LookupResources(self, request, context): def LookupSubjects(self, request, context): """LookupSubjects returns all the subjects of a given type that have access whether via a computed permission or relation membership. + + Results are streamed and **not guaranteed to be unique**: the same subject + may be returned more than once, possibly with differing permissionship. + Callers that require uniqueness should deduplicate results. """ context.set_code(grpc.StatusCode.UNIMPLEMENTED) context.set_details('Method not implemented!') diff --git a/src/buf/validate/validate_pb2.pyi b/src/buf/validate/validate_pb2.pyi index c426943..cd95f87 100644 --- a/src/buf/validate/validate_pb2.pyi +++ b/src/buf/validate/validate_pb2.pyi @@ -27,7 +27,7 @@ See the [developer quickstart](https://protovalidate.com/quickstart/) to get sta [Go](https://github.com/bufbuild/protovalidate-go), [JavaScript/TypeScript](https://github.com/bufbuild/protovalidate-es), [Java](https://github.com/bufbuild/protovalidate-java), -[Python](https://github.com/bufbuild/protovalidate-python), +[Python](https://github.com/bufbuild/protovalidate-py), or [C++](https://github.com/bufbuild/protovalidate-cc). """ @@ -263,7 +263,7 @@ class Rule(google.protobuf.message.Message): """`Rule` represents a validation rule written in the Common Expression Language (CEL) syntax. Each Rule includes a unique identifier, an optional error message, and the CEL expression to evaluate. For more - information, [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + information, [see our documentation](https://protovalidate.com/schemas/custom-rules/). ```proto message Foo { @@ -330,7 +330,7 @@ class MessageRules(google.protobuf.message.Message): simpler syntax when defining CEL Rules where `id` and `message` derived from the `expression`. `id` will be same as the `expression`. - For more information, [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + For more information, [see our documentation](https://protovalidate.com/schemas/custom-rules/). ```proto message MyMessage { @@ -347,7 +347,7 @@ class MessageRules(google.protobuf.message.Message): def cel(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Rule]: """`cel` is a repeated field of type Rule. Each Rule specifies a validation rule to be applied to this message. These rules are written in Common Expression Language (CEL) syntax. For more information, - [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + [see our documentation](https://protovalidate.com/schemas/custom-rules/). ```proto @@ -590,7 +590,7 @@ class FieldRules(google.protobuf.message.Message): simpler syntax when defining CEL Rules where `id` and `message` derived from the `expression`. `id` will be same as the `expression`. - For more information, [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + For more information, [see our documentation](https://protovalidate.com/schemas/custom-rules/). ```proto message MyMessage { @@ -604,7 +604,7 @@ class FieldRules(google.protobuf.message.Message): def cel(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Rule]: """`cel` is a repeated field used to represent a textual expression in the Common Expression Language (CEL) syntax. For more information, - [see our documentation](https://buf.build/docs/protovalidate/schemas/custom-rules/). + [see our documentation](https://protovalidate.com/schemas/custom-rules/). ```proto message MyMessage { @@ -717,7 +717,7 @@ class PredefinedRules(google.protobuf.message.Message): def cel(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___Rule]: """`cel` is a repeated field used to represent a textual expression in the Common Expression Language (CEL) syntax. For more information, - [see our documentation](https://buf.build/docs/protovalidate/schemas/predefined-rules/). + [see our documentation](https://protovalidate.com/schemas/predefined-rules/). ```proto message MyMessage { @@ -1572,7 +1572,7 @@ class UInt64Rules(google.protobuf.message.Message): message MyUInt64 { uint64 value = 1 [ (buf.validate.field).uint64.example = 1, - (buf.validate.field).uint64.example = -10 + (buf.validate.field).uint64.example = 10 ]; } ``` @@ -2462,8 +2462,8 @@ class BoolRules(google.protobuf.message.Message): ```proto message MyBool { bool value = 1 [ - (buf.validate.field).bool.example = 1, - (buf.validate.field).bool.example = 2 + (buf.validate.field).bool.example = true, + (buf.validate.field).bool.example = false ]; } ``` @@ -3043,7 +3043,7 @@ class StringRules(google.protobuf.message.Message): ```proto message MyString { // value must not be in list ["orange", "grape"] - string value = 1 [(buf.validate.field).string.not_in = "orange", (buf.validate.field).string.not_in = "grape"]; + string value = 1 [(buf.validate.field).string = { not_in: ["orange", "grape"] }]; } ``` """ @@ -3284,7 +3284,7 @@ class BytesRules(google.protobuf.message.Message): ```proto message MyBytes { // value must not in ["\\x01\\x02", "\\x02\\x03", "\\x03\\x04"] - optional bytes value = 1 [(buf.validate.field).bytes.not_in = {"\\x01\\x02", "\\x02\\x03", "\\x03\\x04"}]; + optional bytes value = 1 [(buf.validate.field).bytes = { not_in: ["\\x01\\x02", "\\x02\\x03", "\\x03\\x04"] }]; } ``` """ @@ -3408,8 +3408,10 @@ class EnumRules(google.protobuf.message.Message): } message MyMessage { + MyEnum value = 1 [ (buf.validate.field).enum.example = 1, (buf.validate.field).enum.example = 2 + ]; } ``` """ @@ -3648,7 +3650,7 @@ class DurationRules(google.protobuf.message.Message): ```proto message MyDuration { // value must equal 5s - google.protobuf.Duration value = 1 [(buf.validate.field).duration.const = "5s"]; + google.protobuf.Duration value = 1 [(buf.validate.field).duration.const = { seconds: 5 }]; } ``` """ @@ -3662,7 +3664,7 @@ class DurationRules(google.protobuf.message.Message): ```proto message MyDuration { // must be less than 5s - google.protobuf.Duration value = 1 [(buf.validate.field).duration.lt = "5s"]; + google.protobuf.Duration value = 1 [(buf.validate.field).duration.lt = { seconds: 5 }]; } ``` """ @@ -3676,7 +3678,7 @@ class DurationRules(google.protobuf.message.Message): ```proto message MyDuration { // must be less than or equal to 10s - google.protobuf.Duration value = 1 [(buf.validate.field).duration.lte = "10s"]; + google.protobuf.Duration value = 1 [(buf.validate.field).duration.lte = { seconds: 10 }]; } ``` """ @@ -3735,7 +3737,9 @@ class DurationRules(google.protobuf.message.Message): ```proto message MyDuration { // value must not be in list [1s, 2s, 3s] - google.protobuf.Duration value = 1 [(buf.validate.field).duration.not_in = ["1s", "2s", "3s"]]; + google.protobuf.Duration value = 1 [(buf.validate.field).duration = { + not_in: [{ seconds: 1 }, { seconds: 2 }, { seconds: 3 }] + }]; } ``` """ @@ -3750,7 +3754,7 @@ class DurationRules(google.protobuf.message.Message): message MyDuration { google.protobuf.Duration value = 1 [ (buf.validate.field).duration.example = { seconds: 1 }, - (buf.validate.field).duration.example = { seconds: 2 }, + (buf.validate.field).duration.example = { seconds: 2 } ]; } ``` @@ -3830,7 +3834,7 @@ class FieldMaskRules(google.protobuf.message.Message): message MyFieldMask { google.protobuf.FieldMask value = 1 [ (buf.validate.field).field_mask.example = { paths: ["a", "b"] }, - (buf.validate.field).field_mask.example = { paths: ["c.a", "d"] }, + (buf.validate.field).field_mask.example = { paths: ["c.a", "d"] } ]; } ``` @@ -3985,7 +3989,7 @@ class TimestampRules(google.protobuf.message.Message): message MyTimestamp { google.protobuf.Timestamp value = 1 [ (buf.validate.field).timestamp.example = { seconds: 1672444800 }, - (buf.validate.field).timestamp.example = { seconds: 1672531200 }, + (buf.validate.field).timestamp.example = { seconds: 1672531200 } ]; } ``` @@ -4137,7 +4141,7 @@ class Violation(google.protobuf.message.Message): bool b = 2 [(buf.validate.field).cel = { id: "custom_rule", expression: "!this ? 'b must be true': ''" - }] + }]; } ``` @@ -4293,7 +4297,7 @@ this adds additional CEL expressions that apply when the extension is used. ```proto extend buf.validate.Int32Rules { - bool is_zero [(buf.validate.predefined).cel = { + bool is_zero = 1001 [(buf.validate.predefined).cel = { id: "int32.is_zero", message: "must be zero", expression: "!rule || this == 0",