关于javascript:RBAC-和-KetoGo-RBAC-框架

56次阅读

共计 26158 个字符,预计需要花费 66 分钟才能阅读完成。

  1. RBACRBAC(Role-Based Access Control)是最通用的权限拜访控制系统。其思维是,不间接授予具体用户各种权限,而是在用户汇合和权限汇合之间建设角色汇合。每种角色对应一组相应的权限,一旦用户被调配适当的角色,他就领有此角色的所有权限。这样做的益处是,不用在每次创立用户时都调配权限,只有给用户调配相应的角色即可,并且角色的权限变更比用户的权限变更要少得多,这将简化用户的权限治理,缩小零碎开销。RBAC 有三种模型。1.1. RBAC0 它是其它 RBAC 模型的根底。在该模型中,用户和角色之间是多对多的关系,每个角色至多有一个权限。

    1.2. RBAC1 在 RBAC0 的根底上,引入角色间的继承关系,即角色有上下级的区别。角色间的继承关系可分为个别继承关系和受限继承关系。个别继承关系要求角色继承关系是相对偏序关系,容许角色间的多继承。而受限继承关系则进一步要求角色继承关系是树状构造,实现角色间的单继承。

    1.3. RBAC2 在 RBAC0 的根底上,引入角色的访问控制。该模型有以下两种束缚:动态职责拆散互斥角色:互斥角色是指各自权限能够互相制约的角色。对于这类角色,用户在某次流动中只能被调配其中的一个角色,不能同时取得多个角色的使用权。比方在审计流动中,一个用户不能被同时调配会计角色和审计员角色基数束缚:一个角色被调配的用户数量受限;一个用户可领有的角色数量受限;一个角色对应的拜访权限数目也受限,以管制高级权限的调配。比方公司的管理层是无限的先决条件角色:要想取得较高的权限,首先要领有低一级的权限动静职责拆散运行时互斥:动静地束缚用户领有的角色,比方一个用户能够领有两个角色,然而运行时只能激活其中一个

  2. Keto 介绍 2.1. 介绍 Ory Permissions(基于开源的 Ory Keto Permission Server)是第一个、惟一的“Zanzibar:Google 的统一的、寰球的受权零碎”的开源实现。如果你须要晓得是否容许一个用户做某些事件 – Ory Permissions 非常适合你。Ory Permission 实现根本的 API 契约,用于应用 HTTP 和 gRPC API 治理和查看关系(“权限”)。将来的版本将蕴含用户集重写(比方 RBAC 格调的角色 - 权限模型)、Zookies 等个性。2.2. 装置 Ory 软件能够运行在任何操作系统(FreeBSD、macOS、Linux、Windows、…)上,反对所有次要 CPU(ARM64、ARMv7、x86_64、x86、…)平台。Ory 提供预构建的二进制、Docker 镜像,反对多种包管理器。详情请参考:https://www.ory.sh/docs/keto/install2.3. 性能本文档解释 Ory Keto 的工夫复杂度(time complexity)。稍后将剖析和增加主内存复杂度。咱们只查看评估引擎(检查和开展 API),因为其它局部次要由依赖决定,比方你抉择的数据库、音讯的解 / 编码。为清晰起见,给定的示例疏忽命名空间(namespace)。2.3.1. 查看引擎实质上,查看引擎(check-engine)假如关系元组(relation tuple)和它们的间接组合成一个无环有向图,被称为关系图(the graph of relations)。思考上面的示例: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 被解释为下图:

    通过从 object 开始搜寻图,通过 relation,尝试达到 user 的形式,计算 object#relation@user 模式的查看申请。如果存在这样的门路,那么容许申请。Ory Keto 应用的图遍历算法是广度优先搜寻。在最坏的状况下,工夫复杂度是 O(n+e),其中 n 是从节点 object#relation 通过 e 条边可达到的节点数。重排列,工夫和空间复杂度都是 o(b^d),其中 b 是从搜寻根见到的最大宽度,d 是最大深度。这意味着复杂性很大水平上取决于图的构造。如果图蕴含深度嵌套的间接(indirection),须要屡次递归调用解析这些间接。相似地,如果有广度嵌套的间接,Ory Keto 必须能解析所有间接。指标是以只需解析少许间接的形式,设计 ACL 元组。理解更多对于 ACL 设计的最佳实际。因而,咱们认为惯例的基准测试不会产生任何有意义的后果。因而,咱们将在稍后增加与其它相似我的项目的比拟。2.3.2. 扩大引擎与查看引擎遍历关系元组(relation tuple)图的形式相似,扩大引擎构建它遇到的所有汇合操作的树。它解析从申请的主体汇合(subjectset)开始到指定深度的所有间接(indirection)。因为它也是用广度优先搜寻,工夫和空间复杂度线性依赖于从申请的主体汇合可达到的节点。同样的性能思考也实用于这里,须要特地留神的是,申请较低的深度将进一步限度操作的复杂度。如果关系元组是深嵌套和 / 或宽泛嵌套的,那么返回的树也可能很快超过正当的大小限度。2.3.3. 参考 Wikipedia Breadth-first search2.4. 疾速入门:猫视频示例本示例介绍一个视频共享服务。视频被组织在目录中。每个目录有一个所有者,每个视频的所有者与其父目录雷同。所有者有视频文件的特权,无需独自地在 Ory Keto 中建模。在本例中,建模的其它权限只有“视图拜访”,每个所有者都有对其对象的视图拜访权,也能授予其它用户该权限。视频共享应用程序将非凡的 * 用户 ID 解释为任何用户,爱护匿名用户。留神,Ory Keto 对该主体的解读与其它主体并无不同。它不晓得对于目录构造或诱发的所有权的任何事件。术语:“Keto 客户端”是与 Keto 进行交互的应用程序。在本例中,咱们将视频共享服务后端称为 Keto 客户端。2.4.1. 开始示例首先,装置 Keto。当初能够应用 docker-compose 或 bash 脚本启动示例。bash 脚本须要你在 $PATH 中领有 keto 二进制程序。或者,应用 Docker 主动获取所需的镜像。# 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

