API Reference: Content-Change Check

Content-Change Check Requests are a special kind of Check Request that should be used before applications modify protected content.

The primary difference between regular checks and content-change checks is that content-change checks do not require a Zookie because they are always evaluated at the latest revision. The Zookie returned by a Content-Change Check Response is intended to be saved alongside the protected content, so that the application can use it in future Check requests. This avoids the New Enemy Problem.

The following pseudo-code represents the desired usage of this API:

def write_content(user, content_id, new_content):
is_allowed, zookie = content_change_check(content_id, user)
if is_allowed:
storage.write_content(contentd_id, new_content, zookie)
return success
return forbidden

gRPC Endpoint#

ACLService.ContentChangeCheck

Request#

Parameters#

NameTypeRequired
test_usersetObjectAndRelationYes
userUserYes

Request Definition#

message ContentChangeCheckRequest {
ObjectAndRelation test_userset = 1;
User user = 2;
}
Additional Protocol Buffer definitions used
message ObjectAndRelation {
string namespace = 1;
string object_id = 2;
string relation = 3;
}
message User {
oneof user_oneof {
uint64 user_id = 1;
ObjectAndRelation userset = 2;
}
}

Request Example#

{
test_userset: {
namespace: "mynotetakingapp/note"
object_id: "328392"
relation: "owner"
}
user: {
userset: {
namespace: "mynotetakingapp/user"
object_id: "213"
relation: "..."
}
}
}

Response#

A Content-Change Check Response contains two values:

  • a boolean that indicates whether provided user is a member of the provided test_userset
  • a Zookie

Response Definition#

message CheckResponse {
enum Membership {
NOT_MEMBER = 1; MEMBER = 2;
}
Zookie revision = 2;
Membership membership = 3;
}
message Zookie { string token = 1; }

Response Example#

{
revision { token: "CAESAggB" }
result: MEMBER
}

Errors#

  • INVALID_ARGUMENT: a provided value has failed to semantically validate
  • RESOURCE_EXHAUSTED: processing the request surpassed the maximum depth of relationship resolution
  • FAILED_PRECONDITION: a specified namespace or relation does not exist

For more generic failures, see the gRPC Status Code documentation.

Code Samples#

Code Sample Parameter Values
Parameter NameValueDescription
Tenant SlugThe slug for your tenant
TokenYour token
NamespaceThe namespace containing the object to check
Object IDThe ID of the object to check
RelationThe relation to check for the object
User namespaceThe namespace for users in your tenant
User IDThe ID of the user against which to check
grpcurl -rpc-header "authorization: Bearer t_my_token" -d \
'{
"test_userset": {
"namespace": "someslug/mynamespace",
"object_id": "someobject",
"relation": "viewer"
},
"user": {
"userset": {
"namespace": "someslug/user",
"object_id": "someuserid",
"relation": "..."
}
}
}' \
grpc.authzed.com:443 ACLService/ContentChangeCheck