diff --git a/docker-compose.yaml b/docker-compose.yaml index f2e154b..1961ecf 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,5 +1,5 @@ services: permify: - image: "ghcr.io/permify/permify:v1.5.0" - ports: ['3478:3478'] + image: "ghcr.io/permify/permify:v1.6.0" + ports: ["3478:3478"] command: "serve" diff --git a/proto/base/v1/service.proto b/proto/base/v1/service.proto index 476aeda..f8f2aaf 100644 --- a/proto/base/v1/service.proto +++ b/proto/base/v1/service.proto @@ -150,6 +150,24 @@ service Permission { }; } + // BulkCheck method receives a PermissionBulkCheckRequest containing multiple check requests + // and returns a PermissionBulkCheckResponse with results for each request. + // Maximum 100 requests can be processed in a single bulk operation. + rpc BulkCheck(PermissionBulkCheckRequest) returns (PermissionBulkCheckResponse) { + // HTTP mapping for this method + option (google.api.http) = { + post: "/v1/tenants/{tenant_id}/permissions/bulk-check" + body: "*" + }; + // OpenAPI annotations for this method + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { + summary: "bulk check api" + tags: ["Permission"] + operation_id: "permissions.bulk-check" + description: "Check multiple permissions in a single request. Maximum 100 requests allowed." + }; + } + // Expand method receives a PermissionExpandRequest and returns a PermissionExpandResponse. // It expands relationships according to the schema provided. rpc Expand(PermissionExpandRequest) returns (PermissionExpandResponse) { @@ -852,6 +870,76 @@ message PermissionCheckResponseMetadata { int32 check_count = 1 [json_name = "check_count"]; } +// BULK CHECK +message PermissionBulkCheckRequestItem { + // Entity on which the permission needs to be checked, required. + Entity entity = 1 [ + json_name = "entity", + (validate.rules).message.required = true, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {example: "\"repository:1\""} + ]; + + // Name of the permission or relation, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. + string permission = 2 [ + json_name = "permission", + (validate.rules).string = { + pattern: "^[a-zA-Z_]{1,64}$" + max_bytes: 64 + ignore_empty: false + }, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "The action the user wants to perform on the resource"} + ]; + + // Subject for which the permission needs to be checked, required. + Subject subject = 3 [ + json_name = "subject", + (validate.rules).message.required = true + ]; +} +// PermissionBulkCheckRequest is the request message for the BulkCheck method in the Permission service. +message PermissionBulkCheckRequest { + // Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. + string tenant_id = 1 [ + json_name = "tenant_id", + (validate.rules).string = { + pattern: "^([a-zA-Z0-9_\\-@\\.:+]{1,128}|\\*)$" + max_bytes: 128 + ignore_empty: false + }, + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Identifier of the tenant, if you are not using multi-tenancy (have only one tenant) use pre-inserted tenant t1 for this field. Required, and must match the pattern \\“[a-zA-Z0-9-,]+\\“, max 64 bytes."} + ]; + + // Metadata associated with this request, required. + PermissionCheckRequestMetadata metadata = 2 [ + json_name = "metadata", + (validate.rules).message.required = true + ]; + + // List of permission check requests, maximum 100 items. + repeated PermissionBulkCheckRequestItem items = 3 [ + json_name = "items", + (validate.rules).repeated = { + min_items: 1 + max_items: 100 + } + ]; + + // Context associated with this request. + Context context = 4 [ + json_name = "context", + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "Contextual data that can be dynamically added to permission check requests. See details on [Contextual Data](../../operations/contextual-tuples)"} + ]; + + // Additional arguments associated with this request. + repeated Argument arguments = 5 [json_name = "arguments"]; +} + +// PermissionBulkCheckResponse is the response message for the BulkCheck method in the Permission service. +message PermissionBulkCheckResponse { + // List of permission check responses corresponding to each request. + repeated PermissionCheckResponse results = 1 [json_name = "results"]; +} + // EXPAND // PermissionExpandRequest is the request message for the Expand method in the Permission service. diff --git a/src/grpc-clients.test.ts b/src/grpc-clients.test.ts index 5c7b39f..52ca98d 100644 --- a/src/grpc-clients.test.ts +++ b/src/grpc-clients.test.ts @@ -1,20 +1,19 @@ import * as permify from "."; -import {Any} from "./grpc/generated/google/protobuf/any"; +import { Any } from "./grpc/generated/google/protobuf/any"; describe("clients test", () => { + it("permission client check", (done) => { + // Initialize the Permify gRPC client + let client = permify.grpc.newClient({ + endpoint: "localhost:3478", + cert: undefined, + pk: undefined, + certChain: undefined, + insecure: true, + }); - it("permission client check", (done) => { - // Initialize the Permify gRPC client - let client = permify.grpc.newClient({ - endpoint: "localhost:3478", - cert: undefined, - pk: undefined, - certChain: undefined, - insecure: true - }); - - // Define the schema - let schema = ` + // Define the schema + let schema = ` entity user {} entity document { @@ -24,57 +23,65 @@ describe("clients test", () => { } `; - // Write the schema - client.schema.write({ + // Write the schema + client.schema + .write({ + tenantId: "t1", + schema: schema, + }) + .then((response1_1: permify.grpc.payload.SchemaWriteResponse) => { + // Perform the permission check + client.permission + .check({ tenantId: "t1", - schema: schema - }).then((response1_1: permify.grpc.payload.SchemaWriteResponse) => { - // Perform the permission check - client.permission.check({ - tenantId: "t1", - metadata: { - snapToken: "", - schemaVersion: response1_1.schemaVersion, - depth: 20 - }, - entity: { - type: "document", - id: "1" - }, - permission: "view", - subject: { - type: "user", - id: "3" - } - }).then((response1_2: permify.grpc.payload.PermissionCheckResponse) => { - // Verify the response - expect(response1_2.can).toBe(permify.grpc.base.CheckResult.CHECK_RESULT_DENIED); - done(); - }); - }); - }); + metadata: { + snapToken: "", + schemaVersion: response1_1.schemaVersion, + depth: 20, + }, + entity: { + type: "document", + id: "1", + }, + permission: "view", + subject: { + type: "user", + id: "3", + }, + }) + .then((response1_2: permify.grpc.payload.PermissionCheckResponse) => { + // Verify the response + expect(response1_2.can).toBe( + permify.grpc.base.CheckResult.CHECK_RESULT_DENIED + ); + done(); + }); + }); + }); - it("permission client lookup entity", (done) => { - // Initialize the Permify gRPC client - let client = permify.grpc.newClient({ - endpoint: "localhost:3478", - cert: undefined, - pk: undefined, - certChain: undefined, - insecure: true - }); + it("permission client lookup entity", (done) => { + // Initialize the Permify gRPC client + let client = permify.grpc.newClient({ + endpoint: "localhost:3478", + cert: undefined, + pk: undefined, + certChain: undefined, + insecure: true, + }); - // Create a BooleanValue message - const booleanValue = permify.grpc.base.BooleanValue.fromJSON({ data: true }); + // Create a BooleanValue message + const booleanValue = permify.grpc.base.BooleanValue.fromJSON({ + data: true, + }); - // Create an Any message to wrap the BooleanValue - const anyMessage = Any.fromJSON({ - typeUrl: 'type.googleapis.com/base.v1.BooleanValue', - value: permify.grpc.base.BooleanValue.encode(booleanValue).finish() - }); + // Create an Any message to wrap the BooleanValue + const anyMessage = Any.fromJSON({ + typeUrl: "type.googleapis.com/base.v1.BooleanValue", + value: permify.grpc.base.BooleanValue.encode(booleanValue).finish(), + }); - // Define the schema - let schema = ` + // Define the schema + let schema = ` entity user {} entity document { @@ -86,89 +93,206 @@ describe("clients test", () => { } `; - // Write the schema - client.schema.write({ + // Write the schema + client.schema + .write({ + tenantId: "t1", + schema: schema, + }) + .then((response2_1: permify.grpc.payload.SchemaWriteResponse) => { + // Write the data + client.data + .write({ + tenantId: "t1", + metadata: { + schemaVersion: response2_1.schemaVersion, + }, + attributes: [ + { + entity: { + type: "document", + id: "1", + }, + attribute: "public", + value: anyMessage, + }, + ], + tuples: [ + { + entity: { + type: "document", + id: "1", + }, + relation: "viewer", + subject: { + type: "user", + id: "1", + }, + }, + { + entity: { + type: "document", + id: "3", + }, + relation: "viewer", + subject: { + type: "user", + id: "1", + }, + }, + { + entity: { + type: "document", + id: "4", + }, + relation: "viewer", + subject: { + type: "user", + id: "1", + }, + }, + ], + }) + .then((response2_2: permify.grpc.payload.DataWriteResponse) => { + // Perform Lookup Entity Stream + const response2_3 = client.permission.lookupEntityStream({ + tenantId: "t1", + metadata: { + snapToken: response2_2.snapToken, + schemaVersion: response2_1.schemaVersion, + depth: 20, + }, + entityType: "document", + permission: "view", + subject: { + type: "user", + id: "1", + }, + }); + + // Handle the stream response and wait for completion + handle(response2_3, ["1", "3", "4"]).then(() => { + done(); + }); + }); + }); + }); + + it("permission client bulk check", (done) => { + // Initialize the Permify gRPC client + let client = permify.grpc.newClient({ + endpoint: "localhost:3478", + cert: undefined, + pk: undefined, + certChain: undefined, + insecure: true, + }); + + // Define the schema + let schema = ` + entity user {} + + entity document { + relation viewer @user + + action view = viewer + } + `; + + // Write the schema + client.schema + .write({ + tenantId: "t1", + schema: schema, + }) + .then((response_schema: permify.grpc.payload.SchemaWriteResponse) => { + // Write the data to make one check true + client.data + .write({ tenantId: "t1", - schema: schema - }).then((response2_1: permify.grpc.payload.SchemaWriteResponse) => { - - // Write the data - client.data.write({ + metadata: { + schemaVersion: response_schema.schemaVersion, + }, + tuples: [ + { + entity: { + type: "document", + id: "1", + }, + relation: "viewer", + subject: { + type: "user", + id: "user1", + }, + }, + ], + }) + .then((_response_data: permify.grpc.payload.DataWriteResponse) => { + // Perform the bulk permission check + client.permission + .bulkCheck({ tenantId: "t1", metadata: { - schemaVersion: response2_1.schemaVersion + snapToken: "", + schemaVersion: response_schema.schemaVersion, + depth: 20, }, - attributes: [{ + items: [ + { entity: { - type: "document", - id: "1" + type: "document", + id: "1", }, - attribute: "public", - value: anyMessage, - }], - tuples: [{ - entity: { - type: "document", - id: "1" - }, - relation: "viewer", + permission: "view", subject: { - type: "user", - id: "1" - } - }, { - entity: { - type: "document", - id: "3" + type: "user", + id: "user1", }, - relation: "viewer", - subject: { - type: "user", - id: "1" - } - }, { + }, + { entity: { - type: "document", - id: "4" - }, - relation: "viewer", - subject: { - type: "user", - id: "1" - } - }] - }).then((response2_2: permify.grpc.payload.DataWriteResponse) => { - // Perform Lookup Entity Stream - const response2_3 = client.permission.lookupEntityStream({ - tenantId: "t1", - metadata: { - snapToken: response2_2.snapToken, - schemaVersion: response2_1.schemaVersion, - depth: 20 + type: "document", + id: "2", }, - entityType: "document", permission: "view", subject: { - type: "user", - id: "1" - } - }) + type: "user", + id: "user2", + }, + }, + ], + }) + .then( + ( + response_bulk: permify.grpc.payload.PermissionBulkCheckResponse + ) => { + // Verify the response + // Expecting 2 results + expect(response_bulk.results.length).toBe(2); - // Handle the stream response - handle(response2_3, ["1", "3", "4"]); + // First check should be ALLOWED because we added the tuple + expect(response_bulk.results[0].can).toBe( + permify.grpc.base.CheckResult.CHECK_RESULT_ALLOWED + ); - // Wait for the stream to complete - setTimeout(() => { - done(); - }, 1000); - }); - }); - }); + // Second check should be DENIED + expect(response_bulk.results[1].can).toBe( + permify.grpc.base.CheckResult.CHECK_RESULT_DENIED + ); + done(); + } + ); + }); + }); + }); }); // Helper function to handle the stream response -async function handle(res: AsyncIterable, expected: string[]) { - for await (const response of res) { - expect(expected.includes(response.entityId)).toBe(true); - } +async function handle( + res: AsyncIterable, + expected: string[] +) { + for await (const response of res) { + expect(expected.includes(response.entityId)).toBe(true); + } } diff --git a/src/grpc/generated/base/v1/service.ts b/src/grpc/generated/base/v1/service.ts index c399c51..19f0f28 100644 --- a/src/grpc/generated/base/v1/service.ts +++ b/src/grpc/generated/base/v1/service.ts @@ -83,6 +83,42 @@ export interface PermissionCheckResponseMetadata { checkCount: number; } +/** BULK CHECK */ +export interface PermissionBulkCheckRequestItem { + /** Entity on which the permission needs to be checked, required. */ + entity: + | Entity + | undefined; + /** Name of the permission or relation, required, must start with a letter and can include alphanumeric and underscore, max 64 bytes. */ + permission: string; + /** Subject for which the permission needs to be checked, required. */ + subject: Subject | undefined; +} + +/** PermissionBulkCheckRequest is the request message for the BulkCheck method in the Permission service. */ +export interface PermissionBulkCheckRequest { + /** Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. */ + tenantId: string; + /** Metadata associated with this request, required. */ + metadata: + | PermissionCheckRequestMetadata + | undefined; + /** List of permission check requests, maximum 100 items. */ + items: PermissionBulkCheckRequestItem[]; + /** Context associated with this request. */ + context: + | Context + | undefined; + /** Additional arguments associated with this request. */ + arguments: Argument[]; +} + +/** PermissionBulkCheckResponse is the response message for the BulkCheck method in the Permission service. */ +export interface PermissionBulkCheckResponse { + /** List of permission check responses corresponding to each request. */ + results: PermissionCheckResponse[]; +} + /** PermissionExpandRequest is the request message for the Expand method in the Permission service. */ export interface PermissionExpandRequest { /** Identifier of the tenant, required, and must match the pattern "[a-zA-Z0-9-,]+", max 64 bytes. */ @@ -1186,6 +1222,296 @@ export const PermissionCheckResponseMetadata: MessageFns = { + encode(message: PermissionBulkCheckRequestItem, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.entity !== undefined) { + Entity.encode(message.entity, writer.uint32(10).fork()).join(); + } + if (message.permission !== "") { + writer.uint32(18).string(message.permission); + } + if (message.subject !== undefined) { + Subject.encode(message.subject, writer.uint32(26).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PermissionBulkCheckRequestItem { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePermissionBulkCheckRequestItem(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.entity = Entity.decode(reader, reader.uint32()); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.permission = reader.string(); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.subject = Subject.decode(reader, reader.uint32()); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PermissionBulkCheckRequestItem { + return { + entity: isSet(object.entity) ? Entity.fromJSON(object.entity) : undefined, + permission: isSet(object.permission) ? globalThis.String(object.permission) : "", + subject: isSet(object.subject) ? Subject.fromJSON(object.subject) : undefined, + }; + }, + + toJSON(message: PermissionBulkCheckRequestItem): unknown { + const obj: any = {}; + if (message.entity !== undefined) { + obj.entity = Entity.toJSON(message.entity); + } + if (message.permission !== "") { + obj.permission = message.permission; + } + if (message.subject !== undefined) { + obj.subject = Subject.toJSON(message.subject); + } + return obj; + }, + + create(base?: DeepPartial): PermissionBulkCheckRequestItem { + return PermissionBulkCheckRequestItem.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PermissionBulkCheckRequestItem { + const message = createBasePermissionBulkCheckRequestItem(); + message.entity = (object.entity !== undefined && object.entity !== null) + ? Entity.fromPartial(object.entity) + : undefined; + message.permission = object.permission ?? ""; + message.subject = (object.subject !== undefined && object.subject !== null) + ? Subject.fromPartial(object.subject) + : undefined; + return message; + }, +}; + +function createBasePermissionBulkCheckRequest(): PermissionBulkCheckRequest { + return { tenantId: "", metadata: undefined, items: [], context: undefined, arguments: [] }; +} + +export const PermissionBulkCheckRequest: MessageFns = { + encode(message: PermissionBulkCheckRequest, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.tenantId !== "") { + writer.uint32(10).string(message.tenantId); + } + if (message.metadata !== undefined) { + PermissionCheckRequestMetadata.encode(message.metadata, writer.uint32(18).fork()).join(); + } + for (const v of message.items) { + PermissionBulkCheckRequestItem.encode(v!, writer.uint32(26).fork()).join(); + } + if (message.context !== undefined) { + Context.encode(message.context, writer.uint32(34).fork()).join(); + } + for (const v of message.arguments) { + Argument.encode(v!, writer.uint32(42).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PermissionBulkCheckRequest { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePermissionBulkCheckRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.tenantId = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.metadata = PermissionCheckRequestMetadata.decode(reader, reader.uint32()); + continue; + } + case 3: { + if (tag !== 26) { + break; + } + + message.items.push(PermissionBulkCheckRequestItem.decode(reader, reader.uint32())); + continue; + } + case 4: { + if (tag !== 34) { + break; + } + + message.context = Context.decode(reader, reader.uint32()); + continue; + } + case 5: { + if (tag !== 42) { + break; + } + + message.arguments.push(Argument.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PermissionBulkCheckRequest { + return { + tenantId: isSet(object.tenant_id) ? globalThis.String(object.tenant_id) : "", + metadata: isSet(object.metadata) ? PermissionCheckRequestMetadata.fromJSON(object.metadata) : undefined, + items: globalThis.Array.isArray(object?.items) + ? object.items.map((e: any) => PermissionBulkCheckRequestItem.fromJSON(e)) + : [], + context: isSet(object.context) ? Context.fromJSON(object.context) : undefined, + arguments: globalThis.Array.isArray(object?.arguments) + ? object.arguments.map((e: any) => Argument.fromJSON(e)) + : [], + }; + }, + + toJSON(message: PermissionBulkCheckRequest): unknown { + const obj: any = {}; + if (message.tenantId !== "") { + obj.tenant_id = message.tenantId; + } + if (message.metadata !== undefined) { + obj.metadata = PermissionCheckRequestMetadata.toJSON(message.metadata); + } + if (message.items?.length) { + obj.items = message.items.map((e) => PermissionBulkCheckRequestItem.toJSON(e)); + } + if (message.context !== undefined) { + obj.context = Context.toJSON(message.context); + } + if (message.arguments?.length) { + obj.arguments = message.arguments.map((e) => Argument.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): PermissionBulkCheckRequest { + return PermissionBulkCheckRequest.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PermissionBulkCheckRequest { + const message = createBasePermissionBulkCheckRequest(); + message.tenantId = object.tenantId ?? ""; + message.metadata = (object.metadata !== undefined && object.metadata !== null) + ? PermissionCheckRequestMetadata.fromPartial(object.metadata) + : undefined; + message.items = object.items?.map((e) => PermissionBulkCheckRequestItem.fromPartial(e)) || []; + message.context = (object.context !== undefined && object.context !== null) + ? Context.fromPartial(object.context) + : undefined; + message.arguments = object.arguments?.map((e) => Argument.fromPartial(e)) || []; + return message; + }, +}; + +function createBasePermissionBulkCheckResponse(): PermissionBulkCheckResponse { + return { results: [] }; +} + +export const PermissionBulkCheckResponse: MessageFns = { + encode(message: PermissionBulkCheckResponse, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + for (const v of message.results) { + PermissionCheckResponse.encode(v!, writer.uint32(10).fork()).join(); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): PermissionBulkCheckResponse { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBasePermissionBulkCheckResponse(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.results.push(PermissionCheckResponse.decode(reader, reader.uint32())); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): PermissionBulkCheckResponse { + return { + results: globalThis.Array.isArray(object?.results) + ? object.results.map((e: any) => PermissionCheckResponse.fromJSON(e)) + : [], + }; + }, + + toJSON(message: PermissionBulkCheckResponse): unknown { + const obj: any = {}; + if (message.results?.length) { + obj.results = message.results.map((e) => PermissionCheckResponse.toJSON(e)); + } + return obj; + }, + + create(base?: DeepPartial): PermissionBulkCheckResponse { + return PermissionBulkCheckResponse.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): PermissionBulkCheckResponse { + const message = createBasePermissionBulkCheckResponse(); + message.results = object.results?.map((e) => PermissionCheckResponse.fromPartial(e)) || []; + return message; + }, +}; + function createBasePermissionExpandRequest(): PermissionExpandRequest { return { tenantId: "", metadata: undefined, entity: undefined, permission: "", context: undefined, arguments: [] }; } @@ -8237,6 +8563,215 @@ export const PermissionDefinition = { }, }, }, + /** + * BulkCheck method receives a PermissionBulkCheckRequest containing multiple check requests + * and returns a PermissionBulkCheckResponse with results for each request. + * Maximum 100 requests can be processed in a single bulk operation. + */ + bulkCheck: { + name: "BulkCheck", + requestType: PermissionBulkCheckRequest, + requestStream: false, + responseType: PermissionBulkCheckResponse, + responseStream: false, + options: { + _unknownFields: { + 8338: [ + Buffer.from([ + 131, + 1, + 10, + 10, + 80, + 101, + 114, + 109, + 105, + 115, + 115, + 105, + 111, + 110, + 18, + 14, + 98, + 117, + 108, + 107, + 32, + 99, + 104, + 101, + 99, + 107, + 32, + 97, + 112, + 105, + 26, + 77, + 67, + 104, + 101, + 99, + 107, + 32, + 109, + 117, + 108, + 116, + 105, + 112, + 108, + 101, + 32, + 112, + 101, + 114, + 109, + 105, + 115, + 115, + 105, + 111, + 110, + 115, + 32, + 105, + 110, + 32, + 97, + 32, + 115, + 105, + 110, + 103, + 108, + 101, + 32, + 114, + 101, + 113, + 117, + 101, + 115, + 116, + 46, + 32, + 77, + 97, + 120, + 105, + 109, + 117, + 109, + 32, + 49, + 48, + 48, + 32, + 114, + 101, + 113, + 117, + 101, + 115, + 116, + 115, + 32, + 97, + 108, + 108, + 111, + 119, + 101, + 100, + 46, + 42, + 22, + 112, + 101, + 114, + 109, + 105, + 115, + 115, + 105, + 111, + 110, + 115, + 46, + 98, + 117, + 108, + 107, + 45, + 99, + 104, + 101, + 99, + 107, + ]), + ], + 578365826: [ + Buffer.from([ + 51, + 58, + 1, + 42, + 34, + 46, + 47, + 118, + 49, + 47, + 116, + 101, + 110, + 97, + 110, + 116, + 115, + 47, + 123, + 116, + 101, + 110, + 97, + 110, + 116, + 95, + 105, + 100, + 125, + 47, + 112, + 101, + 114, + 109, + 105, + 115, + 115, + 105, + 111, + 110, + 115, + 47, + 98, + 117, + 108, + 107, + 45, + 99, + 104, + 101, + 99, + 107, + ]), + ], + }, + }, + }, /** * Expand method receives a PermissionExpandRequest and returns a PermissionExpandResponse. * It expands relationships according to the schema provided. @@ -15775,6 +16310,15 @@ export interface PermissionServiceImplementation { request: PermissionCheckRequest, context: CallContext & CallContextExt, ): Promise>; + /** + * BulkCheck method receives a PermissionBulkCheckRequest containing multiple check requests + * and returns a PermissionBulkCheckResponse with results for each request. + * Maximum 100 requests can be processed in a single bulk operation. + */ + bulkCheck( + request: PermissionBulkCheckRequest, + context: CallContext & CallContextExt, + ): Promise>; /** * Expand method receives a PermissionExpandRequest and returns a PermissionExpandResponse. * It expands relationships according to the schema provided. @@ -15827,6 +16371,15 @@ export interface PermissionClient { request: DeepPartial, options?: CallOptions & CallOptionsExt, ): Promise; + /** + * BulkCheck method receives a PermissionBulkCheckRequest containing multiple check requests + * and returns a PermissionBulkCheckResponse with results for each request. + * Maximum 100 requests can be processed in a single bulk operation. + */ + bulkCheck( + request: DeepPartial, + options?: CallOptions & CallOptionsExt, + ): Promise; /** * Expand method receives a PermissionExpandRequest and returns a PermissionExpandResponse. * It expands relationships according to the schema provided.