./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#owner2.4.2. 零碎状态在以后状态下,只有一个用户名为 cat lady 的用户增加了视频。两个视频都在 cat lady 领有的 /cat 目录下。文件 /cats/1.mp4 可被任何人()查看,而 /cats/2.mp4 没有额定的共享选项,因而只能被它的所有者 cat lady 拜访。关系元组(relation tuple)的定义位于 contrib/cat-videos-example/relation-tuples 目录。2.4.3. 模仿视频共享程序当初能够关上第二个终端来运行查问,就像视频服务客户端所做的那样。在本例中,咱们将应用 Keto CLI 客户端。如果想在 Docker 内运行 Keto CLI,在终端会话中,设置别名 alias keto=”docker run -it –network cat-videos-example_default -e KETO_READ_REMOTE=\”keto:4466\” oryd/keto:v0.7.0-alpha.1″ 另外须要设置近程端点,以便 Keto CLI 晓得连贯到哪里(如果应用 Docker,则不须要):export KETO_READ_REMOTE=”127.0.0.1:4466″2.4.3.1. 查看传入申请首先,咱们收到一个匿名用户的申请,想要查看 /cats/2.mp4。客户端必须询问 Keto,容许还是回绝该操作。# Is “” allowed to “view” the object “videos”:”/cats/2.mp4″?

keto check “*” view videos /cats/2.mp4

output:

