4.3. List API: Display all objects (object) that a user can access

0 24
1. RBACRBAC (Role-Based Access Control)It is the most general permission access...

1. RBAC

RBAC (Role-Based Access Control)It is the most general permission access control system. The idea is that permissions are not directly granted to specific users, but a set of roles is established between the set of users and the set of permissions. Each role corresponds to a set of corresponding permissions. Once a user is assigned an appropriate role, he will have all the permissions of that role. The advantage of this approach is that it is not necessary to allocate permissions every time a new user is created; it is enough to assign the corresponding roles, and the change of role permissions is much less than that of user permissions, which will simplify user permission management and reduce system overhead.

RBAC has three models.

1.1. RBAC0

It is the basis of other RBAC models. In this model, there is a many-to-many relationship between users and roles, and each role has at least one permission.

1.2. RBAC1

Based on RBAC0, the inheritance relationship between roles is introduced, which means that roles have a distinction between superior and subordinate. The inheritance relationship between roles can be divided into general inheritance relationship and restricted inheritance relationship. The general inheritance relationship requires that the inheritance relationship between roles is an absolute partial order relationship, allowing multiple inheritance between roles. While the restricted inheritance relationship further requires that the inheritance relationship between roles is a tree structure, realizing single inheritance between roles.

1.3. RBAC2

Based on RBAC0, role-based access control is introduced. This model has the following two constraints:

  • Static separation of duties

    • Mutually exclusive roles: Mutually exclusive roles refer to roles whose permissions can mutually restrict each other. For such roles, a user can only be assigned one role in an activity and cannot obtain the use rights of multiple roles at the same time. For example, in an audit activity, a user cannot be assigned both the accounting role and the auditor role

    • Base constraint: The number of users assigned to a role is limited; the number of roles a user can have is limited; the number of access permissions corresponding to a role is also limited to control the distribution of advanced privileges. For example, the management level of a company is limited

    • Prerequisite roles: To obtain higher privileges, you must first have lower-level privileges

  • Dynamic separation of duties

    • Runtime mutual exclusion: Dynamically constrain the roles owned by users, such as a user can have two roles, but can only activate one at runtime


2. Introduction to Keto

2.1. Introduction

Ory Permissions (based on the open-source Ory Keto Permission Server) is the first and only open-source implementation of the "Zanzibar: Google's consistent, global authorization system".

If you need to know whether a user is allowed to do something, Ory Permissions are very suitable for you.

Ory Permission implements the basic API contract for managing and checking relationships ("permissions") using HTTP and gRPC APIs. Future versions will include features such as user set rewriting (e.g., role-permission models in the style of RBAC), Zookies, etc.

2.2. Installation

The Ory software can run on any operating system (FreeBSD, macOS, Linux, Windows, ...) and supports all major CPU platforms (ARM64, ARMv7, x86_64, x86, ...).

Ory provides pre-built binaries, Docker images, and supports various package managers.

For more details, please refer to:https://www.ory.sh/docs/keto/install

2.3. Performance

This document explains the time complexity of Ory Keto. The analysis and addition of the main memory complexity will be discussed later. We only check the evaluation engine (inspection and expansion API) because other parts are mainly determined by dependencies, such as the database you choose and the decoding/encoding of messages. For clarity, the given examples ignore the namespace (namespace).

2.3.1. Check Engine

Essentially, the check engine (check-engine) assumes that relation tuples (relation tuple) and their indirect combinations form an acyclic directed graph called the relation graph (the graph of relations)。

Consider the following example:

file#access@(file#owner) // probably defined via subjectset rewrites file#access@user1 // access was granted directly file#owner@user2 // file owner record; indirectly gets access

is interpreted as the following figure:

By fromobjectStart searching the graph, afterrelation, trying to reachuserin the manner, calculateobject#relation@userof the form of the check request. If such a path exists, then the request is allowed.

The graph traversal algorithm used by Ory Keto is breadth-first search. In the worst case, the time complexity isO(n+e), wherenis from the nodeobject#relationbyethe number of nodes reachable from the set of edges. Rearranging, both time and space complexity areo(b^d), wherebis the maximum width seen from the search root,dis the maximum depth.

This means that complexity largely depends on the structure of the graph. If the graph contains deeply nested indirect (indirection), multiple recursive calls are needed to parse these indirects. Similarly, if there are widely nested indirects, Ory Keto must be able to parse all the indirects. The goal is to design ACL tuples in a way that requires parsing only a few indirects. Learn moreBest Practices for ACL Design.

Therefore, we believe that conventional benchmark tests will not produce any meaningful results. Therefore, we will add comparisons with other similar projects later.

2.3.2. Extension Engine

Similarly to the way the check engine traverses the relation tuple (relation tuple) graph, the extension engine builds the tree of all the collection operations it encounters. It parses all the indirect (indirection) from the subject set (subjectset) to the specified depth. Since it also uses breadth-first search, the time and space complexity are linearly dependent on the number of nodes reachable from the subject set. The same performance considerations also apply here, and it is particularly important to note that lower depths will further limit the complexity of the operations. If the relation tuples are deeply nested and/or widely nested, the returned tree may quickly exceed reasonable size limits.

2.3.3. Reference

2.4. Quick Start: Cat Video Example

This example introduces a video sharing service. Videos are organized in directories. Each directory has an owner, and each video's owner is the same as its parent directory. Owners have privileges over video files and do not need to be modeled separately in Ory Keto. In this example, the other permissions modeled are only 'View Access', and each owner has view access to their objects and can also grant this permission to other users. The video sharing application will have special*User ID is interpreted as any user, protecting anonymous users. Note that Ory Keto's interpretation of the subject is no different from other subjects. It knows nothing about the directory structure or induced ownership.

