Skip to main content

Expand API: display who has access to an object

This guide will explain how to use Ory Keto's expand-API to display who has access to an object, and why. Please refer to the gRPC and REST API reference documentation for all details. The expand-API allows to expand a given subject set into all its effective subjects.

Example

As an example, we want to look at a file sharing application. Files are hierarchically organized in a directory structure. Every user owns files and directories, and can grant any other user access to them on a per-file or per-directory basis. Users can only see and access files they own or were granted access by the owner.

Directories and files are stored in Ory Keto within the directories and files namespaces respectively. They're identified by a UUID that the application maps to the actual object metadata. Users are also identified by and mapped to a UUID.

info

For the sake of readability, the code samples use the object path and user name instead. Please refer to the objects and subjects pages for why the mapping is necessary.

Displaying who has access

To assist users with managing permissions for their files, the application has to display who has access to a file and why. In this example, we assume that the application knows the following files and directories:

├─ photos            (owner: maureen; shared with laura)
├─ beach.jpg (owner: maureen)
├─ mountains.jpg (owner: laura)

This is represented in Ory Keto by the following relation tuples:

// ownership
directories:/photos#owner@maureen
files:/photos/beach.jpg#owner@maureen
files:/photos/mountains.jpg#owner@laura

// maureen granted access to /photos to laura
directories:/photos#access@laura

// the following tuples are defined implicitly through subject set rewrites (not supported yet)
directories:/photos#access@(directories:/photos#owner)
files:/photos/beach.jpg#access@(files:/photos/beach.jpg#owner)
files:/photos/beach.jpg#access@(directories:/photos#access)
files:/photos/mountains.jpg#access@(files:/photos/mountains.jpg#owner)
files:/photos/mountains.jpg#access@(directories:/photos#access)

// the following tuples are required to allow the subject set rewrites (not supported yet)
directories:/photos#parent@(files:/photos/beach.jpg#_)
directories:/photos#parent@(files:/photos/mountains.jpg#_)

The user maureen now wants to manage access for the file /photos/beach.jpg. Therefore, the application uses the expand-API to get a tree of everyone who has access to that file:

contrib/docs-code-samples/expand-api-display-access/01-expand-beach/main.go

Result

Maximum tree depth

The max-depth parameter is important to keep the request latency within an acceptable bound, but also abstract away the most basic subject sets. In many cases the application doesn't want to resolve all subject sets, but rather wants to display that for example Everyone in the company or Admins have a specific relation.

In this example the application knows the rough structure of the relation tuples it uses and can therefore determine that max-depth=3 is sufficient to display all relevant relations:

  1. directly granted access (depth 1)
  2. indirectly granted access through ownership (depth 2)
  3. indirectly granted access through ownership of the parent (depth 3)

Analyzing the tree

The tree doesn't only include the subject IDs (in this case usernames), but also for what reason they were included. This can be useful for users to audits permissions. Also, in many cases the application would not want to list all subject IDs but rather abstract away some subject sets.