Denied 咱们曾经探讨过该申请应该被回绝,但在实际操作中看到该后果是十分好的。当初 cat lady 想要扭转 /cats/1.mp4 的查看权限。为此,视频服务应用程序必须展现容许查看该视频的所有用户。它应用 Keto 的扩大 API(expand-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️

├─ ☘ ️ 咱们能够看到残缺的主体汇合扩大。第一个分支 videos:/cats/1.mp4#view 示意容许对象的每个所有者查看 videos:/cats/1.mp4#owner 下一步,咱们看到对象的所有者是 /cats 的所有者 videos:/cats#owner 咱们看到 cat lady 是 /cats 的所有者。留神,没有间接关系元组(relation tuple)授予 cat lady 对 /cats/1.mp4 的视图拜访权限,因为这是通过所有权关系间接定义的。然而,非凡用户 被间接授予对对象的视图拜访权限,因为它是扩大树的第一级叶子。上面的 CLI 命令能够证实这一点:# Is “*” allowed to “view” the object “videos”:”/cats/1.mp4″?

keto check “*” view videos /cats/1.mp4

output:

Allowed 更新视图权限将在稍后的阶段增加到这里。3. Keto 概念 3.1. 关系元组关系元组(relation tuple)是 Ory Keto 的访问控制语言的底层数据类型。它编码对象(objects)和主体(subjects)之间的关系。关系元组与定义和配置它的关系的命名空间(namespace)相关联。上面的 BNF 语法(BNF grammar)形容该文档和 Ory Keto 里应用的编码。留神:为晋升可读性,在示例中常常疏忽命名空间,但总是严格须要的。<relation-tuple> ::= <object>’#’relation’@'<subject>

<object> ::= namespace’:’object_id
<subject> ::= subject_id | <subject_set>
<subject_set> ::= <object>’#’relation 关系元组 object#relation@subject 可被转换为句子“subject 在 object 上有 relation”。3.1.1. 关系元组的成果(Effect)关系元组的成果是在命名空间配置(namespace configuration)中定义的关系的成果。它能够是并集(布尔 or)、交加(布尔 and)或排除(布尔 not)中的一个。3.1.2. 根底示例返回 basic full feature example 查看带上下文的示例。3.2. 命名空间 Ory Keto 应用命名空间(namespace)的概念组织关系元组(relation tuples)。命名空间领有定义关系,以及其它重要值(see reference)的配置。与其它应用程序不同,Ory Keto 不隔离命名空间。主体汇合(subject sets)能够从一个命名空间穿插援用到另一命名空间。命名空间的用处是将数据宰割成有条理的分区,每个分区有它的相干配置。3.2.1. 对象的作用域应用程序也能够应用命名空间来限定对象(objects)的范畴,因为 Ory Keto 仅比拟命名空间内的对象。比方,Ory Keto 通晓上面的关系元组 // user1 有权限拜访目录 foo
directories:foo#access@user1
// user2 有权限拜访文件 foo
files:foo#access@user2 上面的查看(check)申请 // user2 有权限拜访目录 foo 吗?
directories:foo#access@user2
// user1 有权限拜访文件 foo 吗?
files:foo#access@user1 都计算为 false(即回绝)。反之亦然,所有蕴含对象的关系元组必须在雷同的命名空间中援用雷同的 object。3.2.2. 命名约定命名空间应该以它们形容的对象的类型的复数模式命名(比方 files、chats、organizations)。命名空间中的关系(relation)应该是一个形容主体(subject)到对象(object)之间的关系的词。作为经验之谈,每个关系元组应该转换成相似这样的句子:Subject 在 namespace 的一个 object 上有 relation。比方:// 好示例

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#_)

// 坏示例

// 命名空间未形容对象的同源类型
tenant-1-objects:62237c27-19c3-4bb1-9cbc-a5a67372569b#access@7a012165-7b21-495b-b84b-cf4e1a21b484
// relation 形容 object 到 subject 之间的关系
directories:803a87e9-0da0-486e-bc08-ef559dd8e034#parent@(files:11488ab9-4ede-479f-add4-f1379da4ae43#_)3.3. 对象对象(object)是某种应用程序对象的标识符。它们能够代表文件、网络端口、物理项等。由应用程序将其对象映射到明确的标识符。对象标识符上的限度是 64 个字符。咱们倡议应用 UUID,因为它们提供高熵值和惟一标识符。也能够应用任意品种的 URL 或不通明令牌。请查看 limitations。如果对象的字符串示意相等,那么 Ory Keto 认为它们相等。3.3.1. 根本示例在根本状况下,应用程序应用的对象标识符与其外部应用的雷同,比方 61e75133-efff-4281-8148-a1806919f568 之类的 UUIDv4,或 5c6f593a4e12970d647843f97846fd5ed18179eb 之类的 SHA-1 哈希。返回 basic full feature example 查看带上下文的示例。3.3.2. 高级示例:在 Keto 对象里应用应用程序信息因为 Keto 客户端可应用任意字符串作为对象(object),所以在对象中编码应用程序数据很容易。咱们强烈拥护这种做法。相同,应该应用 UUID 将应用程序数据映射到 Keto 对象,这样做能够确保:繁多的假相起源和容易的数据更新自在的编码抉择(Keto 不容许字符::#@)不受限制的数据大小(Keto 只容许至少 64 个字符)比方,这能够用于实现对值范畴的查看。应用程序晓得下述比拟条件和 UUID 之间的映射:f832e1e7-3c97-4cb8-8582-979e63ae2f1d:
greater_than: 5

c4540cf5-6ac4-4007-910b-c5a56aa3d4e6:
greater_than: 2
smaller_equal: 5Keto 领有如下关系元组(relation tuple):// 容许 admins 组的成员设置 v > 5 的值
values:f832e1e7-3c97-4cb8-8582-979e63ae2f1d#set_value@(groups:admins#member)

// 容许 devs 组的成员设置 2 < v <= 5 的值
values:c4540cf5-6ac4-4007-910b-c5a56aa3d4e6#set_value@(groups:devs#member)

// 任何能够设置 v > 5 的值的人也能够设置 2 < v <= 5
values:c4540cf5-6ac4-4007-910b-c5a56aa3d4e6#set_value@(values:f832e1e7-3c97-4cb8-8582-979e63ae2f1d#set_value) 应用程序必须将传入的“set value”申请翻译成该值满足的相应条件。了解 Ory Keto 不晓得如何解释任何信息很重要。相同,应用程序必须预处理,将值映射到相应的 UUID。3.4. 主体在 Ory Keto 中,主体(subject)是递归的多态数据类型。它们要么通过利用程序定义的标识符援用特定的主体(比方用户),要么援用主体汇合。3.4.1. 主体 ID 主体 ID(Subject ID)能够是任意字符串。由应用程序映射它的用户、设施、… 到固定的、惟一的标识符。咱们倡议应用 UUID,因为它们提供高熵值。也能够应用任意品种的 URL 或不通明令牌。请查看 limitations。如果主体的字符串示意相等,那么 Ory Keto 认为它们相等。3.4.2. 主体汇合主体汇合(subject set)是在一个对象(object)上领有特定关系(relation)的所有主体(subject)的汇合。它们通过定义间接(indirection)的形式,使 Ory Keto 像你须要的一样灵便。能够用它们实现 RBAC 或关系的继承(inheritance of relations)。主体汇合自身能够再一次间接到主体汇合。但出于性能思考,须要遵循一些最佳实际(best practices)。作为一种非凡状况,主体汇合也能够通过应用空关系(relation)的形式,援用对象(object)。实际上,这被解释为“任意关系,甚至是不存在的关系”。主体汇合也示意关系图(the graph of relations)中的所有两头节点。3.4.3. 根本示例在根本状况下,应用程序应用的主体(subject)标识符与其外部应用的雷同,比方 zepatrik 之类的固定的、惟一的用户名,或者最好是 480158d4-0031-4412-9453-1bb0cdf76104v 之类的 UUIDv4。返回 basic full feature example 查看带上下文的示例。3.4.4. 高级示例:在 Keto 主体中应用应用程序信息因为 Keto 客户端能够应用任意字符串作为主体(subject),所以在主体中编码应用程序数据很容易。咱们强烈拥护这种做法。相同,应该应用 UUID 将应用程序数据映射到 Keto 主体,这样做能够确保:繁多的假相起源和容易的数据更新自在的编码抉择(Keto 不容许字符::#@)不受限制的数据大小(Keto 只容许至少 64 个字符)比方,能够通过将属性映射到主体 ID 的形式,实现毛糙的 ABAC 零碎。而后,应用程序能够定义依据属性值反馈权限的关系元组(relation tuple)。必须将每个申请映射到代表属性的主体。假如应用程序晓得下述属性和 UUID 之间的映射:c5b6454f-f79c-4a6d-9e1b-b44e04b56009:
subnet: 192.168.0.0/24
office_hours: trueKeto 通晓以下关系元组:// 在办公时间,当申请来源于特定的子网时,容许拜访 TCP 端口 22tcp/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)转换成相应的关系图。留神:为进步可读性,该示例在所有数据中省略了命名空间(namespace)。实际上,必须始终思考命名空间。// user1 has access on dir1
dir1#access@user1
// Have a look on the subjects concept page if you don’t know the empty relation.
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) 这由上面的图示意:

