diff --git a/authzed/api/v0/core.proto b/authzed/api/v0/core.proto index eadb7e3..6325396 100644 --- a/authzed/api/v0/core.proto +++ b/authzed/api/v0/core.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package authzed.api.v0; +import "buf/validate/validate.proto"; import "validate/validate.proto"; option go_package = "github.com/authzed/authzed-go/proto/authzed/api/v0"; @@ -18,40 +19,80 @@ message RelationTuple { // doc:12345#writer#* (all tuples with direct write relationship with the // document) doc:#writer#group:eng#member (all tuples that eng group has write // relationship) - ObjectAndRelation object_and_relation = 1 [(validate.rules).message.required = true]; - User user = 2 [(validate.rules).message.required = true]; + ObjectAndRelation object_and_relation = 1 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; + User user = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; } message ObjectAndRelation { - string namespace = 1 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 128 - }]; - string object_id = 2 [(validate.rules).string = { - pattern: "^(([a-zA-Z0-9_][a-zA-Z0-9/_|-]{0,127})|\\*)$" - max_bytes: 128 - }]; - string relation = 3 [(validate.rules).string = { - pattern: "^(\\.\\.\\.|[a-z][a-z0-9_]{1,62}[a-z0-9])$" - max_bytes: 64 - }]; + string namespace = 1 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + } + ]; + string object_id = 2 [ + (validate.rules).string = { + pattern: "^(([a-zA-Z0-9_][a-zA-Z0-9/_|-]{0,127})|\\*)$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^(([a-zA-Z0-9_][a-zA-Z0-9/_|-]{0,127})|\\*)$" + max_bytes: 128 + } + ]; + string relation = 3 [ + (validate.rules).string = { + pattern: "^(\\.\\.\\.|[a-z][a-z0-9_]{1,62}[a-z0-9])$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^(\\.\\.\\.|[a-z][a-z0-9_]{1,62}[a-z0-9])$" + max_bytes: 64 + } + ]; } message RelationReference { - string namespace = 1 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 128 - }]; - string relation = 3 [(validate.rules).string = { - pattern: "^(\\.\\.\\.|[a-z][a-z0-9_]{1,62}[a-z0-9])$" - max_bytes: 64 - }]; + string namespace = 1 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + } + ]; + string relation = 3 [ + (validate.rules).string = { + pattern: "^(\\.\\.\\.|[a-z][a-z0-9_]{1,62}[a-z0-9])$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^(\\.\\.\\.|[a-z][a-z0-9_]{1,62}[a-z0-9])$" + max_bytes: 64 + } + ]; } message User { oneof user_oneof { option (validate.required) = true; + option (buf.validate.oneof).required = true; - ObjectAndRelation userset = 2 [(validate.rules).message.required = true]; + ObjectAndRelation userset = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; } } diff --git a/authzed/api/v1/core.proto b/authzed/api/v1/core.proto index 891438b..e3848b7 100644 --- a/authzed/api/v1/core.proto +++ b/authzed/api/v1/core.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package authzed.api.v1; +import "buf/validate/validate.proto"; import "google/protobuf/struct.proto"; import "validate/validate.proto"; @@ -13,19 +14,34 @@ option java_package = "com.authzed.api.v1"; // answered. message Relationship { // resource is the resource to which the subject is related, in some manner - ObjectReference resource = 1 [(validate.rules).message.required = true]; + ObjectReference resource = 1 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // relation is how the resource and subject are related. - string relation = 2 [(validate.rules).string = { - pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 64 - }]; + string relation = 2 [ + (validate.rules).string = { + pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 64 + } + ]; // subject is the subject to which the resource is related, in some manner. - SubjectReference subject = 3 [(validate.rules).message.required = true]; + SubjectReference subject = 3 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // optional_caveat is a reference to a the caveat that must be enforced over the relationship - ContextualizedCaveat optional_caveat = 4 [(validate.rules).message.required = false]; + ContextualizedCaveat optional_caveat = 4 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; } // ContextualizedCaveat represents a reference to a caveat to be used by caveated relationships. @@ -33,36 +49,66 @@ message Relationship { // The keys must match the arguments defined on the caveat in the schema. message ContextualizedCaveat { // caveat_name is the name of the caveat expression to use, as defined in the schema - string caveat_name = 1 [(validate.rules).string = { - pattern: "^([a-zA-Z0-9_][a-zA-Z0-9/_|-]{0,127})$" - max_bytes: 128 - }]; + string caveat_name = 1 [ + (validate.rules).string = { + pattern: "^([a-zA-Z0-9_][a-zA-Z0-9/_|-]{0,127})$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^([a-zA-Z0-9_][a-zA-Z0-9/_|-]{0,127})$" + max_bytes: 128 + } + ]; // context consists of any named values that are defined at write time for the caveat expression - google.protobuf.Struct context = 2 [(validate.rules).message.required = false]; + google.protobuf.Struct context = 2 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; } // SubjectReference is used for referring to the subject portion of a // Relationship. The relation component is optional and is used for defining a // sub-relation on the subject, e.g. group:123#members message SubjectReference { - ObjectReference object = 1 [(validate.rules).message.required = true]; - string optional_relation = 2 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + ObjectReference object = 1 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; + string optional_relation = 2 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; } // ObjectReference is used to refer to a specific object in the system. message ObjectReference { - string object_type = 1 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 128 - }]; - string object_id = 2 [(validate.rules).string = { - pattern: "^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)$" - max_bytes: 1024 - }]; + string object_type = 1 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + } + ]; + string object_id = 2 [ + (validate.rules).string = { + pattern: "^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)$" + max_bytes: 1024 + }, + (buf.validate.field).string = { + pattern: "^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)$" + max_bytes: 1024 + } + ]; } // ZedToken is used to provide causality metadata between Write and Check @@ -70,16 +116,25 @@ message ObjectReference { // // See the authzed.api.v1.Consistency message for more information. message ZedToken { - string token = 1 [(validate.rules).string = {min_bytes: 1}]; + string token = 1 [ + (validate.rules).string = {min_bytes: 1}, + (buf.validate.field).string = {min_bytes: 1} + ]; } // Cursor is used to provide resumption of listing between calls to APIs // such as LookupResources. message Cursor { - string token = 1 [(validate.rules).string = { - min_bytes: 1 - max_bytes: 102400 - }]; + string token = 1 [ + (validate.rules).string = { + min_bytes: 1 + max_bytes: 102400 + }, + (buf.validate.field).string = { + min_bytes: 1 + max_bytes: 102400 + } + ]; } // RelationshipUpdate is used for mutating a single relationship within the @@ -100,11 +155,20 @@ message RelationshipUpdate { OPERATION_TOUCH = 2; OPERATION_DELETE = 3; } - Operation operation = 1 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; - Relationship relationship = 2 [(validate.rules).message.required = true]; + Operation operation = 1 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; + Relationship relationship = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; } // PermissionRelationshipTree is used for representing a tree of a resource and @@ -112,6 +176,7 @@ message RelationshipUpdate { message PermissionRelationshipTree { oneof tree_type { option (validate.required) = true; + option (buf.validate.oneof).required = true; AlgebraicSubjectSet intermediate = 1; DirectSubjectSet leaf = 2; @@ -138,11 +203,20 @@ message AlgebraicSubjectSet { OPERATION_EXCLUSION = 3; } - Operation operation = 1 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; - repeated PermissionRelationshipTree children = 2 [(validate.rules).repeated.items.message.required = true]; + Operation operation = 1 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; + repeated PermissionRelationshipTree children = 2 [ + (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true + ]; } // DirectSubjectSet is a subject set which is simply a collection of subjects. @@ -155,5 +229,8 @@ message DirectSubjectSet { message PartialCaveatInfo { // missing_required_context is a list of one or more fields that were missing and prevented caveats // from being fully evaluated - repeated string missing_required_context = 1 [(validate.rules).repeated.min_items = 1]; + repeated string missing_required_context = 1 [ + (validate.rules).repeated.min_items = 1, + (buf.validate.field).repeated.min_items = 1 + ]; } diff --git a/authzed/api/v1/debug.proto b/authzed/api/v1/debug.proto index 8145746..dfeb745 100644 --- a/authzed/api/v1/debug.proto +++ b/authzed/api/v1/debug.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package authzed.api.v1; import "authzed/api/v1/core.proto"; +import "buf/validate/validate.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/struct.proto"; import "validate/validate.proto"; @@ -45,26 +46,44 @@ message CheckDebugTrace { } // resource holds the resource on which the Check was performed. - ObjectReference resource = 1 [(validate.rules).message.required = true]; + ObjectReference resource = 1 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // permission holds the name of the permission or relation on which the Check was performed. string permission = 2; // permission_type holds information indicating whether it was a permission or relation. - PermissionType permission_type = 3 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; + PermissionType permission_type = 3 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; // subject holds the subject on which the Check was performed. This will be static across all calls within // the same Check tree. - SubjectReference subject = 4 [(validate.rules).message.required = true]; + SubjectReference subject = 4 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // result holds the result of the Check call. - Permissionship result = 5 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; + Permissionship result = 5 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; // caveat_evaluation_info holds information about the caveat evaluated for this step of the trace. CaveatEvalInfo caveat_evaluation_info = 8; @@ -75,6 +94,7 @@ message CheckDebugTrace { // resolution holds information about how the problem was resolved. oneof resolution { option (validate.required) = true; + option (buf.validate.oneof).required = true; // was_cached_result, if true, indicates that the result was found in the cache and returned directly. bool was_cached_result = 6; diff --git a/authzed/api/v1/experimental_service.proto b/authzed/api/v1/experimental_service.proto index a89d1a6..2e1b0b9 100644 --- a/authzed/api/v1/experimental_service.proto +++ b/authzed/api/v1/experimental_service.proto @@ -3,6 +3,7 @@ package authzed.api.v1; import "authzed/api/v1/core.proto"; import "authzed/api/v1/permission_service.proto"; +import "buf/validate/validate.proto"; import "google/api/annotations.proto"; import "google/protobuf/struct.proto"; import "google/rpc/status.proto"; @@ -119,24 +120,39 @@ service ExperimentalService { message ExperimentalRegisterRelationshipCounterRequest { // name is the name of the counter being registered. - string name = 1 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string name = 1 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; // relationship_filter defines the filter to be applied to the relationships // to be counted. - RelationshipFilter relationship_filter = 2 [(validate.rules).message.required = true]; + RelationshipFilter relationship_filter = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; } message ExperimentalRegisterRelationshipCounterResponse {} message ExperimentalCountRelationshipsRequest { // name is the name of the counter whose count is being requested. - string name = 1 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string name = 1 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; } message ExperimentalCountRelationshipsResponse { @@ -154,15 +170,24 @@ message ReadCounterValue { uint64 relationship_count = 1; // read_at is the ZedToken at which the relationship count applies. - ZedToken read_at = 2 [(validate.rules).message.required = true]; + ZedToken read_at = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; } message ExperimentalUnregisterRelationshipCounterRequest { // name is the name of the counter being unregistered. - string name = 1 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string name = 1 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; } message ExperimentalUnregisterRelationshipCounterResponse {} @@ -173,27 +198,49 @@ message BulkCheckPermissionRequest { repeated BulkCheckPermissionRequestItem items = 2 [ (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true, deprecated = true ]; } message BulkCheckPermissionRequestItem { - ObjectReference resource = 1 [(validate.rules).message.required = true]; + ObjectReference resource = 1 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; - string permission = 2 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string permission = 2 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; - SubjectReference subject = 3 [(validate.rules).message.required = true]; + SubjectReference subject = 3 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; - google.protobuf.Struct context = 4 [(validate.rules).message.required = false]; + google.protobuf.Struct context = 4 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; } message BulkCheckPermissionResponse { - ZedToken checked_at = 1 [(validate.rules).message.required = false]; + ZedToken checked_at = 1 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; - repeated BulkCheckPermissionPair pairs = 2 [(validate.rules).repeated.items.message.required = true]; + repeated BulkCheckPermissionPair pairs = 2 [ + (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true + ]; } message BulkCheckPermissionPair { @@ -205,12 +252,21 @@ message BulkCheckPermissionPair { } message BulkCheckPermissionResponseItem { - CheckPermissionResponse.Permissionship permissionship = 1 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; + CheckPermissionResponse.Permissionship permissionship = 1 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; - PartialCaveatInfo partial_caveat_info = 2 [(validate.rules).message.required = false]; + PartialCaveatInfo partial_caveat_info = 2 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; } // BulkImportRelationshipsRequest represents one batch of the streaming @@ -221,7 +277,10 @@ message BulkCheckPermissionResponseItem { // invocation are executed under this single transaction. If a relationship already // exists within the datastore, the entire transaction will fail with an error. message BulkImportRelationshipsRequest { - repeated Relationship relationships = 1 [(validate.rules).repeated.items.message.required = true]; + repeated Relationship relationships = 1 [ + (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true + ]; } // BulkImportRelationshipsResponse is returned on successful completion of the @@ -239,7 +298,10 @@ message BulkExportRelationshipsRequest { // relationships the server can return in one page. By default, the server // will pick a page size, and the server is free to choose a smaller size // at will. - uint32 optional_limit = 2 [(validate.rules).uint32 = {gte: 0}]; + uint32 optional_limit = 2 [ + (validate.rules).uint32 = {gte: 0}, + (buf.validate.field).uint32 = {gte: 0} + ]; // optional_cursor, if specified, indicates the cursor after which results // should resume being returned. The cursor can be found on the diff --git a/authzed/api/v1/permission_service.proto b/authzed/api/v1/permission_service.proto index cc76f84..243a514 100644 --- a/authzed/api/v1/permission_service.proto +++ b/authzed/api/v1/permission_service.proto @@ -3,6 +3,7 @@ package authzed.api.v1; import "authzed/api/v1/core.proto"; import "authzed/api/v1/debug.proto"; +import "buf/validate/validate.proto"; import "google/api/annotations.proto"; import "google/protobuf/struct.proto"; import "google/rpc/status.proto"; @@ -122,10 +123,14 @@ service PermissionsService { message Consistency { oneof requirement { option (validate.required) = true; + option (buf.validate.oneof).required = true; // minimize_latency indicates that the latency for the call should be // minimized by having the system select the fastest snapshot available. - bool minimize_latency = 1 [(validate.rules).bool.const = true]; + bool minimize_latency = 1 [ + (validate.rules).bool.const = true, + (buf.validate.field).bool.const = true + ]; // at_least_as_fresh indicates that all data used in the API call must be // *at least as fresh* as that found in the ZedToken; more recent data might @@ -143,7 +148,10 @@ message Consistency { // NOTE: using this method can be *quite slow*, so unless there is a need to // do so, it is recommended to use `at_least_as_fresh` with a stored // ZedToken. - bool fully_consistent = 4 [(validate.rules).bool.const = true]; + bool fully_consistent = 4 [ + (validate.rules).bool.const = true, + (buf.validate.field).bool.const = true + ]; } } @@ -159,30 +167,54 @@ message Consistency { message RelationshipFilter { // resource_type is the *optional* resource type of the relationship. // NOTE: It is not prefixed with "optional_" for legacy compatibility. - string resource_type = 1 [(validate.rules).string = { - pattern: "^(([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 128 - }]; + string resource_type = 1 [ + (validate.rules).string = { + pattern: "^(([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^(([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 128 + } + ]; // optional_resource_id is the *optional* resource ID of the relationship. // If specified, optional_resource_id_prefix cannot be specified. - string optional_resource_id = 2 [(validate.rules).string = { - pattern: "^([a-zA-Z0-9/_|\\-=+]{1,})?$" - max_bytes: 1024 - }]; + string optional_resource_id = 2 [ + (validate.rules).string = { + pattern: "^([a-zA-Z0-9/_|\\-=+]{1,})?$" + max_bytes: 1024 + }, + (buf.validate.field).string = { + pattern: "^([a-zA-Z0-9/_|\\-=+]{1,})?$" + max_bytes: 1024 + } + ]; // optional_resource_id_prefix is the *optional* prefix for the resource ID of the relationship. // If specified, optional_resource_id cannot be specified. - string optional_resource_id_prefix = 5 [(validate.rules).string = { - pattern: "^([a-zA-Z0-9/_|\\-=+]{1,})?$" - max_bytes: 1024 - }]; + string optional_resource_id_prefix = 5 [ + (validate.rules).string = { + pattern: "^([a-zA-Z0-9/_|\\-=+]{1,})?$" + max_bytes: 1024 + }, + (buf.validate.field).string = { + pattern: "^([a-zA-Z0-9/_|\\-=+]{1,})?$" + max_bytes: 1024 + } + ]; // relation is the *optional* relation of the relationship. - string optional_relation = 3 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string optional_relation = 3 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; // optional_subject_filter is the optional filter for the subjects of the relationships. SubjectFilter optional_subject_filter = 4; @@ -194,21 +226,39 @@ message RelationshipFilter { // impose any additional requirements if left unspecified. message SubjectFilter { message RelationFilter { - string relation = 1 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string relation = 1 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; } - string subject_type = 1 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 128 - }]; + string subject_type = 1 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + } + ]; - string optional_subject_id = 2 [(validate.rules).string = { - pattern: "^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)?$" - max_bytes: 1024 - }]; + string optional_subject_id = 2 [ + (validate.rules).string = { + pattern: "^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)?$" + max_bytes: 1024 + }, + (buf.validate.field).string = { + pattern: "^(([a-zA-Z0-9/_|\\-=+]{1,})|\\*)?$" + max_bytes: 1024 + } + ]; RelationFilter optional_relation = 3; } @@ -220,13 +270,19 @@ message ReadRelationshipsRequest { // relationship_filter defines the filter to be applied to the relationships // to be returned. - RelationshipFilter relationship_filter = 2 [(validate.rules).message.required = true]; + RelationshipFilter relationship_filter = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // optional_limit, if non-zero, specifies the limit on the number of relationships to return // before the stream is closed on the server side. By default, the stream will continue // resolving relationships until exhausted or the stream is closed due to the client or a // network issue. - uint32 optional_limit = 3 [(validate.rules).uint32 = {gte: 0}]; + uint32 optional_limit = 3 [ + (validate.rules).uint32 = {gte: 0}, + (buf.validate.field).uint32 = {gte: 0} + ]; // optional_cursor, if specified, indicates the cursor after which results should resume being returned. // The cursor can be found on the ReadRelationshipsResponse object. @@ -238,10 +294,16 @@ message ReadRelationshipsRequest { // be streamed to the client for each relationship found. message ReadRelationshipsResponse { // read_at is the ZedToken at which the relationship was found. - ZedToken read_at = 1 [(validate.rules).message.required = true]; + ZedToken read_at = 1 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // relationship is the found relationship. - Relationship relationship = 2 [(validate.rules).message.required = true]; + Relationship relationship = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // after_result_cursor holds a cursor that can be used to resume the ReadRelationships stream after this // result. @@ -263,11 +325,20 @@ message Precondition { OPERATION_MUST_MATCH = 2; } - Operation operation = 1 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; - RelationshipFilter filter = 2 [(validate.rules).message.required = true]; + Operation operation = 1 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; + RelationshipFilter filter = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; } // WriteRelationshipsRequest contains a list of Relationship mutations that @@ -276,14 +347,23 @@ message Precondition { // the write will be committed. All updates will be applied transactionally, // and if any preconditions fail, the entire transaction will be reverted. message WriteRelationshipsRequest { - repeated RelationshipUpdate updates = 1 [(validate.rules).repeated.items.message.required = true]; + repeated RelationshipUpdate updates = 1 [ + (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true + ]; - repeated Precondition optional_preconditions = 2 [(validate.rules).repeated.items.message.required = true]; // To be bounded by configuration + repeated Precondition optional_preconditions = 2 [ + (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true + ]; // To be bounded by configuration // optional_transaction_metadata is an optional field that can be used to store metadata about the transaction. // If specified, this metadata will be supplied in the WatchResponse for the updates associated with this // transaction. - google.protobuf.Struct optional_transaction_metadata = 3 [(validate.rules).message.required = false]; + google.protobuf.Struct optional_transaction_metadata = 3 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; } message WriteRelationshipsResponse { @@ -296,16 +376,25 @@ message WriteRelationshipsResponse { // specified preconditions must also be satisfied before the delete will be // executed. message DeleteRelationshipsRequest { - RelationshipFilter relationship_filter = 1 [(validate.rules).message.required = true]; + RelationshipFilter relationship_filter = 1 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; - repeated Precondition optional_preconditions = 2 [(validate.rules).repeated.items.message.required = true]; // To be bounded by configuration + repeated Precondition optional_preconditions = 2 [ + (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true + ]; // To be bounded by configuration // 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, // the deletion call will fail with an error to prevent partial deletion. If partial deletion // is needed, specify below that partial deletion is allowed. Partial deletions can be used // in a loop to delete large amounts of relationships in a *non-transactional* manner. - uint32 optional_limit = 3 [(validate.rules).uint32 = {gte: 0}]; + uint32 optional_limit = 3 [ + (validate.rules).uint32 = {gte: 0}, + (buf.validate.field).uint32 = {gte: 0} + ]; // optional_allow_partial_deletions, if true and a limit is specified, will delete matching found // relationships up to the count specified in optional_limit, and no more. @@ -314,7 +403,10 @@ message DeleteRelationshipsRequest { // optional_transaction_metadata is an optional field that can be used to store metadata about the transaction. // If specified, this metadata will be supplied in the WatchResponse for the deletions associated with // this transaction. - google.protobuf.Struct optional_transaction_metadata = 5 [(validate.rules).message.required = false]; + google.protobuf.Struct optional_transaction_metadata = 5 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; } message DeleteRelationshipsResponse { @@ -345,20 +437,35 @@ message CheckPermissionRequest { Consistency consistency = 1; // resource is the resource on which to check the permission or relation. - ObjectReference resource = 2 [(validate.rules).message.required = true]; + ObjectReference resource = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // permission is the name of the permission (or relation) on which to execute // the check. - string permission = 3 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string permission = 3 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; // subject is the subject that will be checked for the permission or relation. - SubjectReference subject = 4 [(validate.rules).message.required = true]; + SubjectReference subject = 4 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // context consists of named values that are injected into the caveat evaluation context - google.protobuf.Struct context = 5 [(validate.rules).message.required = false]; + google.protobuf.Struct context = 5 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; // with_tracing, if true, indicates that the response should include a debug trace. // This can be useful for debugging and performance analysis, but adds a small amount @@ -374,7 +481,10 @@ message CheckPermissionResponse { PERMISSIONSHIP_CONDITIONAL_PERMISSION = 3; } - ZedToken checked_at = 1 [(validate.rules).message.required = false]; + ZedToken checked_at = 1 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; // Permissionship communicates whether or not the subject has the requested // permission or has a relationship with the given resource, over the given @@ -384,13 +494,22 @@ message CheckPermissionResponse { // requested subject is a member of the computed permission set or there // exists a relationship with the requested relation from the given resource // to the given subject. - Permissionship permissionship = 2 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; + Permissionship permissionship = 2 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; // partial_caveat_info holds information of a partially-evaluated caveated response - PartialCaveatInfo partial_caveat_info = 3 [(validate.rules).message.required = false]; + PartialCaveatInfo partial_caveat_info = 3 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; // debug_trace is the debugging trace of this check, if requested. DebugInformation debug_trace = 4; @@ -404,26 +523,50 @@ message CheckPermissionResponse { message CheckBulkPermissionsRequest { Consistency consistency = 1; - repeated CheckBulkPermissionsRequestItem items = 2 [(validate.rules).repeated.items.message.required = true]; + repeated CheckBulkPermissionsRequestItem items = 2 [ + (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true + ]; } message CheckBulkPermissionsRequestItem { - ObjectReference resource = 1 [(validate.rules).message.required = true]; + ObjectReference resource = 1 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; - string permission = 2 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string permission = 2 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; - SubjectReference subject = 3 [(validate.rules).message.required = true]; + SubjectReference subject = 3 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; - google.protobuf.Struct context = 4 [(validate.rules).message.required = false]; + google.protobuf.Struct context = 4 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; } message CheckBulkPermissionsResponse { - ZedToken checked_at = 1 [(validate.rules).message.required = false]; + ZedToken checked_at = 1 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; - repeated CheckBulkPermissionsPair pairs = 2 [(validate.rules).repeated.items.message.required = true]; + repeated CheckBulkPermissionsPair pairs = 2 [ + (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true + ]; } message CheckBulkPermissionsPair { @@ -435,12 +578,21 @@ message CheckBulkPermissionsPair { } message CheckBulkPermissionsResponseItem { - CheckPermissionResponse.Permissionship permissionship = 1 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; + CheckPermissionResponse.Permissionship permissionship = 1 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; - PartialCaveatInfo partial_caveat_info = 2 [(validate.rules).message.required = false]; + PartialCaveatInfo partial_caveat_info = 2 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; } // ExpandPermissionTreeRequest returns a tree representing the expansion of all @@ -454,14 +606,23 @@ message ExpandPermissionTreeRequest { Consistency consistency = 1; // resource is the resource over which to run the expansion. - ObjectReference resource = 2 [(validate.rules).message.required = true]; + ObjectReference resource = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // permission is the name of the permission or relation over which to run the // expansion for the resource. - string permission = 3 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string permission = 3 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; } message ExpandPermissionTreeResponse { @@ -481,29 +642,50 @@ message LookupResourcesRequest { // resource_object_type is the type of resource object for which the IDs will // be returned. - string resource_object_type = 2 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 128 - }]; + string resource_object_type = 2 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + } + ]; // permission is the name of the permission or relation for which the subject // must Check. - string permission = 3 [(validate.rules).string = { - pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 64 - }]; + string permission = 3 [ + (validate.rules).string = { + pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 64 + } + ]; // subject is the subject with access to the resources. - SubjectReference subject = 4 [(validate.rules).message.required = true]; + SubjectReference subject = 4 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // context consists of named values that are injected into the caveat evaluation context - google.protobuf.Struct context = 5 [(validate.rules).message.required = false]; + google.protobuf.Struct context = 5 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; // optional_limit, if non-zero, specifies the limit on the number of resources to return // before the stream is closed on the server side. By default, the stream will continue // resolving resources until exhausted or the stream is closed due to the client or a // network issue. - uint32 optional_limit = 6 [(validate.rules).uint32 = {gte: 0}]; + uint32 optional_limit = 6 [ + (validate.rules).uint32 = {gte: 0}, + (buf.validate.field).uint32 = {gte: 0} + ]; // optional_cursor, if specified, indicates the cursor after which results should resume being returned. // The cursor can be found on the LookupResourcesResponse object. @@ -527,13 +709,22 @@ message LookupResourcesResponse { string resource_object_id = 2; // permissionship indicates whether the response was partially evaluated or not - LookupPermissionship permissionship = 3 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; + LookupPermissionship permissionship = 3 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; // partial_caveat_info holds information of a partially-evaluated caveated response - PartialCaveatInfo partial_caveat_info = 4 [(validate.rules).message.required = false]; + PartialCaveatInfo partial_caveat_info = 4 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; // after_result_cursor holds a cursor that can be used to resume the LookupResources stream after this // result. @@ -554,30 +745,54 @@ message LookupSubjectsRequest { // resource is the resource for which all matching subjects for the permission // or relation will be returned. - ObjectReference resource = 2 [(validate.rules).message.required = true]; + ObjectReference resource = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; // permission is the name of the permission (or relation) for which to find // the subjects. - string permission = 3 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string permission = 3 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; // subject_object_type is the type of subject object for which the IDs will // be returned. - string subject_object_type = 4 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 128 - }]; + string subject_object_type = 4 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + } + ]; // optional_subject_relation is the optional relation for the subject. - string optional_subject_relation = 5 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" - max_bytes: 64 - }]; + string optional_subject_relation = 5 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$" + max_bytes: 64 + } + ]; // context consists of named values that are injected into the caveat evaluation context - google.protobuf.Struct context = 6 [(validate.rules).message.required = false]; + google.protobuf.Struct context = 6 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; // optional_concrete_limit, if non-zero, specifies the limit on the number of // *concrete* (non-wildcard) subjects to return before the stream is closed on the @@ -599,7 +814,10 @@ message LookupSubjectsRequest { // for each invocation of the API. // // ***IT IS UP TO THE CALLER IN THIS CASE TO COMBINE THE EXCLUSIONS IF DESIRED*** - uint32 optional_concrete_limit = 7 [(validate.rules).uint32 = {gte: 0}]; + uint32 optional_concrete_limit = 7 [ + (validate.rules).uint32 = {gte: 0}, + (buf.validate.field).uint32 = {gte: 0} + ]; // optional_cursor, if specified, indicates the cursor after which results should resume being returned. // The cursor can be found on the LookupSubjectsResponse object. @@ -635,6 +853,10 @@ message LookupSubjectsResponse { (validate.rules).enum = { defined_only: true not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] } ]; @@ -642,7 +864,8 @@ message LookupSubjectsResponse { // deprecated: use `subject.partial_caveat_info` PartialCaveatInfo partial_caveat_info = 5 [ deprecated = true, - (validate.rules).message.required = false + (validate.rules).message.required = false, + (buf.validate.field).required = false ]; // subject is the subject found, along with its permissionship. @@ -665,13 +888,22 @@ message ResolvedSubject { string subject_object_id = 1; // permissionship indicates whether the response was partially evaluated or not - LookupPermissionship permissionship = 2 [(validate.rules).enum = { - defined_only: true - not_in: [0] - }]; + LookupPermissionship permissionship = 2 [ + (validate.rules).enum = { + defined_only: true + not_in: [0] + }, + (buf.validate.field).enum = { + defined_only: true + not_in: [0] + } + ]; // partial_caveat_info holds information of a partially-evaluated caveated response - PartialCaveatInfo partial_caveat_info = 3 [(validate.rules).message.required = false]; + PartialCaveatInfo partial_caveat_info = 3 [ + (validate.rules).message.required = false, + (buf.validate.field).required = false + ]; } // ImportBulkRelationshipsRequest represents one batch of the streaming @@ -682,7 +914,10 @@ message ResolvedSubject { // invocation are executed under this single transaction. If a relationship already // exists within the datastore, the entire transaction will fail with an error. message ImportBulkRelationshipsRequest { - repeated Relationship relationships = 1 [(validate.rules).repeated.items.message.required = true]; + repeated Relationship relationships = 1 [ + (validate.rules).repeated.items.message.required = true, + (buf.validate.field).repeated.items.required = true + ]; } // ImportBulkRelationshipsResponse is returned on successful completion of the @@ -700,7 +935,10 @@ message ExportBulkRelationshipsRequest { // relationships the server can return in one page. By default, the server // will pick a page size, and the server is free to choose a smaller size // at will. - uint32 optional_limit = 2 [(validate.rules).uint32 = {gte: 0}]; + uint32 optional_limit = 2 [ + (validate.rules).uint32 = {gte: 0}, + (buf.validate.field).uint32 = {gte: 0} + ]; // optional_cursor, if specified, indicates the cursor after which results // should resume being returned. The cursor can be found on the diff --git a/authzed/api/v1/schema_service.proto b/authzed/api/v1/schema_service.proto index 876f79c..3ebaa10 100644 --- a/authzed/api/v1/schema_service.proto +++ b/authzed/api/v1/schema_service.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package authzed.api.v1; import "authzed/api/v1/core.proto"; +import "buf/validate/validate.proto"; import "google/api/annotations.proto"; import "validate/validate.proto"; @@ -42,7 +43,10 @@ message ReadSchemaResponse { string schema_text = 1; // read_at is the ZedToken at which the schema was read. - ZedToken read_at = 2 [(validate.rules).message.required = true]; + ZedToken read_at = 2 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; } // WriteSchemaRequest is the required data used to "upsert" the Schema of a @@ -50,12 +54,18 @@ message ReadSchemaResponse { message WriteSchemaRequest { // The Schema containing one or more Object Definitions that will be written // to the Permissions System. - string schema = 1 [(validate.rules).string.max_bytes = 4194304]; // 4MiB + string schema = 1 [ + (validate.rules).string.max_bytes = 4194304, + (buf.validate.field).string.max_bytes = 4194304 + ]; // 4MiB } // WriteSchemaResponse is the resulting data after having written a Schema to // a Permissions System. message WriteSchemaResponse { // written_at is the ZedToken at which the schema was written. - ZedToken written_at = 1 [(validate.rules).message.required = true]; + ZedToken written_at = 1 [ + (validate.rules).message.required = true, + (buf.validate.field).required = true + ]; } diff --git a/authzed/api/v1/watch_service.proto b/authzed/api/v1/watch_service.proto index 7a7e54a..79706f9 100644 --- a/authzed/api/v1/watch_service.proto +++ b/authzed/api/v1/watch_service.proto @@ -3,6 +3,7 @@ package authzed.api.v1; import "authzed/api/v1/core.proto"; import "authzed/api/v1/permission_service.proto"; +import "buf/validate/validate.proto"; import "google/api/annotations.proto"; import "google/protobuf/struct.proto"; import "validate/validate.proto"; @@ -29,11 +30,18 @@ message WatchRequest { // optional_relationship_filters cannot be used. repeated string optional_object_types = 1 [ (validate.rules).repeated.min_items = 0, + (buf.validate.field).repeated.min_items = 0, (validate.rules).repeated.items.string = { pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9]/" ")*[a-z][a-z0-9_]{1,62}[a-z0-9]$" max_bytes: 128 + }, + (buf.validate.field).repeated.items.string = { + pattern: + "^([a-z][a-z0-9_]{1,62}[a-z0-9]/" + ")*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 } ]; diff --git a/authzed/api/v1alpha1/schema.proto b/authzed/api/v1alpha1/schema.proto index 046a6f4..27b564a 100644 --- a/authzed/api/v1alpha1/schema.proto +++ b/authzed/api/v1alpha1/schema.proto @@ -1,6 +1,7 @@ syntax = "proto3"; package authzed.api.v1alpha1; +import "buf/validate/validate.proto"; import "validate/validate.proto"; option go_package = "github.com/authzed/authzed-go/proto/authzed/api/v1alpha1"; @@ -28,10 +29,16 @@ message ReadSchemaRequest { // // These names must be fully qualified with their namespace (e.g. // myblog/post). - repeated string object_definitions_names = 1 [(validate.rules).repeated.items.string = { - pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 128 - }]; + repeated string object_definitions_names = 1 [ + (validate.rules).repeated.items.string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + }, + (buf.validate.field).repeated.items.string = { + pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + } + ]; } // ReadSchemaResponse is the resulting data after having read the Object @@ -49,7 +56,10 @@ message ReadSchemaResponse { message WriteSchemaRequest { // The Schema containing one or more Object Definitions that will be written // to the Permissions System. - string schema = 1 [(validate.rules).string.max_bytes = 262144]; // 256KiB + string schema = 1 [ + (validate.rules).string.max_bytes = 262144, + (buf.validate.field).string.max_bytes = 262144 + ]; // 256KiB // If specified, the existing revision of object definitions in the schema that must be present for // the write to succeed. If the revision specified differs (i.e. the underlying schema has changed), diff --git a/authzed/api/v1alpha1/watchresources_service.proto b/authzed/api/v1alpha1/watchresources_service.proto index 255944e..fe610fa 100644 --- a/authzed/api/v1alpha1/watchresources_service.proto +++ b/authzed/api/v1alpha1/watchresources_service.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package authzed.api.v1alpha1; import "authzed/api/v1/core.proto"; +import "buf/validate/validate.proto"; import "google/api/annotations.proto"; import "validate/validate.proto"; @@ -26,17 +27,29 @@ service WatchResourcesService { message WatchResourcesRequest { // resource_object_type is the type of resource object for which we will // watch for changes. - string resource_object_type = 1 [(validate.rules).string = { - pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 128 - }]; + string resource_object_type = 1 [ + (validate.rules).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + }, + (buf.validate.field).string = { + pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 128 + } + ]; // permission is the name of the permission or relation for which we will // watch for changes. - string permission = 2 [(validate.rules).string = { - pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$" - max_bytes: 64 - }]; + string permission = 2 [ + (validate.rules).string = { + pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 64 + }, + (buf.validate.field).string = { + pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$" + max_bytes: 64 + } + ]; // subject_object_type is the type of the subject resource for which we will // watch for changes. diff --git a/buf.lock b/buf.lock index e098f10..35335dc 100644 --- a/buf.lock +++ b/buf.lock @@ -1,12 +1,15 @@ # Generated by buf. DO NOT EDIT. version: v2 deps: + - name: buf.build/bufbuild/protovalidate + commit: 5a7b106cbb87462d9a8c9ffecdbd2e38 + digest: b5:0f2dc6c9453e9cc9e9f36807aaa5f94022e837d91fef4dcaeed79a35c0843cc64eba28ff077aab24da3b2cb12639ad256246f9f9a36c033b99d5754b19996b7e - name: buf.build/envoyproxy/protoc-gen-validate - commit: 45685e052c7e406b9fbd441fc7a568a5 - digest: b5:63939effe0c64a94cd3151770b73007e43c9aeff31dcb24737fb11750dcaaca99338df3c1e5513828a685c743712e59ce283e046c27725e96928d200492bb6ec + commit: daf171c6cdb54629b5f51e345a79e4dd + digest: b5:c745e1521879f43740230b1df673d0729f55704efefdcfc489d4a0a2d40c92a26cacfeab62813403040a8b180142d53b398c7ca784a065e43823605ee49681de - name: buf.build/googleapis/googleapis - commit: 62f35d8aed1149c291d606d958a7ce32 - digest: b5:d66bf04adc77a0870bdc9328aaf887c7188a36fb02b83a480dc45ef9dc031b4d39fc6e9dc6435120ccf4fe5bfd5c6cb6592533c6c316595571f9a31420ab47fe + commit: c0913f24652a4cfc95f77d97443a5005 + digest: b5:4edb1480036c60f7867d75417d7faa87c851c96a4988a9746058a24e8e9bb4978daed0af35d57f6043de5a60355978dceaaa93dc992be99193260ac8823cbb8f - name: buf.build/grpc-ecosystem/grpc-gateway - commit: bc28b723cd774c32b6fbc77621518765 - digest: b5:a613f827fa6ff35a4f5e87e80e35ac6b35e5792cc9c5a658351072777d88c6d4df785a0c14889090db11667cf5463d122c7193b3719c7861d3e5747c22ce1381 + commit: a48fcebcf8f140dd9d09359b9bb185a4 + digest: b5:330af8a71b579ab96c4f3ee26929d1a68a5a9e986c7cfe0a898591fc514216bb6e723dc04c74d90fdee3f3f14f9100a54b4f079eb273e6e7213f0d5baca36ff8 diff --git a/buf.yaml b/buf.yaml index ad6a3f7..d9f1b0c 100644 --- a/buf.yaml +++ b/buf.yaml @@ -2,6 +2,7 @@ version: "v2" name: "buf.build/authzed/api" deps: + - "buf.build/envoyproxy/protoc-gen-validate" - "buf.build/bufbuild/protovalidate" - "buf.build/googleapis/googleapis" - "buf.build/grpc-ecosystem/grpc-gateway"