syntax = "proto3"; package openfga.v1; import "google/api/field_behavior.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/timestamp.proto"; import "protoc-gen-openapiv2/options/annotations.proto"; import "validate/validate.proto"; // Object represents an OpenFGA Object. // // An Object is composed of a type and identifier (e.g. 'document:1') // // See https://openfga.dev/docs/concepts#what-is-an-object message Object { string type = 1 [ (validate.rules).string = { pattern: "^[^:#@\\s]{1,254}$", ignore_empty: false }, (google.api.field_behavior) = REQUIRED, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {example: "\"document\""} ]; string id = 2 [ (validate.rules).string = { pattern: "[^#:\\s]+$", ignore_empty: false }, (google.api.field_behavior) = REQUIRED ]; } message RelationshipCondition { // A reference (by name) of the relationship condition defined in the authorization model. string name = 1 [ (validate.rules).string = { pattern: "^[^\\s]{2,256}$", ignore_empty: false }, (google.api.field_behavior) = REQUIRED, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { max_length: 256, example: "\"condition1\"" } ]; // Additional context/data to persist along with the condition. // The keys must match the parameters defined by the condition, and the value types must // match the parameter type definitions. google.protobuf.Struct context = 2; } message TupleKeyWithoutCondition { string user = 1 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = {max_bytes: 512}, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { max_length: 512, example: "\"user:anne\"" } ]; string relation = 2 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = { pattern: "^[^:#@\\s]{1,50}$", ignore_empty: true }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { max_length: 50, example: "\"reader\"" } ]; string object = 3 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = { pattern: "^[^\\s]{2,256}$", ignore_empty: true }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { max_length: 256, example: "\"document:2021-budget\"" } ]; } message TupleKey { string user = 1 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = { max_bytes: 512, ignore_empty: false }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { max_length: 512, example: "\"user:anne\"" } ]; string relation = 2 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = { pattern: "^[^:#@\\s]{1,50}$", ignore_empty: true }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { max_length: 50, example: "\"reader\"" } ]; string object = 3 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = { pattern: "^[^\\s]{2,256}$", ignore_empty: true }, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { max_length: 256, example: "\"document:2021-budget\"" } ]; RelationshipCondition condition = 4; } message Tuple { TupleKey key = 1 [ (google.api.field_behavior) = REQUIRED, (validate.rules).message.required = true ]; google.protobuf.Timestamp timestamp = 2 [(google.api.field_behavior) = REQUIRED]; } message TupleKeys { repeated TupleKey tuple_keys = 1 [ json_name = "tuple_keys", (google.api.field_behavior) = REQUIRED, (validate.rules).repeated.min_items = 1, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {minimum: 1} ]; } message ContextualTupleKeys { repeated TupleKey tuple_keys = 1 [ json_name = "tuple_keys", (google.api.field_behavior) = REQUIRED, (validate.rules).repeated.max_items = 20, (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {maximum: 20} ]; } // A UsersetTree contains the result of an Expansion. message UsersetTree { // A leaf node contains either // - a set of users (which may be individual users, or usersets // referencing other relations) // - a computed node, which is the result of a computed userset // value in the authorization model // - a tupleToUserset nodes, containing the result of expanding // a tupleToUserset value in a authorization model. message Leaf { oneof value { Users users = 1; Computed computed = 2; TupleToUserset tuple_to_userset = 3; } } message Nodes { repeated Node nodes = 1 [(google.api.field_behavior) = REQUIRED]; } message Users { repeated string users = 1 [(google.api.field_behavior) = REQUIRED]; } message Computed { string userset = 1 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = {ignore_empty: false} ]; } message TupleToUserset { string tupleset = 1 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = {ignore_empty: false} ]; repeated Computed computed = 2 [(google.api.field_behavior) = REQUIRED]; } message Difference { Node base = 1 [ (google.api.field_behavior) = REQUIRED, (validate.rules).message.required = true ]; Node subtract = 2 [ (google.api.field_behavior) = REQUIRED, (validate.rules).message.required = true ]; } message Node { string name = 1 [(google.api.field_behavior) = REQUIRED]; oneof value { Leaf leaf = 2; Difference difference = 5; Nodes union = 6; Nodes intersection = 7; } } Node root = 1; } // buf:lint:ignore ENUM_ZERO_VALUE_SUFFIX enum TupleOperation { TUPLE_OPERATION_WRITE = 0; TUPLE_OPERATION_DELETE = 1; } message TupleChange { TupleKey tuple_key = 1 [ json_name = "tuple_key", (google.api.field_behavior) = REQUIRED, (validate.rules).message.required = true ]; TupleOperation operation = 2 [ (validate.rules).enum.defined_only = true, (google.api.field_behavior) = REQUIRED ]; google.protobuf.Timestamp timestamp = 3 [(google.api.field_behavior) = REQUIRED]; } message Store { string id = 1 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = {ignore_empty: false} ]; string name = 2 [ (google.api.field_behavior) = REQUIRED, (validate.rules).string = {ignore_empty: false} ]; google.protobuf.Timestamp created_at = 3 [ json_name = "created_at", (google.api.field_behavior) = REQUIRED ]; google.protobuf.Timestamp updated_at = 4 [ json_name = "updated_at", (google.api.field_behavior) = REQUIRED ]; google.protobuf.Timestamp deleted_at = 5 [json_name = "deleted_at"]; }