Terms:

"Keto Client" is the application that interacts with Keto. In this example, we will call the video sharing service backend Keto Client.

2.4.1. Starting Example

Firstly,Install Keto.

Now you can usedocker-composeor bash script startup examples. The bash script requires you to$PATHownsketoBinary program.

Or, use Docker to automatically obtain the required images.

# clone the repository if you don't have it yet git clone https://github.com/ory/keto.git && cd keto docker-compose -f contrib/cat-videos-example/docker-compose.yml up # or https://www.freebuf.com/articles/database/contrib/cat-videos-example/up.sh # output: all initially created relation tuples # NAMESPACE OBJECT RELATION NAME SUBJECT # videos /cats/1.mp4 owner videos:/cats#owner # videos /cats/1.mp4 view videos:/cats/1.mp4#owner # videos /cats/1.mp4 view * # videos /cats/2.mp4 owner videos:/cats#owner # videos /cats/2.mp4 view videos:/cats/2.mp4#owner # videos /cats owner cat lady # videos /cats view videos:/cats#owner

2.4.2. System status

Currently, there is only one user namedcat ladyusers added videos. Both videos are incat ladyowned/catdirectory. File/cats/1.mp4can be viewed by anyone (*) view, while/cats/2.mp4There are no additional sharing options, so it can only be viewed by its ownercat ladyThe definition of relationship tuples (relation tuple) is locatedcontrib/cat-videos-example/relation-tuplesdirectory.

2.4.3. Simulate video sharing program

Now you can open a second terminal to run the query, just like the video service client does. In this example, we will use the Keto CLI client. If you want to DockerRun Keto CLI inside the container, set up the alias in the terminal session

alias keto="docker run -it --network cat-videos-example_default -e KETO_READ_REMOTE=\"keto:4466\" oryd/keto:v0.7.0-alpha.1"

Additionally, you need to set the remote endpoint so that the Keto CLI knows where to connect (if using Docker, this is not necessary):

export KETO_READ_REMOTE="127.0.0.1:4466"

2.4.3.1. Check the incoming request

Firstly, we received a request from an anonymous user wanting to view/cats/2.mp4The client must ask Keto whether to allow or deny the operation.

# Is "*" allowed to "view" the object "videos":"/cats/2.mp4"? keto check "*" view videos /cats/2.mp4 # output: # Denied

We have discussed that the request should be denied, but seeing this result in practice is very good.

Nowcat ladyto change/cats/1.mp4expand-API

# Who is allowed to "view" the object "videos":"/cats/2.mp4"? keto expand view videos /cats/1.mp4 # output: # ∪ videos:/cats/1.mp4#view # ├─ ∪ videos:/cats/1.mp4#owner # │ ├─ ∪ videos:/cats#owner # │ │ ├─ ☘ cat lady️ # ├─ ☘ *️

We can see the complete subject collection expansion. The first branch

videos:/cats/1.mp4#view

indicating that each owner of the object is allowed to view

videos:/cats/1.mp4#owner

Next, we see that the owner of the object is/catsthe owner

videos:/cats#owner

We seecat ladyis/catsthe owner.

Note that there is no direct relation tuple (relation tuple) grantedcat ladyto/cats/1.mp4view access due to the fact that it is indirectly defined through ownership relationships.

However, special users*Directly granted view access to the object because it is the first-level leaf of the extension tree. The following CLI command can demonstrate this:

# Is "*" allowed to "view" the object "videos":"/cats/1.mp4"? keto check "*" view videos /cats/1.mp4 # output: # Allowed

The permission to update the view will be added here in a later stage.


3. Keto Concepts

3.1. Relation Tuple

The relation tuple is the underlying data type of Ory Keto's access control language. It encodes objects (objects) and the subject (}}subjects) relationships. Relationship tuples are related to the namespace (namespace) associated with. The following BNF grammar (BNF grammar) describes the encoding used in this document and Ory Keto.

Note:

For readability, namespaces are often omitted in examples, but they are always strictly required.

<relation-tuple> ::= <object>'#'relation'@'<subject> <object> ::= namespace':'object_id <subject> ::= subject_id | <subject_set> <subject_set> ::= <object>'#'relation

relationship tuple

object#relation@subject

Can be converted to the sentence "subjectin objectthere is relation"

3.1.1. Effect of Relationship Tuples (Effect)

The effect of the relationship tuple is in the namespace configuration (namespace configuration) has the effect defined by the relationships. It can be one of the following: union (boolean or), intersection (boolean and), or exclusion (boolean not).

3.1.2. Basic Example

Go to basic full feature exampleView the example with context.

3.2. Namespaces

Ory Keto uses the concept of namespaces (namespace) to organize relationship tuples (relation tuples). Namespaces have defined relationships, as well as other important values (see reference) configuration. Unlike other applications, Ory Keto does not isolate namespaces. The subject set (subject sets) can be cross-referenced from one namespace to another. The purpose of namespaces is to divide data into organized partitions, each with its related configuration.

3.2.1. Scope of Objects

The application can also use namespaces to limit objects (objects) scope, because Ory Keto only compares objects within the same namespace. For example, Ory Keto knows the following relationship tuple

// user1 has permission to access the directory foo directories:foo#access@user1 // user2 has permission to access the file foo files:foo#access@user2

The following checks (check) request

// Does user2 have permission to access the directory foo? directories:foo#access@user2 // Does user1 have permission to access the file foo? files:foo#access@user1

are all calculated as false (i.e., rejected).

Conversely, all relationship tuples containing objects must refer to the same object in the same namespace.

3.2.2. Naming convention