实线边代表显式定义的关系,虚线边代表通过主体汇合继承的关系。3.5.3. 对于图的察看 Ory Keto 利用关系图的以下要害属性:从对象到主体的有向边:这意味着在一个区域内参差地排列对象(object),在另一个区域中排列主体 ID(subject ID),在它们之间排列主体汇合(subject set)。边总是从对象区域指向主体区域搜寻可能的门路是部分的:试图找到从对象到主体的门路总是在部分产生。这意味着仅需遍历对象的后继节点。在典型的设置中,这意味着无论后果如何,只须要搜寻图的一小部分。这里能够直观地看到,当查看对 user2 的文件的拜访时,user1 的文件的关系是无关的这两个属性对于确保高性能(high performance)都很重要。3.6. API 概览该页面给出 Ory Keto 提供的所有 API 的概览,包含常见的用例。基于权限,将 API 分为读(read)和写(write)端点。在不同的端口上裸露每个端点,因而你能够决定如何限度拜访(you can decide how to restrict access)。在雷同的端口上复用 gRPC 和 REST 连贯。只管不总是给出个性平等,然而所有 API 都可用于 gRPC 和 REST 客户端。因为咱们遵循 gRPC 和 REST 最佳实际和设计指南,所以 API 提供略微不同的接口和性能。3.6.1. 读 API 默认在 TCP 端口 4466 上裸露读 API。3.6.1.1. 列出关系元组该 API 容许通过提供局部关系元组查问关系元组(relation tuples)。可用于列出用户能够拜访的对象(list objects a user has access to)列出领有特定角色的用户(list users who have a specific role)列出特定组的成员审计零碎权限要理解更多细节,请拜访 gRPC API reference 或 REST API reference。3.6.1.2. 查看关系元组查看 API 容许查看主体(subject)在对象(object)上是否有关系(relation)。该 API 解析主体汇合(subject sets)和主体汇合重写(subject set rewrites)。该 API 次要用于查看权限以限度操作(check permissions to restrict actions)。查看申请能够蕴含搜寻树的最大深度。如果该值小于 1 或大于全局的最大深度,那么将应用全局的最大深度。这样做是为了确保低提早和限度每个申请的资源应用。如欲了解更多对于 Ory Keto 性能的细节,请查看 performance considerations。要理解更多细节,请拜访 gRPC API reference 或 REST API reference。3.6.1.3. 开展主体汇合开展 API 递归地将主体汇合(subject set)开展为主体(subject)树。对于每个主体,该树组装蕴含与命名空间配置(namespace configuration)中的定义雷同的操作数的关系元组(relation tuple)。可用于:列出谁能够拜访对象(list who has access to an object)确定某人为什么能够拜访对象审计零碎中的权限开展申请能够蕴含要返回的树的最大深度。如果该值小于 1 或大于全局的最大深度,那么将应用全局的最大深度。这样做是为了确保低提早和限度每个申请的资源应用。如欲了解更多对于 Ory Keto 性能的细节,请查看 performance considerations。要理解更多细节,请拜访 gRPC API reference 或 REST API reference。3.6.2 写 API 默认在 TCP 端口 4467 上裸露写 API。3.6.2.1. 扭转关系元组写 API 提供多种形式插入和删除关系元组(relation tuple)。请拜访 gRPC API reference 或 REST API reference 浏览对于每种客户端类型的可用办法的更多信息。对于批量更新,最好应用基于事务的办法,而不是反复调用简略办法。这不仅因为它们提供更强的一致性保障,而且因为数据库解决具备大量数据的单个事务的速度通常比解决大量小事务快。写 API 的次要用例是:为新对象设置权限与其它用户共享对象撤销对对象的拜访将对象的关系转移到其它用户 4. Keto 指南 4.1. 平安与 Ory 生态系统中的其它服务相似,Ory Keto 的 API 本人未集成访问控制。认为对任何 Keto API 发动的任何申请都已认证、已受权,因而执行申请。然而,这些端点十分敏感,因为它们定义在你的零碎中容许谁做什么。请应用 API 网关爱护这些端点。如何爱护它们,由你决定。4.2. 检查用户是否有拜访权限本指南将论述如何应用 Ory Keto 的查看 API(check-API)来确定主体(subject)在对象(object)上是否有特定的关系(relation)。该后果可用于管制对特定资源的拜访。4.2.1. 同步的受权流程咱们倡议将访问控制的全副重任交给 Ory Keto。通常,这意味着应用程序将每个传入申请作为查看申请转发给 Ory Keto。上面是展现该流程的图表:

