diff --git a/authzed/api/v1/error_reason.proto b/authzed/api/v1/error_reason.proto index bbeedf9..1526852 100644 --- a/authzed/api/v1/error_reason.proto +++ b/authzed/api/v1/error_reason.proto @@ -299,4 +299,18 @@ enum ErrorReason { // "metadata": {} // } ERROR_REASON_SERIALIZATION_FAILURE = 20; + + // The request contained more check items than the maximum configured. + // + // Example of an ErrorInfo: + // + // { + // "reason": "ERROR_REASON_TOO_MANY_CHECKS_IN_REQUEST", + // "domain": "authzed.com", + // "metadata": { + // "check_count": "525", + // "maximum_checks_allowed": "500", + // } + // } + ERROR_REASON_TOO_MANY_CHECKS_IN_REQUEST = 21; } \ No newline at end of file diff --git a/authzed/api/v1/experimental_service.proto b/authzed/api/v1/experimental_service.proto index efa6b32..d24e1c8 100644 --- a/authzed/api/v1/experimental_service.proto +++ b/authzed/api/v1/experimental_service.proto @@ -45,12 +45,12 @@ service ExperimentalService { } rpc BulkCheckPermission(BulkCheckPermissionRequest) - returns (BulkCheckPermissionResponse) { - option (google.api.http) = { - post: "/v1/experimental/permissions/bulkcheckpermission" - body: "*" - }; - } + returns (BulkCheckPermissionResponse) { + option (google.api.http) = { + post: "/v1/experimental/permissions/bulkcheckpermission" + body: "*" + }; + } } message BulkCheckPermissionRequest { @@ -87,7 +87,6 @@ message BulkCheckPermissionPair { } message BulkCheckPermissionResponseItem { - CheckPermissionResponse.Permissionship permissionship = 1 [ (validate.rules).enum = {defined_only: true, not_in: [0]} ]; PartialCaveatInfo partial_caveat_info = 2 [ (validate.rules).message.required = false ]; diff --git a/authzed/api/v1/permission_service.proto b/authzed/api/v1/permission_service.proto index e28b73e..391b6c7 100644 --- a/authzed/api/v1/permission_service.proto +++ b/authzed/api/v1/permission_service.proto @@ -6,6 +6,7 @@ option java_package = "com.authzed.api.v1"; import "google/protobuf/struct.proto"; import "google/api/annotations.proto"; +import "google/rpc/status.proto"; import "validate/validate.proto"; import "authzed/api/v1/core.proto"; @@ -56,6 +57,16 @@ service PermissionsService { }; } + // CheckBulkPermissions evaluates the given list of permission checks + // and returns the list of results. + rpc CheckBulkPermissions(CheckBulkPermissionsRequest) + returns (CheckBulkPermissionsResponse) { + option (google.api.http) = { + post: "/v1/permissions/checkbulk" + 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. @@ -349,6 +360,50 @@ message CheckPermissionResponse { PartialCaveatInfo partial_caveat_info = 3 [ (validate.rules).message.required = false ]; } +// CheckBulkPermissionsRequest issues a check on whether a subject has permission +// or is a member of a relation on a specific resource for each item in the list. +// +// The ordering of the items in the response is maintained in the response. +// Checks with the same subject/permission will automatically be batched for performance optimization. +message CheckBulkPermissionsRequest { + Consistency consistency = 1; + + repeated CheckBulkPermissionsRequestItem items = 2 [ (validate.rules).repeated .items.message.required = true ]; +} + +message CheckBulkPermissionsRequestItem { + ObjectReference resource = 1 [ (validate.rules).message.required = true ]; + + string permission = 2 [ (validate.rules).string = { + pattern : "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$", + max_bytes : 64, + } ]; + + SubjectReference subject = 3 [ (validate.rules).message.required = true ]; + + google.protobuf.Struct context = 4 [ (validate.rules).message.required = false ]; +} + +message CheckBulkPermissionsResponse { + ZedToken checked_at = 1 [ (validate.rules).message.required = false ]; + + repeated CheckBulkPermissionsPair pairs = 2 [ (validate.rules).repeated .items.message.required = true ]; +} + +message CheckBulkPermissionsPair { + CheckBulkPermissionsRequestItem request = 1; + oneof response { + CheckBulkPermissionsResponseItem item = 2; + google.rpc.Status error = 3; + } +} + +message CheckBulkPermissionsResponseItem { + CheckPermissionResponse.Permissionship permissionship = 1 [ (validate.rules).enum = {defined_only: true, not_in: [0]} ]; + + PartialCaveatInfo partial_caveat_info = 2 [ (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.