The namespace should be named in the plural form of the type of object it describes (for examplefiles,chats,organizations)。The relationships (relations) in the namespace should be words that describe the relationship between the subject (subject) and the object (object). As a matter of experience, each relationship tuple should be converted into a sentence like this:

Subjectin namespacea objectthere is relation.

For example:

// Good example files:8f427c01-c295-44f3-b43d-49c3a1042f35#write@02a3c847-c903-446a-a34f-dae74b4fab86 groups:43784684-103e-44c0-9d6c-db9fb265f617#member@b8d00059-b803-4123-9d3d-b3613bfe7c1b directories:803a87e9-0da0-486e-bc08-ef559dd8e034#child@(files:11488ab9-4ede-479f-add4-f1379da4ae43#_) files:11488ab9-4ede-479f-add4-f1379da4ae43#parent@(directories:803a87e9-0da0-486e-bc08-ef559dd8e034#_) // Bad example // The namespace does not describe the same-origin type of the object tenant-1-objects:62237c27-19c3-4bb1-9cbc-a5a67372569b#access@7a012165-7b21-495b-b84b-cf4e1a21b484 // relation describes the relationship between object and subject directories:803a87e9-0da0-486e-bc08-ef559dd8e034#parent@(files:11488ab9-4ede-479f-add4-f1379da4ae43#_)

3.3. Object

An object (object) is an identifier for a type of application object. They can represent files, network ports, physical items, and so on. The application maps its objects to explicit identifiers. The limit on object identifiers is 64 characters. We recommend using UUIDs because they provide high entropy and unique identifiers. Arbitrary types of URLs or opaque tokens can also be used. Please check limitations. If the string representation of the objects is equal, then Ory Keto considers them equal.

3.3.1. Basic Example

In the basic case, the object identifier used by the application is the same as the one used internally, such as61e75133-efff-4281-8148-a1806919f568such as UUIDv4, or5c6f593a4e12970d647843f97846fd5ed18179ebsuch as SHA-1 hashes.

Go to basic full feature exampleView the example with context.

3.3.2. Advanced Example: Using in Keto objectsApplicationProgram information