留神 User <-> Application 和 Application <-> Ory Keto 之间的通信通道可能十分不同。应用程序可能向用户提供 JSON API,而与 Keto 通过 gRPC 进行通信。首先,应用程序必须牢靠地验证用户身份,以便将主体(subject)提供给 Keto。能够通过应用认证零碎的形式,达成此指标。而后,将申请(解密音讯 02y_15_4w350m3)转换为对 Ory Keto 查看 API(check-API)的申请。应用程序问 Keto“容许 john 解密文本 02y_15_4w350m3 吗?”该问题被编码为上面的关系元组(relation tuple):messages:02y_15_4w350m3#decypher@john 重要:如何编码查看申请取决于应用程序及其定义的关系元组。在本例中,咱们假设已知的加密音讯存储在 Ory Keto 中,对明文的拜访由 decypher 关系编码。4.2.1.1. 间接定义的拜访 Ory Keto 晓得应用程序正在查看的确切关系元组(relation tuple)。这意味着间接容许 john 解密音讯 02y_15_4w350m3(假如 UI 中的“与 john 共享”输出)。首先应用写 API(write API)增加关系元组:// 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”)
} 当初,咱们应用查看 API 来验证容许 john 解密音讯:// 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. 间接定义的拜访另外,能够间接地授予 john 对资源的拜访权限。能够通过增加一个叫 hackers 的组,来实现该指标。当初咱们能够通过向 Ory Keto 增加如下关系元组的形式,授予该组中的每个人对资源的拜访权限:messages:02y_15_4w350m3#decypher@(groups:hackers#member) 咱们也必须通过增加关系元组的形式,使 john 成为 hacker 组的 member:groups:hackers#member@john 当初,当 Keto 接管下面的查看申请时,它将解析主体汇合(subject set)groups:hackers#member 而后确定 john 是后果汇合中的一个主体。因而,它通过查看申请。间接(indirection)的数量没有限度。然而,遵循咱们的最佳实际(best practices),以确保良好的性能(performance)是很重要的。4.2.2. 缓存 Keto 响应咱们不倡议缓存 Ory Keto 的响应。它被设计为疾速响应,以及提供一些一致性保障(some consistency guarantees)。对于拜访的撤销而言,不应用本地缓存很重要。Ory Keto 在任何可能的中央充沛地利用缓存。如果依然发现令人无奈承受的慢查问申请,请确保遵循咱们的最佳实际(best practices),以取得良好的性能(performance)。4.2.3. 论断咱们曾经学习了如何应用 Ory Keto 的查看 API(check-API)将查看申请和访问控制集成到应用程序中。4.3. 列举 API:显示用户能够拜访的所有对象(object)在本指南中,你将学习如何应用 Ory Keto 的列表 API 来显示用户能够拜访的所有对象(比方文件、…)的列表。请查阅 gRPC 和 REST API 援用文档,获取所有细节。列表 API 容许你基于局部关系元组(relation tuple)查问关系元组。4.3.1. 示例上面咱们以聊天程序为示例。每个用户是一或多个聊天的成员,每个聊天有一或多个成员。聊天被存储在 Ory Keto 的 chats 命名空间中。用 UUID 标识聊天,应用程序将其映射到理论的对象元数据。用户也被 UUID 标识,被映射到 UUID。阐明:因可读性缘故,代码示例应用聊天和用户的名称代替 UUID。请参考 objects 和 subjects 页面,理解为何映射是必要的。4.3.1.1. 列出对象咱们的示例容许用户浏览他们所属的聊天。为达成该指标,该示例应用 Ory Keto 列举 API。咱们假如应用程序有如下聊天:memes:
members:

