aboutsummaryrefslogtreecommitdiff
path: root/crates/secd/proto/authzed/api/v1/permission_service.proto
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--crates/secd/proto/authzed/api/v1/permission_service.proto438
1 files changed, 438 insertions, 0 deletions
diff --git a/crates/secd/proto/authzed/api/v1/permission_service.proto b/crates/secd/proto/authzed/api/v1/permission_service.proto
new file mode 100644
index 0000000..859d0d0
--- /dev/null
+++ b/crates/secd/proto/authzed/api/v1/permission_service.proto
@@ -0,0 +1,438 @@
+syntax = "proto3";
+package authzed.api.v1;
+
+option go_package = "github.com/authzed/authzed-go/proto/authzed/api/v1";
+option java_package = "com.authzed.api.v1";
+
+import "google/protobuf/struct.proto";
+import "google/api/annotations.proto";
+import "validate/validate.proto";
+
+import "authzed/api/v1/core.proto";
+
+// PermissionsService implements a set of RPCs that perform operations on
+// relationships and permissions.
+service PermissionsService {
+ // ReadRelationships reads a set of the relationships matching one or more
+ // filters.
+ rpc ReadRelationships(ReadRelationshipsRequest)
+ returns (stream ReadRelationshipsResponse) {
+ option (google.api.http) = {
+ post: "/v1/relationships/read"
+ body: "*"
+ };
+ }
+
+ // WriteRelationships atomically writes and/or deletes a set of specified
+ // relationships. An optional set of preconditions can be provided that must
+ // be satisfied for the operation to commit.
+ rpc WriteRelationships(WriteRelationshipsRequest)
+ returns (WriteRelationshipsResponse) {
+ option (google.api.http) = {
+ post: "/v1/relationships/write"
+ body: "*"
+ };
+ }
+
+ // DeleteRelationships atomically bulk deletes all relationships matching the
+ // provided filter. If no relationships match, none will be deleted and the
+ // operation will succeed. An optional set of preconditions can be provided that must
+ // be satisfied for the operation to commit.
+ rpc DeleteRelationships(DeleteRelationshipsRequest)
+ returns (DeleteRelationshipsResponse) {
+ option (google.api.http) = {
+ post: "/v1/relationships/delete"
+ body: "*"
+ };
+ }
+
+ // CheckPermission determines for a given resource whether a subject computes
+ // to having a permission or is a direct member of a particular relation.
+ rpc CheckPermission(CheckPermissionRequest)
+ returns (CheckPermissionResponse) {
+ option (google.api.http) = {
+ post: "/v1/permissions/check"
+ body: "*"
+ };
+ }
+
+ // ExpandPermissionTree reveals the graph structure for a resource's
+ // permission or relation. This RPC does not recurse infinitely deep and may
+ // require multiple calls to fully unnest a deeply nested graph.
+ rpc ExpandPermissionTree(ExpandPermissionTreeRequest)
+ returns (ExpandPermissionTreeResponse) {
+ option (google.api.http) = {
+ post: "/v1/permissions/expand"
+ body: "*"
+ };
+ }
+
+ // LookupResources returns all the resources of a given type that a subject
+ // can access whether via a computed permission or relation membership.
+ rpc LookupResources(LookupResourcesRequest)
+ returns (stream LookupResourcesResponse) {
+ option (google.api.http) = {
+ post: "/v1/permissions/resources"
+ body: "*"
+ };
+ }
+
+ // LookupSubjects returns all the subjects of a given type that
+ // have access whether via a computed permission or relation membership.
+ rpc LookupSubjects(LookupSubjectsRequest)
+ returns (stream LookupSubjectsResponse) {
+ option (google.api.http) = {
+ post: "/v1/permissions/subjects"
+ body: "*"
+ };
+ }
+}
+
+// Consistency will define how a request is handled by the backend.
+// By defining a consistency requirement, and a token at which those
+// requirements should be applied, where applicable.
+message Consistency {
+ oneof requirement {
+ option (validate.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 ];
+
+ // 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
+ // be used if available or faster.
+ ZedToken at_least_as_fresh = 2;
+
+ // at_exact_snapshot indicates that all data used in the API call must be
+ // *at the given* snapshot in time; if the snapshot is no longer available,
+ // an error will be returned to the caller.
+ ZedToken at_exact_snapshot = 3;
+
+ // fully_consistent indicates that all data used in the API call *must* be
+ // at the most recent snapshot found.
+ //
+ // 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 ];
+ }
+}
+
+// RelationshipFilter is a collection of filters which when applied to a
+// relationship will return relationships that have exactly matching fields.
+//
+// resource_type is required. All other fields are optional and if left
+// unspecified will not filter relationships.
+message RelationshipFilter {
+ 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 optional_resource_id = 2 [ (validate.rules).string = {
+ pattern : "^([a-zA-Z0-9_][a-zA-Z0-9/_|-]{0,127})?$",
+ max_bytes : 128,
+ } ];
+
+ string optional_relation = 3 [ (validate.rules).string = {
+ pattern : "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$",
+ max_bytes : 64,
+ } ];
+
+ SubjectFilter optional_subject_filter = 4;
+}
+
+// SubjectFilter specifies a filter on the subject of a relationship.
+//
+// subject_type is required and all other fields are optional, and will not
+// 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 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 optional_subject_id = 2 [ (validate.rules).string = {
+ pattern : "^(([a-zA-Z0-9_][a-zA-Z0-9/_|-]{0,127})|\\*)?$",
+ max_bytes : 128,
+ } ];
+
+ RelationFilter optional_relation = 3;
+}
+
+// ReadRelationshipsRequest specifies one or more filters used to read matching
+// relationships within the system.
+message ReadRelationshipsRequest {
+ Consistency consistency = 1;
+ RelationshipFilter relationship_filter = 2
+ [ (validate.rules).message.required = true ];
+}
+
+// ReadRelationshipsResponse contains a Relationship found that matches the
+// specified relationship filter(s). A instance of this response message will
+// be streamed to the client for each relationship found.
+message ReadRelationshipsResponse {
+ ZedToken read_at = 1 [ (validate.rules).message.required = true ];
+ Relationship relationship = 2 [ (validate.rules).message.required = true ];
+}
+
+// Precondition specifies how and the existence or absence of certain
+// relationships as expressed through the accompanying filter should affect
+// whether or not the operation proceeds.
+//
+// MUST_NOT_MATCH will fail the parent request if any relationships match the
+// relationships filter.
+// MUST_MATCH will fail the parent request if there are no
+// relationships that match the filter.
+message Precondition {
+ enum Operation {
+ OPERATION_UNSPECIFIED = 0;
+ OPERATION_MUST_NOT_MATCH = 1;
+ OPERATION_MUST_MATCH = 2;
+ }
+
+ Operation operation = 1 [ (validate.rules).enum = {defined_only: true, not_in: [0]} ];
+ RelationshipFilter filter = 2 [ (validate.rules).message.required = true ];
+}
+
+// WriteRelationshipsRequest contains a list of Relationship mutations that
+// should be applied to the service. If the optional_preconditions parameter
+// is included, all of the specified preconditions must also be satisfied before
+// the write will be committed.
+message WriteRelationshipsRequest {
+ repeated RelationshipUpdate updates = 1
+ [ (validate.rules).repeated .items.message.required = true ];
+
+ repeated Precondition optional_preconditions = 2
+ [ (validate.rules).repeated .items.message.required =
+ true ]; // To be bounded by configuration
+}
+
+message WriteRelationshipsResponse { ZedToken written_at = 1; }
+
+// DeleteRelationshipsRequest specifies which Relationships should be deleted,
+// requesting the delete of *ALL* relationships that match the specified
+// filters. If the optional_preconditions parameter is included, all of the
+// specified preconditions must also be satisfied before the delete will be
+// executed.
+message DeleteRelationshipsRequest {
+ RelationshipFilter relationship_filter = 1
+ [ (validate.rules).message.required = true ];
+
+ repeated Precondition optional_preconditions = 2
+ [ (validate.rules).repeated .items.message.required =
+ true ]; // To be bounded by configuration
+}
+
+message DeleteRelationshipsResponse { ZedToken deleted_at = 1; }
+
+// CheckPermissionRequest issues a check on whether a subject has a permission
+// or is a member of a relation, on a specific resource.
+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 ];
+
+ // 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,
+ } ];
+
+ // subject is the subject that will be checked for the permission or relation.
+ SubjectReference subject = 4 [ (validate.rules).message.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 ];
+}
+
+message CheckPermissionResponse {
+ enum Permissionship {
+ PERMISSIONSHIP_UNSPECIFIED = 0;
+ PERMISSIONSHIP_NO_PERMISSION = 1;
+ PERMISSIONSHIP_HAS_PERMISSION = 2;
+ PERMISSIONSHIP_CONDITIONAL_PERMISSION = 3;
+ }
+
+ ZedToken checked_at = 1 [ (validate.rules).message.required = false ];
+
+ // Permissionship communicates whether or not the subject has the requested
+ // permission or has a relationship with the given resource, over the given
+ // relation.
+ //
+ // This value will be authzed.api.v1.PERMISSIONSHIP_HAS_PERMISSION if the
+ // 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]} ];
+
+ // partial_caveat_info holds information of a partially-evaluated caveated response
+ PartialCaveatInfo partial_caveat_info = 3 [ (validate.rules).message.required = false ];
+}
+
+// ExpandPermissionTreeRequest returns a tree representing the expansion of all
+// relationships found accessible from a permission or relation on a particular
+// resource.
+//
+// ExpandPermissionTreeRequest is typically used to determine the full set of
+// subjects with a permission, along with the relationships that grant said
+// access.
+message ExpandPermissionTreeRequest {
+ Consistency consistency = 1;
+
+ // resource is the resource over which to run the expansion.
+ ObjectReference resource = 2 [ (validate.rules).message.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,
+ } ];
+}
+
+message ExpandPermissionTreeResponse {
+ ZedToken expanded_at = 1;
+
+ // tree_root is a tree structure whose leaf nodes are subjects, and
+ // intermediate nodes represent the various operations (union, intersection,
+ // exclusion) to reach those subjects.
+ PermissionRelationshipTree tree_root = 2;
+}
+
+// LookupResourcesRequest performs a lookup of all resources of a particular
+// kind on which the subject has the specified permission or the relation in
+// which the subject exists, streaming back the IDs of those resources.
+message LookupResourcesRequest {
+ Consistency consistency = 1;
+
+ // 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,
+ } ];
+
+ // 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,
+ } ];
+
+ // subject is the subject with access to the resources.
+ SubjectReference subject = 4 [ (validate.rules).message.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 ];
+}
+
+// LookupPermissionship represents whether a Lookup response was partially evaluated or not
+enum LookupPermissionship {
+ LOOKUP_PERMISSIONSHIP_UNSPECIFIED = 0;
+ LOOKUP_PERMISSIONSHIP_HAS_PERMISSION = 1;
+ LOOKUP_PERMISSIONSHIP_CONDITIONAL_PERMISSION = 2;
+}
+
+// LookupResourcesResponse contains a single matching resource object ID for the
+// requested object type, permission, and subject.
+message LookupResourcesResponse {
+ ZedToken looked_up_at = 1;
+ 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]} ];
+
+ // partial_caveat_info holds information of a partially-evaluated caveated response
+ PartialCaveatInfo partial_caveat_info = 4 [ (validate.rules).message.required = false ];
+}
+
+// LookupSubjectsRequest performs a lookup of all subjects of a particular
+// kind for which the subject has the specified permission or the relation in
+// which the subject exists, streaming back the IDs of those subjects.
+message LookupSubjectsRequest {
+ Consistency consistency = 1;
+
+ // 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 ];
+
+ // 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,
+ } ];
+
+ // 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,
+ } ];
+
+ // 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,
+ } ];
+
+ /** context consists of named values that are injected into the caveat evaluation context **/
+ google.protobuf.Struct context = 6 [ (validate.rules).message.required = false ];
+}
+
+// LookupSubjectsResponse contains a single matching subject object ID for the
+// requested subject object type on the permission or relation.
+message LookupSubjectsResponse {
+ ZedToken looked_up_at = 1;
+
+ // subject_object_id is the Object ID of the subject found. May be a `*` if
+ // a wildcard was found.
+ // deprecated: use `subject`
+ string subject_object_id = 2 [deprecated = true];
+
+ // excluded_subject_ids are the Object IDs of the subjects excluded. This list
+ // will only contain object IDs if `subject_object_id` is a wildcard (`*`) and
+ // will only be populated if exclusions exist from the wildcard.
+ // deprecated: use `excluded_subjects`
+ repeated string excluded_subject_ids = 3 [deprecated = true];
+
+ // permissionship indicates whether the response was partially evaluated or not
+ // deprecated: use `subject.permissionship`
+ LookupPermissionship permissionship = 4 [ deprecated = true, (validate.rules).enum = {defined_only: true, not_in: [0]} ];
+
+ // partial_caveat_info holds information of a partially-evaluated caveated response
+ // deprecated: use `subject.partial_caveat_info`
+ PartialCaveatInfo partial_caveat_info = 5 [ deprecated = true, (validate.rules).message.required = false ];
+
+ // subject is the subject found, along with its permissionship.
+ ResolvedSubject subject = 6;
+
+ // excluded_subjects are the subjects excluded. This list
+ // will only contain subjects if `subject.subject_object_id` is a wildcard (`*`) and
+ // will only be populated if exclusions exist from the wildcard.
+ repeated ResolvedSubject excluded_subjects = 7;
+}
+
+// ResolvedSubject is a single subject resolved within LookupSubjects.
+message ResolvedSubject {
+ // subject_object_id is the Object ID of the subject found. May be a `*` if
+ // a wildcard was found.
+ 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]} ];
+
+ // partial_caveat_info holds information of a partially-evaluated caveated response
+ PartialCaveatInfo partial_caveat_info = 3 [ (validate.rules).message.required = false ];
+} \ No newline at end of file