Because the Keto client can use any string as an object (object), it is easy to encode application data within the object.We strongly oppose this practice. Conversely, UUIDs should be used to map application data to Keto objects, which ensures that:

  1. Single truth source and easy data update

  2. Free encoding choice (Keto does not allow characters::#@

  3. Unrestricted data size (Keto allows up to 64 characters only)

For example, this can be used to implement checks on the range of values. The application knows the mapping between the following comparison conditions and UUIDs:

f832e1e7-3c97-4cb8-8582-979e63ae2f1d: greater_than: 5 c4540cf5-6ac4-4007-910b-c5a56aa3d4e6: greater_than: 2 smaller_equal: 5

Keto has the following relation tuples (relation tuples):

// Allows members of the admins group to set values of v > 5 values:f832e1e7-3c97-4cb8-8582-979e63ae2f1d#set_value@(groups:admins#member) // Allows members of the devs group to set values of 2 < v <= 5 values:c4540cf5-6ac4-4007-910b-c5a56aa3d4e6#set_value@(groups:devs#member) // Anyone who can set a value of v > 5 can also set 2 < v <= 5 values:c4540cf5-6ac4-4007-910b-c5a56aa3d4e6#set_value@(values:f832e1e7-3c97-4cb8-8582-979e63ae2f1d#set_value)

The application must translate the incoming 'set value' request into the corresponding conditions that the value satisfies. Understanding Ory Keto does not know how to interpret any informationIt is very important. Conversely, the application must preprocess and map values to the corresponding UUIDs.

3.4. Subjects

In Ory Keto, the subject (subject) is a recursive polymorphic data type. They are either referenced by a specific subject (such as a user) defined by the application identifier, or they refer to a set of subjects.

3.4.1. Subject ID

The subject ID (Subject ID) can be any string. The application maps its users, devices, ... to fixed, unique identifiers. We recommend using UUIDs because they provide high entropy. They can also use any kind of URL or opaque token. Please check limitations. If the string representation of the subject is equal, then Ory Keto considers them equal.

3.4.2. Subject Set

The subject set (subject set) is within an object (object). They enable Ory Keto to be as flexible as you need by defining indirect (indirection) methods. They can be used to implement RBACor the inheritance of relations (inheritance of relations). The set of subjects itself can also indirectly refer to another set of subjects. However, for performance considerations, it is necessary to follow some best practices (best practices). As a special case, the set of subjects can also refer to objects by using empty relations (relation). In fact, this is interpreted as "any relationship, even non-existent ones".

The set of subjects also represents a graph of relations (the graph of relationsin all intermediate nodes.

3.4.3. Basic Example

In basic cases, the application subject identifier used by the application is the same as the one it uses internally, such aszepatriksuch as fixed, unique usernames, or better yet480158d4-0031-4412-9453-1bb0cdf76104vsuch as UUIDv4.

Go to basic full feature exampleView the example with context.

3.4.4. Advanced Example: Using in Keto subjectApplicationProgram information

Because the Keto client can use any string as a subject (subject), encoding application data in the subject is easy.We strongly oppose this practice. On the contrary, it is recommended to use UUID to map application data to the Keto subject, which can ensure that:

  1. Single truth source and easy data update

  2. Free encoding choice (Keto does not allow characters::#@

  3. Unrestricted data size (Keto allows up to 64 characters only)

比如,可以通过将属性映射到主体 ID 的方式,实现粗糙的 ABAC 系统。然后,应用程序可以定义根据属性值反应权限的关系元组(relation tuple)。必须将每个请求映射到代表属性的主体。

假设应用程序知道下述属性和 UUID 之间的映射:

c5b6454f-f79c-4a6d-9e1b-b44e04b56009: subnet: 192.168.0.0/24 office_hours: true

Keto 知晓以下关系元组:

// 在办公时间,当请求来源于特定的子网时,允许访问 TCP 端口 22

tcp/22#access@c5b6454f-f79c-4a6d-9e1b-b44e04b56009

应用程序必须将每个传入的请求映射到代表请求属性的主体字符串。Ory Keto 将使用已知的关系元组,根据代表属性的请求主体的字符串相等性,回复正向的检查响应(check response)。记住,Ory Keto 不知道如何解释存储在关系元组(relation tuple)中的任何信息。相反,应用程序必须预处理,将值映射到相应的 UUID。

3.5. 关系图

可以用关系图表示 Ory Keto 使用的 ACL 的关系元组(relation tuples)。该图将帮助我们理解许多性能影响(implications on performance)和内部算法(internal algorithms)。

3.5.1. 定义

该图由三种类型的节点组成:代表应用程序对象的对象(Object)节点,中间主体集合(subject set)节点,代表个体的主体 ID(subject ID)节点。边是有向的,代表对象(object)和主体(subject)之间的关系(relation)。

3.5.2. 示例

下面的示例将视图关系元组(relation tuple)转换成相应的关系图。

Note:

为提高可读性,该示例在所有数据中省略了命名空间(namespace)。实际上,必须始终考虑命名空间。

// user1 有对 dir1 的访问权限 dir1#access@user1 // 查看主题概念页面,如果您不知道空关系。 dir1#child@(file1#) // Everyone with access to dir1 has access to file1. This would probably be defined // through a subject set rewrite that defines this inherited relation globally. // In this example, we define this tuple explicitly. file1#access@(dir1#access) // Direct access on file2 was granted. file2#access@user1 // user2 is owner of file2 file2#owner@user2 // Owners of file2 have access to it; possibly defined through subject set rewrites. file2#access@(file2#owner)

This is represented by the following diagram:

Solid lines represent explicitly defined relationships, and dashed lines represent relationships inherited through subject sets.

3.5.3. Observations on the graph

Ory Keto utilizes the following key properties of the relationship graph:

  • The search for possible paths is local

These two properties are crucial for ensuring high performance(high performance)are all important.

3.6. APIOverview

This page provides an overview of all the APIs provided by Ory Keto, including common use cases.

Based on permissions, the API is divided into read(read)and write(write)Endpoint. Each endpoint is exposed on different ports, so you can decide how to limit access(you can decide how to restrict access). Reuse gRPC and REST connections on the same port.

Although not always giving feature parity, all APIs are available for gRPC and REST clients. Because we follow gRPC and REST best practices and design guidelines, the API provides slightly different interfaces and features.

3.6.1. Read API

Default on TCP port4466to expose the read API.

3.6.1.1. List Relation Tuples

This API allows querying relation tuples by providing partial relation tuples (relation tuples). It can be used

For more details, please visit gRPC API referenceor REST API reference.

3.6.1.2. List Relation Tuples

check API allows checking if a subject (subject) has a relationship (relation) on an object (object). This API parses the subject set (subject sets) and subject set rewriting (subject set rewrites)。

This API is mainly used to check permissions to restrict operations (check permissions to restrict actions)。

The check request can include the maximum depth of the search tree. If this value is less than 1 or greater than the global maximum depth, then the global maximum depth will be used. This is done to ensure low latency and limit the resource usage of each request.

For more details about the performance of Ory Keto, please see performance considerations.

For more details, please visit gRPC API referenceor REST API reference.

3.6.1.3. Expand Subject Set

The expand API recursively expands the subject set (subject set) into a subject (subject) tree. For each subject, the tree assembles include the namespace configuration (namespace configuration) with the same defined operands (relation tuples). It can be used for:

The expand request can include the maximum depth of the tree to be returned. If this value is less than 1 or greater than the global maximum depth, then the global maximum depth will be used. This is done to ensure low latency and limit the resource usage of each request. For more details about the performance of Ory Keto, please see performance considerations.

For more details, please visit gRPC API referenceor REST API reference.

3.6.2 Write API

Default on TCP port4467to expose the write API.

3.6.2.1. Modify relation tuples

The write API provides various ways to insert and delete relation tuples (relation tuples). Please visit gRPC API referenceor REST API referenceRead more about the available methods for each client type.

For batch updates, it is best to use transaction-based methods rather than repeated calls to simple methods. This is not only because they provide stronger consistency guarantees but also because the speed of processing a single transaction with a large amount of data in the database is usually faster than processing a large number of small transactions.

The main use cases for writing the API are:

  • Set permissions for new objects

  • Share the object with other users

  • Revoke access to the object

  • Transfer the object's relationship to other users


4. Keto Guide

4.1. Security

Like other services in the Ory ecosystem, Ory Keto's API does not integrate access control itself. It assumes that any request made to any Keto API is already authenticated and authorized, thus executing the request. However, these endpoints are very sensitive because they define who is allowed to do what in your system.

Please use an API gateway to protect these endpoints. How to protect them is up to you.

4.2. Checking User Access Permissions

This guide will explain how to use Ory Keto's check API (check-API) to determine the subject (subject) in the object (object). Does there exist a specific relationship (relation). This result can be used to control access to specific resources.

4.2.1. Synchronous Authorization Process

We recommend offloading the entire burden of access control to Ory Keto. Typically, this means the application forwards each incoming request as a check request to Ory Keto. Below is a diagram illustrating this process:

Note that the communication channels between User <-> Application and Application <-> Ory Keto may be very different. The application may provide a JSON API to users, while communicating with Keto via gRPC.

Firstly, the application must reliably verify the user's identity to provide the subject to Keto. This can be achieved by using an authentication system.

Then, the request (decrypting message02y_15_4w350m3). It converts this into a request to the Ory Keto check API (check-API). The application asks Keto, 'Is it allowed for john to decrypt the text 02y_15_4w350m3?'

This issue is encoded as the following relational tuple (relation tuple):

messages:02y_15_4w350m3#decypher@john

Important:

How to encode the check request depends on the application and its defined relation tuples. In this example, we assume that the encrypted message is stored in Ory Keto, and access to the plaintext is controlled bydecypherrelation encoding.

4.2.1.1. Directly defined access

Ory Keto knows the exact relation tuple (relation tuple) that the application is checking. This means direct access is allowedjohnDecrypt the message02y_15_4w350m3(Assuming the "with" in the UI,johnshared "input").

Firstly use the write API (write API)Add relation tuple:

// contrib/docs-code-samples/simple-access-check-guide/00-write-direct-access/main.go package main import ( "context" "fmt" "google.golang.org/grpc" acl "github.com/ory/keto/proto/ory/keto/acl/v1alpha1" ) func main() { conn, err := grpc.Dial("127.0.0.1:4467", grpc.WithInsecure()) if err != nil { panic("Encountered error: " + err.Error()) } client := acl.NewWriteServiceClient(conn) _ , err = client.TransactRelationTuples(context.Background(), &acl.TransactRelationTuplesRequest{ RelationTupleDeltas: []*acl.RelationTupleDelta{ { Action: acl.RelationTupleDelta_INSERT, RelationTuple: &acl.RelationTuple{ Namespace: "messages" Object: "02y_15_4w350m3", Relation: "decypher", Subject: acl.NewSubjectID("john"), }, }, }, } if err != nil { panic("Encountered error: " + err.Error()) } fmt.Println("Successfully created tuple") }

Now, we use the check API to verify the allowedjohnDecrypt the message:

// contrib/docs-code-samples/simple-access-check-guide/01-check-direct-access/main.go package main import ( "context" "fmt" "google.golang.org/grpc" acl "github.com/ory/keto/proto/ory/keto/acl/v1alpha1" ) func main() { conn, err := grpc.Dial("127.0.0.1:4466", grpc.WithInsecure()) if err != nil { panic(err.Error()) } client := acl.NewCheckServiceClient(conn) res, err := client.Check(context.Background(), &acl.CheckRequest{ Namespace: "messages" Object: "02y_15_4w350m3", Relation: "decypher", Subject: acl.NewSubjectID("john"), } if err != nil { panic(err.Error()) } if res.Allowed { fmt.Println("Allowed") return } fmt.Println("Denied") }

4.2.1.2. Indirectly defined access

In addition, access can be indirectly grantedjohnaccess to the resource. This can be done by adding a calledhackersthe group, in order to achieve the goal. Now we can grant each member of the group access to the resource by adding the following relationship tuple to Ory Keto:

messages:02y_15_4w350m3#decypher@(groups:hackers#member)

We also need to make it through adding relationship tuples, so thatjohnbecomeshackergroupmember:

groups:hackers#member@john

Now, when Keto receives the above check request, it will parse the subject set (subject set

groups:hackers#member

Then determinejohnis a subject in the result set. Therefore, it checks the request.

The number of indirect (indirection) is not limited. However, it is through checking the request that it becomes a subject in the result set.best practices), to ensure good performance (performance) is very important.

4.2.2. Caching Keto responses

We do not recommend caching the responses of Ory Keto. It is designed to provide fast responses and some consistency guarantees (some consistency guarantees). It is very important not to use local caching for revocation of access. Ory Keto makes full use of caching in any possible place. If you still find unacceptable slow query requests, make sure to follow our best practices (best practices), to achieve good performance (performance)。

4.2.3. Conclusion

We have learned how to use Ory Keto's check API (check-API) will check the request and integrate access control into the application.

4.3. Enumeration API: Display all objects (object) that users can access

In this guide, you will learn how to use the Ory Keto list API to display a list of all objects (such as files, ...) that users can access. Please refer to gRPCand RESTAPI reference documentation for all details. The List API allows you to query relationship tuples based on partial relationship tuples (relation tuple).

4.3.1. Example

Next, let's take the chat program as an example. Each user is a member of one or more chats, and each chat has one or more members.

Chats are stored in Ory Keto'schatsnamespace. Chats are identified by UUID and mapped to actual object metadata. Users are also identified by UUID and mapped to UUID.

Description:

For readability, the code example uses chat and user names instead of UUIDs. Please refer to objectsand subjectspage to understand why mapping is necessary.

4.3.1.1. List Objects

Our example allows users to browse the chats they belong to. To achieve this goal, the example uses the Ory Keto listing API.

We assume that the application has the following chats:

memes: members: - PM - Vincent - Julia cars: members: - PM - Julia coffee-break: members: - PM - Vincent - Julia - Patrik

In Ory Keto, through the following relationship tuples (relation tuples)to represent them:

chats:memes#member@PM chats:memes#member@Vincent chats:memes#member@Julia chats:cars#member@PM chats:cars#member@Julia chats:coffee-break#member@PM chats:coffee-break#member@Vincent chats:coffee-break#member@Julia chats:coffee-break#member@Patrik

userPMNow open the chat application. To displayPMall chat lists, the application uses Keto's List API:

// contrib/docs-code-samples/list-api-display-objects/01-list-PM/main.go package main import ( "context" "fmt" "google.golang.org/grpc" acl "github.com/ory/keto/proto/ory/keto/acl/v1alpha1" ) func main() { conn, err := grpc.Dial("127.0.0.1:4466", grpc.WithInsecure()) if err != nil { panic(err.Error()) } client := acl.NewReadServiceClient(conn) res, err := client.ListRelationTuples(context.Background(), &acl.ListRelationTuplesRequest{ Query: &acl.ListRelationTuplesRequest_Query{ Namespace: "chats", Relation: "member", Subject: acl.NewSubjectID("PM"), }, } if err != nil { panic(err.Error()) } for _, rt := range res.RelationTuples { fmt.Println(rt.Object) } }

Result:

cars coffee-break memes

In response, the application retrieves the userPMlist of all chats owned. Then, it uses this information to build the UI.

4.3.1.2. List Subjects

Another view of the chat application must display all members of a specific group to the user. The List API can be used to achieve this goal. It uses the information to build the UI.subject sets)in the scenario of modeling member relationships, the Expand API must be used(expand-API)。

Warning:

In this scenario, the application should first use the check API (check-API),to check whether the user is allowed to list the members of the group. This step is not part of this example.

In our example, the user wants to view who iscoffee-breakGroup members:

// contrib/docs-code-samples/list-api-display-objects/02-list-coffee-break/main.go package main import ( "context" "fmt" "google.golang.org/grpc" acl "github.com/ory/keto/proto/ory/keto/acl/v1alpha1" ) func main() { conn, err := grpc.Dial("127.0.0.1:4466", grpc.WithInsecure()) if err != nil { panic(err.Error()) } client := acl.NewReadServiceClient(conn) res, err := client.ListRelationTuples(context.Background(), &acl.ListRelationTuplesRequest{ Query: &acl.ListRelationTuplesRequest_Query{ Namespace: "chats", Object: "coffee-break", Relation: "member", }, } if err != nil { panic(err.Error()) } for _, rt := range res.RelationTuples { fmt.Println(rt.Subject.Ref.(*acl.Subject_Id).Id) } }

Result:

Julia PM Patrik Vincent

4.3.2. Application Context

Special attention should be paid to the fact that the list API does not expand the subject set (subject sets)。Typically, applications have some context to determine what tuples to query. This may be knowledge about the structure of the subject set, such as depth or hierarchy, or UI context, such as the 'My Projects' view should include other objects besides 'My Organization' or 'Shared With Me' views. If it is indeed impossible to narrow the scope of the query, then the Expand API must be used (expand-API),or call the list API repeatedly. Try to avoid this situation, as they require a lot of resources and will quickly degrade service quality. Please refer to performance considerations.

4.3.3. Pagination

The list API only returns pagination results. The order of the results cannot be customized. The response returns an opaque Token used to get the next page. Retrieve the first page by passing no or an empty token.

You can adjust the page size at any time, not just when requesting the first page. The default is 100 entries.

4.4. Expand API: Displaying who has access to objects

This guide will explain how to use Ory Keto's expand API (expand-API) to display who has access to objects (objects) and why. Please refer to gRPCand RESTAPI reference documentation for full details. Expanding the API allows expanding a given subject set (subject set) to all valid subjects (subjects).

4.4.1. Example

In the following example, we will take a file sharing program. Files are organized hierarchically in the directory structure. Each user has files and directories and can grant access to any other user to them at the level of each file or each directory. Users can only view and access the files they own and those to which access has been granted by the owner.

Directories and files are stored separately in Ory Keto'sdirectoriesandfilesWithin the namespace, they are identified by UUIDs, which the application maps to actual object metadata. Users are also identified by UUIDs and are mapped to UUIDs.

Description:

For readability, code examples use object paths and usernames. Please refer to objectsand subjectspage to understand why mapping is necessary.

4.4.1.1. Displaying Access Permissions

To assist users in managing their file permissions, the application must display who has access to the files 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)

这在 Ory Keto 中由以下关系元组(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#_)

usermaureenNow it wants to manage the file/photos/beach.jpgThe access permission. Therefore, the application uses the expand API to obtain the tree of everyone who has the right to access the file:

// contrib/docs-code-samples/expand-api-display-access/01-expand-beach/main.go package main import ( "context" "encoding/json" "os" "github.com/ory/keto/internal/expand" "google.golang.org/grpc" acl "github.com/ory/keto/proto/ory/keto/acl/v1alpha1" ) func main() { conn, err := grpc.Dial("127.0.0.1:4466", grpc.WithInsecure()) if err != nil { panic(err) } client := acl.NewExpandServiceClient(conn) res, err := client.Expand(context.Background(), &acl.ExpandRequest{ Subject: acl.NewSubjectSet("files", "/photos/beach.jpg", "access"), MaxDepth: 3, } if err != nil { panic(err) } tree, err := expand.TreeFromProto(res.Tree) if err != nil { panic(err) } enc := json.NewEncoder(os.Stdout) enc.SetIndent("", " ") if err := enc.Encode(tree); err != nil { panic(err.Error()) } } Result: { "type": "union", "children": [ { "type": "union", "children": [ { "type": "leaf", "subject_id": "maureen" } ], "subject_set": { "namespace": "files", "object": "/photos/beach.jpg", "relation": "owner" } }, { "type": "union", "children": [ { "type": "leaf", "subject_set": { "namespace": "directories", "object": "/photos", "relation": "owner" } }, { "type": "leaf", "subject_id": "laura" } ], "subject_set": { "namespace": "directories", "object": "/photos", "relation": "access" } } ], "subject_set": { "namespace": "files", "object": "/photos/beach.jpg", "relation": "access" } }

4.4.1.2. Maximum tree depth

max-depthThe parameters are very important for keeping the request delay within an acceptable range, but also abstract out the most basic subject set (subject set). In many cases, the application does not want to parse all subject sets but rather want to display, for example, that everyone in the company or administrators have specific relationships (relation).

In this example, the application knows the rough structure of the relation tuples (relation tuple) it uses, so it can determinemax-depth=3Sufficient to display all relevant relationships:

  • Directly authorize access (depth 1)

  • Grant access indirectly through ownership (depth 2)

  • Grant access indirectly through ownership (depth 3)

4.4.1.3. Analyze the tree

This tree includes not only the subject ID (in this case, the username) but also the reasons for their inclusion. This is very useful for user audit permissions. In many cases, the application does not want to list all subject IDs but rather abstract out some sets of subjects.

4.5. Prepare for Production Environment

When self-hosting Ory Keto, read this document to prepare for the production environment.

4.5.1. Database

Ory Keto requires a production-grade database such as PostgreSQL, MySQL, or CockroachDB. Do not use SQLite in a production environment. Read about Ory Deployment Basics and Requirementsfor more information.

4.5.2. APIOry Keto API behind the gateway

Although Ory Keto implements all Go best practices around running a production-facing public HTTP server, we do not encourage running Ory Keto directly facing the public internet. We strongly recommend running Ory Keto behind an API gateway or load balancer. It is common to terminate TLS at the edge (gateway/load balancer) and use certificates provided by infrastructure providers (such as AWS CA) to ensure the security of the last mile. It is a good practice not to expose write APIs to the public network. Read APIs should also be protected as they may leak exposed information (such as who has the right to do something).

4.5.3. Scaling (scaling)

When self-hosting Ory Keto, there are no additional scaling requirements, just start another container.

4.6. Role-Based Access Control (ACL)

This guide will explain how to implement RBAC using Ory Keto.

Risk:

The current implementation of RBAC is feasible, but some workaround methods are needed. This guide enables RBAC support for Keto, but native support is still in progress. Please refer to the issueto follow the progress.

Role Based Access Control (RBAC)Mapping subjects (subject) to roles (role), and roles to permissions (permission). The goal of (H)RBAC is to make permission management more convenient by grouping subjects by roles and assigning permissions to roles. This type of access control is very common in web applications, where roles such as 'admin' and 'host' are often encountered.

In Hierarchical Role Based Access Control (HRBAC)In this context, roles can inherit permissions from other roles. For example, the 'admin' role can inherit all permissions from the 'host' role, which helps reduce repetition and management complexity when defining permissions.

Suppose we are building a reporting program that requires three groups of users with different access levels. The program has the following report groups:

  • Financial Performance Report

  • Marketing Performance Report

  • Community Work Performance Report

This time we use (H)RBAC and rolescommunity,marketing,financeandadminModeling access permissions:

roleadminFromfinance,marketingandcommunityInherit all permissions.

(H)RBAC is ubiquitous. If you have installed forum software such as phpBBor WordpressYou must have encountered ACL, (H)RBAC.

(H)RBAC can reduce management complexity and the overhead brought by a large number of users. However, sometimes even (H)RBAC is not enough. For example, it is necessary to represent ownership (such asDilanCan only modify his own reports), have properties (such asDilanOnly need to access during working hours), or in a multi-tenant environment.

Advantages:

  • Reduce management complexity when multiple identities share similar permissions

  • Role hierarchy can further reduce redundancy

  • Recognized, and easy for developers to understand because it is the de facto standard for web applications

Disadvantages:

  • There is no concept of ownership: Dan is the author of the article 'Hello World', so he is allowed to update the article

  • There is no concept of environment: When the request comes from IP 10.0.0.3, allow Dan to access the account service

  • There is no concept of tenant: Allow Dan to access resources on the 'Dan's Test' tenant

4.6.1. Implement RBAC with Ory Keto

We need three groupsfinance,marketing,community. We also need two namespaces: one for managing access controlreportsand for adding users to groupsgroups.

Firstly, add the namespace (namespace) to the Keto configuration.Here

# ... namespaces: - id: 0 name: groups - id: 1 name: reports #...

We have two types of permissions, assuming we need to reporteditandviewPermissions.

// View only access for finance department reports:finance#view@(groups:finance#member) // View only access for community department reports:community#view@(groups:community#member) // View only access for marketing department reports:marketing#view@(groups:marketing#member) // Edit access for admin group reports:finance#edit@(groups:admin#member) reports:community#edit@(groups:admin#member) reports:marketing#edit@(groups:admin#member) reports:finance#view@(groups:admin#member) reports:community#view@(groups:admin#member) reports:marketing#view@(groups:admin#member)

Assuming there are four people in our organization. Lila is the CFO, who needs to view financial reports, Hadley works in marketing, Dilan is a community administrator. Neel is the system administrator, who needs editing permissions for the reports.

groups:finance#member@Lila groups:community#member@Dilan groups:marketing#member@Hadley groups:admin#member@Neel

4.6.2. Create Relationship Tuples

We copy all permissions and create a file with the following contentpolicies.rtsfile.

reports:finance#view@(groups:finance#member) reports:community#view@(groups:community#member) reports:marketing#view@(groups:marketing#member) reports:finance#edit@(groups:admin#member) reports:community#edit@(groups:admin#member) reports:marketing#edit@(groups:admin#member) reports:finance#view@(groups:admin#member) reports:community#view@(groups:admin#member) reports:marketing#view@(groups:admin#member) groups:finance#member@Lila groups:community#member@Dilan groups:marketing#member@Hadley groups:admin#member@Neel

Then run

keto relation-tuple parse policies.rts --format json | \ keto relation-tuple create - >/dev/null \ && echo "Successfully created tuple" \ || echo "Encountered error"

Since Dilan is a community administrator, the following example of checks shows that he can only access community reports

keto check Dilan view reports finance Denied keto check Dilan view reports community Allowed keto check Dilan edit reports community Denied

Now Dilan decides to cooperate with marketing. Therefore, we need to update his permissions and add him to the marketing group

groups:marketing#member@Dilan

Now he can also access the marketing reports

keto check Dilan view reports marketing Allowed

4.6.3. Display all objects that a user can access

The following example shows you how to get the list of objects that Dilan can access

# Get all groups for Dilan keto relation-tuple get --subject-id=Dilan --relation=member --format json --read-remote localhost:4466 | jq { "relation_tuples": [ { "namespace": "groups", "object": "community", "relation": "member" "subject_id": "Dilan" }, { "namespace": "groups", "object": "marketing" "relation": "member" "subject_id": "Dilan" } ], "next_page_token": "" } # Get permissions to objects for marketing group keto relation-tuple get --subject-set="groups:marketing#member" --format json --read-remote localhost:4466 | jq { "relation_tuples": [ { "namespace": "reports" "object": "marketing" "relation": "view" "subject_set": { "namespace": "groups", "object": "marketing" "relation": "member" } } ], "next_page_token": "" } # Get permissions to objects for community group keto relation-tuple get --subject-set="groups:community#member" --format json --read-remote localhost:4466 | jq { "relation_tuples": [ { "namespace": "reports" "object": "community", "relation": "view" "subject_set": { "namespace": "groups", "object": "community", "relation": "member" } } ], "next_page_token": "" }


5. Example

Basic example: Olymp Library

A basic, practical full-featured example

Suppose there is a file sharing application named 'Olymp Library'. Each file is stored in a key-value store, with the key being a UUIDv4 (a pseudo-random unique identifier) and the value being metadata and content. The application uses Ory Keto to track ownership and granted access permissions at the file level.

Note:

This example assumes that a defined relationship (relation) existsownerandaccessof the namespace(namespacefiles. Each owner of an object can also access the object. All relation tuples (relation tuple) are stored in this namespace.

Now, the user identified by a unique usernamedemeterI want to upload a file containing the most fertile soil. The file is assigned a UUIDec788a82-a12e-45a4-b906-3e69f78c94e4)。The application adds the following relation tuple (write-API)to add the following relation tuple (relation tuple):

ec788a82-a12e-45a4-b906-3e69f78c94e4#owner@demeter

to prepare for a meeting with the userathenaan important meeting,demeterhope to haveathenaShare the file containing fertile land so that they can all read the file. Therefore, he opens the "Olymp Library", lists all the files he owns. The application internally uses the list API(list-API)request the ownerdemeterof all objects(objects,file ID). The response will include objectsec788a82-a12e-45a4-b906-3e69f78c94e4,and the application maps it to the file in the question.

Then, the userdemeterRequest the application withathenaShare the file, the application converts the request into a write API request to add the following relation tuple (relation tuple) to Ory Keto(write-API request):

ec788a82-a12e-45a4-b906-3e69f78c94e4#access@athena

To confirm the operation is successful, the application uses Ory Keto's expand API(expand-API)Compile a list of all users who can access this file:

// The following subject set is expanded by Keto ec788a82-a12e-45a4-b906-3e69f78c94e4#access

The expand API will return an expanded tree

∪ ec788a82-a12e-45a4-b906-3e69f78c94e4#access ├─ ∪ ec788a82-a12e-45a4-b906-3e69f78c94e4#owner │ ├─ ☘ demeter ├─ ☘ athena

Then, 'Olymp Library' sends todemeterDisplay this information.

WhenathenaWhen the application wants to get a file with fertile soil, it uses the check API(check-API)to verifyathenaAccess to this file. By deleting the corresponding relationship tuples, it allowsdemeterRevocation at any timeathenaaccess permissions.


6. Local Setup and Configuration of Keto

6.1. Environment Description

  • Operating System: Ubuntu 18.04.6 LTS

  • Go: go version go1.18.8 linux/amd64

6.2. Install keto

git clone https://github.com/ory/keto -b v0.8.0-alpha.2 cd keto/ go mod download go install -tags sqlite,json1,hsm . $(go env GOPATH)/bin/keto help

ExecuteGOPATHAdd toPATHIn:

export PATH=$PATH:$(go env GOPATH)/bin

6.3. Create configuration file keto.yaml

version: v0.8.0-alpha.2 log: level: debug namespaces: - id: 0 name: groups - id: 1 name: reports dsn: memory serve: read: host: 0.0.0.0 port: 4466 write: host: 0.0.0.0 port: 4467

6.4. Start Keto

keto serve -c keto.yaml

6.5. Test with the use cases in the RBAC chapter


Reference Document

你可能想看:

Class and object - object characteristics - separate storage of member variables and member functions

Data security can be said to be a hot topic in recent years, especially with the rapid development of information security technologies such as big data and artificial intelligence, the situation of d

In today's rapidly developing digital economy, data has become an important engine driving social progress and enterprise development. From being initially regarded as part of intangible assets to now

2.1 Find the location and the root cause of the problem in the code for the large object

1.1 Create user objects from the Active Directory Users and Computers console

Based on AbstractProcessor, MapStruct is extended to automatically generate entity mapping utility classes

Announcement regarding the addition of 7 units as technical support units for the Ministry of Industry and Information Technology's mobile Internet APP product security vulnerability database

5. Collect exercise results The main person in charge reviews the exercise results, sorts out the separated exercise issues, and allows the red and blue sides to improve as soon as possible. The main

4.5 Main person in charge reviews the simulation results, sorts out the separated simulation issues, and allows the red and blue teams to improve as soon as possible. The main issues are as follows

Ensure that the ID can be accessed even if it is guessed or cannot be tampered with; the scenario is common in resource convenience and unauthorized vulnerability scenarios. I have found many vulnerab

最后修改时间:
admin
上一篇 2025年03月26日 04:16
下一篇 2025年03月26日 04:39

评论已关闭