- PM
- Vincent
- Julia

cars:
members:

- PM
- Julia

coffee-break:
members:

- PM
- Vincent
- Julia
- Patrik 在 Ory Keto 中通过上面的关系元组(relation tuples)代表它们: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 用户 PM 当初关上聊天利用。为展现 PM 的所有聊天的列表,应用程序应用 Keto 的列表 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)

}
} 后果:cars
coffee-break
memes 作为响应,应用程序获取用户 PM 所属的所有聊天的列表。而后,它应用该信息构建 UI。4.3.1.2. 列出主体聊天利用的另一个视图必须向用户显示特定组的所有成员。能够应用列表 API 达成该指标。在通过主体汇合(subject sets)建模成员关系的场景下,必须应用开展 API(expand-API)。正告:在该场景下,应用程序应该先应用查看 API(check-API),查看是否容许用户列出组的成员。该步骤不是本示例的一部分。在咱们的示例中,用户想要查看谁是 coffee-break 组的成员:// 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)

}
} 后果:Julia
PM
Patrik
Vincent4.3.2. 应用程序上下文须要特地留神,列表 API 不开展主体汇合(subject sets)。通常应用程序有一些用于确定要查问什么元组的上下文。这可能是对于主体汇合(subject set)的构造的常识,比方深度或层级,或 UI 上下文,比方“我的我的项目”视图应该蕴含“我的组织”或“与我共享”视图以外的其它对象。如果的确无奈放大查问的范畴,那么必须应用开展 API(expand-API),或者反复调用列表 API。尽量避免这种状况,因为它们须要大量资源,并且会迅速升高服务质量。请参考 performance considerations。4.3.3. 分页列表 API 只返回分页后果。无奈定制后果的程序。响应返回用于获取下一页的非通明 Token。通过传递 no 或空 token 的形式,检索第一页。能够随时调整页面大小,而不仅仅是在申请第一页时。默认为 100 个条目。4.4. 开展 API:显示谁有权拜访对象本指南将论述如何应用 Ory Keto 的开展 API(expand-API),来显示谁有权拜访对象(object),以及为什么。请参考 gRPC 和 REST API 援用文档,获取全副细节。开展 API 容许将给定的主体汇合(subject set)开展为所有无效的主体(subject)。4.4.1. 示例上面咱们以文件共享程序为例。在目录构造中按层级组织文件。每个用户领有文件和目录,能够在每个文件或每个目录的根底上授予任何其它用户拜访它们的权限。用户仅能查看和拜访他们领有的,以及被所有者授予拜访权限的文件。目录和文件别离存储在 Ory Keto 的 directories 和 files 命名空间内。它们由 UUID 标识,应用程序将其映射到理论的对象元数据。用户也由 UUID 标识,被映射到 UUID。阐明:因可读性缘故,代码示例应用对象门路和用户名称。请参考 objects 和 subjects 页面,理解为何映射是必要的。4.4.1.1. 显示谁有拜访权限为帮助用户治理其文件的权限,应用程序必须显示谁有权拜访文件,以及为什么。在本示例中,咱们假如应用程序晓得上面的文件和目录:├─ 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#_) 用户 maureen 当初想要管理文件 /photos/beach.jpg 的拜访权限。因而,应用程序应用开展 API 获取有权拜访该文件的每个人的树:// 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())

}
}
后果:
{
“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. 最大树深度 max-depth 参数对于将申请提早放弃在可承受的范畴内十分重要,但也形象出最根本的主体汇合(subject set)。在许多状况下,应用程序不心愿解析所有主体汇合,而是心愿显示,比方公司的每个人或管理员们有特定的关系(relation)。在本示例中,应用程序晓得它应用的关系元组(relation tuple)的粗略构造,因而能够确定 max-depth=3 足够显示所有相干关系:间接受权拜访(深度 1)通过所有权间接地授予拜访(深度 2)通过父的所有权间接地授予拜访(深度 3)4.4.1.3. 剖析该树该树不仅包含主体(subject)ID(在本例中为用户名),也包含它们被包含的起因。这对用户审计权限很有用。在许多状况下,应用程序不心愿列出全副主体 ID,而是形象出一些主体汇合。4.5. 筹备生产环境当自托管 Ory Keto 时,浏览该文档筹备生产环境。4.5.1. 数据库 Ory Keto 须要生产级数据库,比方 PostgreSQL、MySQL、CockroachDB。不要在生产环境中应用 SQLite。浏览对于 Ory 部署根底和需要的更多信息。4.5.2. API 网关前面的 Ory Keto API 只管 Ory Keto 围绕运行面向公网的生产 HTTP 服务器实现所有 Go 最佳实际,然而咱们不激励运行间接面向公网的 Ory Keto。咱们强烈推荐在 API 网关或负载平衡前面运行 Ory Keto。通常在边缘(网关 / 负载平衡)上终止 TLS,应用基础设施提供商(如 AWS CA)提供的证书保障最初一英里的平安。较好的实际是不向公共网络裸露写 API。读 API 也应受爱护,它可能透露裸露的信息(比方透露谁有权做某事)。4.5.3. 缩放(scaling)当自托管 Ory Keto 时,没有额定的缩放要求,只需启停另一个容器。4.6. 基于角色的访问控制(ACL)本指南将论述如何应用 Ory Keto 实现 RBAC。危险:以后实现 RBAC 是可行的,但须要一些变通方法。本指南启用对 Keto 的 RBAC 反对,但原生反对仍在进行中。请在该 issue 中跟进进度。Role Based Access Control (RBAC) 映射主体(subject)到角色(role),以及角色到权限(permission)。(H)RBAC 的指标是通过将主体按角色分组,以及调配权限给角色的形式,使权限治理更便捷。这种类型的访问控制在 Web 应用程序中很常见,比方常常会遇到诸如“管理员”、“主持人”等角色。In Hierarchical Role Based Access Control (HRBAC) 中,角色能够从其它角色继承权限。比方“管理员”角色能够从“主持人”角色继承所有权限,这有助于在定义权限时,缩小反复和治理复杂度。假如咱们正在构建一个报告程序,须要有三组具备不同拜访级别的用户。程序中有如下报告组:财务业绩报告市场业绩报告社区工作体现报告这次咱们应用 (H)RBAC 和角色 community、marketing、finance 和 admin 建模拜访权限:角色 admin 从 finance、marketing 和 community 继承所有权限。(H)RBAC 无处不在。如果你装置过论坛软件,如 phpBB 或 WordPress,你必定遇到过 ACL、(H)RBAC。(H)RBAC 能够升高治理复杂度,以及宏大的用户基数带来的开销。然而,有时甚至 (H)RBAC 是不够的。例如,须要示意所有权(比方 Dilan 只能批改他本人的报告)、领有属性(比方 Dilan 只须要在工作工夫拜访),或者在多租户环境中。长处:当多个身份共享类似权限时,升高治理复杂度角色层级可进一步缩小冗余公认,并且开发人员容易了解,因为它是 Web 应用程序的事实标准毛病:没有所有权的概念:Dan 是文章“Hello World”的作者,因而容许他更新该文章没有环境的概念:当申请来自 IP 10.0.0.3 时,容许 Dan 拜访账号服务没有租户的概念:容许 Dan 拜访“Dan 的测试”租户上的资源 4.6.1. 应用 Ory Keto 实现 RBAC 咱们须要有三个组 finance、marketing、community。咱们也须要有两个命名空间:用于治理访问控制的 reports 和用于将用户增加进组的 groups。首先将命名空间(namespace)增加到 Keto 配置。这里# …
namespaces:

  • id: 0
    name: groups
  • id: 1
    name: reports

… 咱们有两种类型的权限,假如咱们须要报告的 edit 和 view 权限。// 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) 假如在咱们的组织中有四个人。Lila 是 CFO,须要查看财务报告,Hadley 从事市场营销工作,Dilan 是一名社区管理员。Neel 是系统管理员,须要对报告具备编辑权限。groups:finance#member@Lila
groups:community#member@Dilan
groups:marketing#member@Hadley
groups:admin#member@Neel4.6.2. 创立关系元组咱们拷贝所有权限,创立具备如下内容的 policies.rts 文件。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 而后运行
keto relation-tuple parse policies.rts –format json | \
keto relation-tuple create – >/dev/null \
&& echo “Successfully created tuple” \
|| echo “Encountered error” 因为 Dilan 是一名社区管理员,所以上面的查看示例显示他只能拜访社区报告 keto check Dilan view reports finance
Denied
keto check Dilan view reports community
Allowed
keto check Dilan edit reports community
Denied 当初 Dilan 决定与市场营销单干。因而咱们须要更新他的权限,将他增加到市场营销组 groups:marketing#member@Dilan 当初他也能够拜访市场营销报告 keto check Dilan view reports marketing
Allowed4.6.3. 显示用户能够拜访的所有对象上面的示例向你展现如何获取 Dilan 能够拜访的对象列表# 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. 示例根底示例:Olymp 图书馆根底的、理论的全个性示例假如有一个名为“Olymp 图书馆”的文件共享应用程序。每个文件存储在键 - 值存储中,键是 UUIDv4(伪随机的惟一标识符),值是元数据和内容。应用程序应用 Ory Keto 追踪每个文件级别的所有权和授予的拜访权限。留神:本示例假设存在一个已定义关系(relation)owner 和 access 的命名空间(namespace)files。对象的每个所有者也能够拜访该对象。所有关系元组(relation tuple)都存储在该命名空间中。当初,由其惟一用户名标识的用户 demeter 想上传一个蕴含最肥沃的土壤的文件。文件被调配 UUID ec788a82-a12e-45a4-b906-3e69f78c94e4。应用程序通过写 API(write-API)向 Ory Keto 增加如下关系元组(relation tuple):ec788a82-a12e-45a4-b906-3e69f78c94e4#owner@demeter 为筹备与用户 athena 的重要会议,demeter 心愿与 athena 分享蕴含肥沃土地的文件,以便他们都能浏览该文件。因而,他关上“Olymp 图书馆”,列出他领有的所有文件。应用程序外部应用列表 API(list-API)申请所有者为 demeter 的所有对象(objects,文件 ID)。响应将蕴含对象 ec788a82-a12e-45a4-b906-3e69f78c94e4,应用程序将其映射到问题中的文件。而后,用户 demeter 申请应用程序与 athena 分享该文件,应用程序将该申请转换为向 Ory Keto 增加如下关系元组(relation tuple)的写 API 申请(write-API request):ec788a82-a12e-45a4-b906-3e69f78c94e4#access@athena 为确认操作胜利,应用程序应用 Ory Keto 的开展 API(expand-API)编制能够拜访该文件的所有人的列表:
// The following subject set is expanded by Keto
ec788a82-a12e-45a4-b906-3e69f78c94e4#access 开展 API 将返回开展树∪ ec788a82-a12e-45a4-b906-3e69f78c94e4#access
├─ ∪ ec788a82-a12e-45a4-b906-3e69f78c94e4#owner
│ ├─ ☘ demeter
├─ ☘ athena 而后“Olymp 图书馆”向 demeter 显示该信息。当 athena 想获取蕴含肥沃土壤的文件时,应用程序在返回文件前,应用查看 API(check-API)来验证 athena 有拜访该文件的权限。通过删除相应的关系元组的形式,容许 demeter 随时撤销 athena 的拜访权限。6. 本地设置和配置 Keto6.1. 环境阐明操作系统:Ubuntu 18.04.6 LTSGo:go version go1.18.8 linux/amd646.2. 装置 ketogit 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 将 GOPATH 增加到 PATH 中:export PATH=$PATH:$(go env GOPATH)/bin6.3. 创立配置文件 keto.yamlversion: 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 对于 Keto 配置文件的具体配置,请参考:https://www.ory.sh/docs/keto/reference/configuration 对于生产环境部署的细节,请参考:https://www.ory.sh/docs/ecosystem/deployment6.4. 启动 Ketoketo serve -c keto.yaml6.5. 应用 RBAC 章节中的用例进行测试参考文档 https://blog.csdn.net/qq_45874107/article/details/119839187https://www.ory.sh/docs/keto

正文完
 0