Overview
The Ory Permission Service (Keto) implements Google Zanzibar. It might differ a bit from other authorization services you know, so let's first clarify a few concepts.
Ory Cloud Availability
The Permission Service is available to all Ory Cloud users without additional fees or setup. The API is in a production-ready state. The documentation, integration, and UI are under active development.
Relations and Relation Tuples
The data model used by the Permission Service are so-called relation tuples that encode relations between subjects and objects.
Examples of relation tuples are:
user1
ismember
ofgroups:group1
member
ofgroups:group1
isreader
offiles:file1
As you can see, the subject of a relation tuple can either be a specific subject ID, or subjects defined through an indirection (all members of a certain group). The object is referenced by its ID.
Checking Permissions
Permissions are just another form of relations. Therefore, a permission check is a request to check whether a subject has a certain relation to an object, possibly through one or more indirections.
As a very simple example, we assume the following tuples exist:
user1
ismember
ofgroups:group1
member
ofgroups:group1
isreader
offiles:file1
Now, one could ask:
- Is
user1
areader
offiles:file1
? - Yes, becauseuser1
is amember
ofgroups:group1
and allmember
s ofgroups:group1
arereader
offiles:file1
. - Is
user2
amember
ofgroups:group1
? - No.
Example
This example setup demonstrates the basics of relation tuple management and usage of the Check API.
Defining Namespaces
Relation tuples reside in namespaces. To create relation tuples, you must define their namespace first.
- Ory CLI
- Self-Hosted Ory Keto Config
ory patch permission-config <your-project-id> \
--add '/namespaces/-={"id": 0, "name": "resources"}' \
--add '/namespaces/-={"id": 1, "name": "groups"}'
namespaces:
- id: 0
name: resources
- id: 1
name: groups
Creating Relation Tuples
After creating the namespaces, you can use the relation tuple APIs to create a relation tuple.
- Ory Cloud
- Self-Hosted Ory Keto
ORY_PAT="<your ory personal access token from the console>"
ORY_SDK_URL="<your ory project sdk url from the console>"
echo '[
{
"action": "insert",
"relation_tuple": {
"subject_id": "user1",
"relation": "member",
"namespace": "groups",
"object": "group1"
}
}, {
"action": "insert",
"relation_tuple": {
"subject_set": {
"relation": "member",
"namespace": "groups",
"object": "group1"
},
"relation": "owner",
"namespace": "resources",
"object": "file1"
}
}
]' > relationtuple.json
curl -X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ORY_PAT" \
-d @relationtuple.json \
"$ORY_SDK_URL/admin/relation-tuples"
KETO_WRITE_URL="<your keto write url>"
echo '[
{
"action": "insert"
"relation_tuple": {
"subject_id": "user1",
"relation": "member",
"namespace": "groups",
"object": "group1"
}
}, {
"action": "insert"
"relation_tuple": {
"subject_set": {
"relation": "member",
"namespace": "groups",
"object": "group1"
},
"relation": "owner",
"namespace": "resources",
"object": "file1"
}
}
]' > relationtuple.json
curl -X PUT \
-H "Content-Type: application/json" \
-d @relationtuple.json \
"$KETO_WRITE_URL/admin/relation-tuples"
Checking Permissions
Permission checks are requests that check whether a subject has a relation to an object. This relation can be directly defined, or constructed following indirections (e.g. members of a group).
The Check API allows to perform such checks:
- Ory Cloud
- Self-Hosted Ory Keto
ORY_PAT="<your ory personal access token from the console>"
ORY_SDK_URL="<your ory project sdk url from the console>"
echo '{
"subject_id": "user1",
"relation": "owner",
"namespace": "resources",
"object": "file1"
}' > query.json
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ORY_PAT" \
-d @query.json \
"$ORY_SDK_URL/relation-tuples/check"
# should print:
# {"allowed":true}
KETO_WRITE_URL="<your keto write url>"
echo '{
"subject_id": "user1",
"relation": "owner",
"namespace": "resources",
"object": "file1"
}' > query.json
curl -X POST \
-H "Content-Type: application/json" \
-d @query.json \
"$KETO_WRITE_URL/relation-tuples/check"
# should print:
# {"allowed":true}