syntax = "proto3";

package ory.keto.relation_tuples.v1alpha2;

import "ory/keto/relation_tuples/v1alpha2/relation_tuples.proto";

option csharp_namespace = "Ory.Keto.RelationTuples.v1alpha2";
option go_package = "github.com/ory/keto/proto/ory/keto/relation_tuples/v1alpha2;rts";
option java_multiple_files = true;
option java_outer_classname = "CheckServiceProto";
option java_package = "sh.ory.keto.relation_tuples.v1alpha2";
option php_namespace = "Ory\\Keto\\RelationTuples\\v1alpha2";

// The service that performs authorization checks
// based on the stored Access Control Lists.
//
// This service is part of the [read-APIs](../concepts/25_api-overview.mdx#read-apis).
service CheckService {
  // Performs an authorization check.
  rpc Check(CheckRequest) returns (CheckResponse);
  rpc BatchCheck(BatchCheckRequest) returns (BatchCheckResponse);
}

// The request for a CheckService.Check RPC.
// Checks whether a specific subject is related to an object.
message CheckRequest {
  // The namespace to evaluate the check.
  //
  // Note: If you use the expand-API and the check
  // evaluates a RelationTuple specifying a SubjectSet as
  // subject or due to a rewrite rule in a namespace config
  // this check request may involve other namespaces automatically.
  string namespace = 1 [deprecated = true];
  // The related object in this check.
  string object = 2 [deprecated = true];
  // The relation between the Object and the Subject.
  string relation = 3 [deprecated = true];
  // The related subject in this check.
  Subject subject = 4 [deprecated = true];

  // The relation tuple to check. This field supersedes the deprecated
  // namespace/object/relation/subject fields.
  RelationTuple tuple = 8;

  // This field is not implemented yet and has no effect.
  // <!--
  // Set this field to `true` in case your application
  // needs to authorize depending on up to date ACLs,
  // also called a "content-change check".
  //
  // If set to `true` the `snaptoken` field is ignored,
  // the check is evaluated at the latest snapshot
  // (globally consistent) and the response includes a
  // snaptoken for clients to store along with object
  // contents that can be used for subsequent checks
  // of the same content version.
  //
  // Example use case:
  //  - You need to authorize a user to modify/delete some resource
  //    and it is unacceptable that if the permission to do that had
  //    just been revoked some seconds ago so that the change had not
  //    yet been fully replicated to all availability zones.
  // -->
  bool latest = 5;
  // This field is not implemented yet and has no effect.
  // <!--
  // Optional. Like reads, a check is always evaluated at a
  // consistent snapshot no earlier than the given snaptoken.
  //
  // Leave this field blank if you want to evaluate the check
  // based on eventually consistent ACLs, benefiting from very
  // low latency, but possibly slightly stale results.
  //
  // If the specified token is too old and no longer known,
  // the server falls back as if no snaptoken had been specified.
  //
  // If not specified the server tries to evaluate the check
  // on the best snapshot version where it is very likely that
  // ACLs had already been replicated to all availability zones.
  // -->
  string snaptoken = 6;
  // The maximum depth to search for a relation.
  //
  // If the value is less than 1 or greater than the global
  // max-depth then the global max-depth will be used instead.
  int32 max_depth = 7;
}

// The response for a CheckService.Check rpc.
message CheckResponse {
  // Whether the specified subject (id)
  // is related to the requested object.
  //
  // It is false by default if no ACL matches.
  bool allowed = 1;
  // This field is not implemented yet and has no effect.
  // <!--
  // The last known snapshot token ONLY specified if
  // the request had not specified a snaptoken,
  // since this performed a "content-change request"
  // and consistently fetched the last known snapshot token.
  //
  // This field is not set if the request had specified a snaptoken!
  //
  // If set, clients should cache and use this token
  // for subsequent requests to have minimal latency,
  // but allow slightly stale responses (only some milliseconds or seconds).
  // -->
  string snaptoken = 2;
}

// The response for an individual check in the CheckService.BatchCheck rpc.
message CheckResponseWithError {
  // Whether the specified subject (id)
  // is related to the requested object.
  //
  // It is false by default if no ACL matches.
  bool allowed = 1;
  // If there was an error checking the tuple,
  // this will contain the error message.
  //
  // If the check was performed successfully, this will be empty.
  string error = 2;
  // This field is not implemented yet and has no effect.
  // <!--
  // The last known snapshot token ONLY specified if
  // the request had not specified a snaptoken,
  // since this performed a "content-change request"
  // and consistently fetched the last known snapshot token.
  //
  // This field is not set if the request had specified a snaptoken!
  //
  // If set, clients should cache and use this token
  // for subsequent requests to have minimal latency,
  // but allow slightly stale responses (only some milliseconds or seconds).
  // -->
  string snaptoken = 3;
}

// The request for a CheckService.BatchCheck RPC.
// Checks a batch of relations.
message BatchCheckRequest {
  // The relation tuples to check in this batch.
  repeated RelationTuple tuples = 1;

  // This field is not implemented yet and has no effect.
  // <!--
  // Set this field to `true` in case your application
  // needs to authorize depending on up to date ACLs,
  // also called a "content-change check".
  //
  // If set to `true` the `snaptoken` field is ignored,
  // the check is evaluated at the latest snapshot
  // (globally consistent) and the response includes a
  // snaptoken for clients to store along with object
  // contents that can be used for subsequent checks
  // of the same content version.
  //
  // Example use case:
  //  - You need to authorize a user to modify/delete some resource
  //    and it is unacceptable that if the permission to do that had
  //    just been revoked some seconds ago so that the change had not
  //    yet been fully replicated to all availability zones.
  // -->
  bool latest = 2;
  // This field is not implemented yet and has no effect.
  // <!--
  // Optional. Like reads, a check is always evaluated at a
  // consistent snapshot no earlier than the given snaptoken.
  //
  // Leave this field blank if you want to evaluate the check
  // based on eventually consistent ACLs, benefiting from very
  // low latency, but possibly slightly stale results.
  //
  // If the specified token is too old and no longer known,
  // the server falls back as if no snaptoken had been specified.
  //
  // If not specified the server tries to evaluate the check
  // on the best snapshot version where it is very likely that
  // ACLs had already been replicated to all availability zones.
  // -->
  string snaptoken = 3;
  // The maximum depth to search for a relation.
  //
  // If the value is less than 1 or greater than the global
  // max-depth then the global max-depth will be used instead.
  int32 max_depth = 4;
}

// The response for a CheckService.BatchCheck rpc.
message BatchCheckResponse {
  // The results of the batch check. The order of these
  // results will match the order of the input.
  repeated CheckResponseWithError results = 1;
}
