Quickstart: Cat Videos Example
Ory offers support for self-hosted Ory software through the Ory Enterprise License (OEL). Read more about the OEL here.
This example describes a video sharing service. The individual videos are organized in directories. Every directory has an owner
and every video has the same owner as it's parent directory. The owner has elevated privileges about the video files that aren't
modeled individually in Ory Keto. The only other privilege modeled in this example is "view access." Every owner has view access
to their objects, and this privilege can be granted to other users as well. The video sharing application interprets the special
* user ID as any user, including anonymous users. Note that Ory Keto doesn't interpret this subject any differently from other
subjects. It also doesn't know anything about directory structures or induced ownership.
The "Keto client" is the application interacting with Keto. In this case we refer to the video sharing service backend as the Keto client.
Starting the example
First, install Keto.
Now you can start the example using either docker-compose or a bash script. The bash script requires you to have the keto
binary in your $PATH.
Alternatively, use Docker to automatically get the required images.
# clone the repository if you don't have it yet
git clone git@github.com:ory/keto.git && cd keto
# Alternatively, you can use 'https' to clone if ssh cloning gives permission denied error. (Configure ssh keys in github to resolve the issue.)
git clone https://github.com/ory/keto.git && cd keto
docker-compose -f contrib/cat-videos-example/docker-compose.yml up
# or
./contrib/cat-videos-example/up.sh
# output: all initially created relationships
# NAMESPACE OBJECT RELATION NAME SUBJECT
# Video /cats/1.mp4 owner Video:/cats#owner
# Video /cats/1.mp4 view Video:/cats/1.mp4#owner
# Video /cats/1.mp4 view User:*
# Video /cats/2.mp4 owner Video:/cats#owner
# Video /cats/2.mp4 view Video:/cats/2.mp4#owner
# Video /cats owner User:Alice
# Video /cats view Video:/cats#owner
State of the system
At the current state only one user with the username Alice has added videos. Both videos are in the /cats directory owned by
Alice. The file /cats/1.mp4 can be viewed by anyone (*), while /cats/2.mp4 has no extra sharing options, and can therefore
only be viewed by its owner, Alice. The relationship definitions are located in the contrib/cat-videos-example/relation-tuples
directory.
Simulating the video sharing application
Now you can open a second terminal to run the queries against, just like the video service client would do. In this example we will use the Keto CLI client.
If you want to run the Keto CLI within Docker, set the alias
alias keto="docker run -it --network cat-videos-example_default -e KETO_READ_REMOTE=\"keto:4466\" oryd/keto:v25.4.0"
in your terminal session. Alternatively, you need to set the remote endpoint so that the Keto CLI knows where to connect to (not necessary if using Docker):
export KETO_READ_REMOTE="127.0.0.1:4466"
Check incoming requests
First off, we get a request by an anonymous user that would like to view /cats/2.mp4. The client now has to ask Keto if that
operation should be allowed or denied.
# Is "*" allowed to "view" the object "videos":"/cats/2.mp4"?
keto check "User:*" view Video /cats/2.mp4 --insecure-disable-transport-security
# output:
# Denied
We already discussed that this request should be denied, but it's always good to see this in action.
Now Alice wants to change some view permissions of /cats/1.mp4. For this, the video service application has to show all users
that are allowed to view the video. It uses Keto's expand-API to get these
data:
# Who is allowed to "view" the object "videos":"/cats/2.mp4"?
keto expand view Video /cats/1.mp4
# output:
# or :#@Video:/cats/1.mp4#view
# ├──∋ :#@User:*️
# └──or :#@Video:/cats/1.mp4#owner
# └──or :#@Video:/cats#owner
# └──∋ :#@User:Alice️
Here we can see the full subject set expansion. The second branch
Video:/cats/1.mp4#owner
indicates that every owner of the object is allowed to view the Object.
In the next step we see that the object's owners are the owners of Video:/cats
Video:/cats#owner
On the last line, We see that Alice is the owner of /cats.
Note that there is no direct relationship that would grant Alice view access on /cats/1.mp4 as this is indirectly defined via
the ownership relation.
The special user User:* on the other hand was directly granted view access on the object, as it's a first-level leaf of the
expansion tree. The following CLI command proves that this is the case:
# Is "*" allowed to "view" the object "Video":"/cats/1.mp4"?
keto check "User:*" view Video /cats/1.mp4 --insecure-disable-transport-security
# output:
# Allowed
Updating the view permissions will be added here at a later stage.