Skip to main content


In Ory Keto subjects are a recursive polymorphic datatype. They either refer to a specific subject (for example user) by some application defined identifier, or a set of subjects.

Subject IDs

A subject ID can be any string. It's up to the application to map its users, devices, ... to a constant, unique identifier. We recommend the usage of UUIDs as they provide a high entropy. It's however possible to use for example URLs or opaque tokens of any kind. Please check the limitations. Ory Keto will consider subject IDs equal iff their string representation is equal.

Subject sets

A subject set is the set of all subjects that have a specific relation on an object. They empower Ory Keto to be as flexible as you need it by defining indirections. They can be used to realize for example RBAC or inheritance of relations. Subject sets themselves can again indirect to subject sets. For a performant evaluation of requests it's however required to follow some best practices. As a special case, subject sets can also refer to an object by using the empty relation. Effectively, this is interpreted as "any relation, even a non-existent one".

Subject sets also represent all intermediary nodes in the graph of relations.

Basic example

In the basic case an application uses the same subject identifiers as it uses internally, for example a constant, unique username like zepatrik or preferably UUIDv4 like 480158d4-0031-4412-9453-1bb0cdf76104.

Head over to the basic full feature example to see an example with some context.

Advanced example: using application information within Keto subjects

Because the Keto client can use arbitrary strings as subjects, it's tempting to encode application data within the subject. We strongly discourage this practice. Instead, you should use a UUID to map application data to Keto subjects. This is required to ensure:

  1. single source of truth and easy data update
  2. free choice of encoding (Keto doesn't allow the characters :#@)
  3. unlimited data size (Keto only allows up to 64 characters)

For example, this can be used to implement a crude ABAC system by mapping attributes to a subject ID. The application can then define relation tuples that reflect permissions depending on the value of attributes. It will have to map each request to the subject representing the attributes.

Let's assume the application knows the following mapping between attributes and UUIDs:

office_hours: true

Keto could then know the following relation tuple:

// allow access to TCP port 22 when the request originates from a specific subnet during office hours

The application has to map each incoming request to a subject string representing the attributes of the request. Ory Keto will reply with a positive check response depending on the string equality of the requested subject representing the attributes with the known relation tuples. Remember that Ory Keto does not know how to interpret any information stored in the relation tuples. Rather, the application has to preprocess and map the value to the corresponding UUID.