Zadig 基于 OPA 實(shí)現(xiàn) RBAC 和 ABAC 權(quán)限管理技術(shù)方案詳解
隨著 Zadig 被越來越多企業(yè)用戶和社區(qū)小伙伴采用,大家對(duì)企業(yè)級(jí)權(quán)限和安全性有更高的訴求,亟待一套權(quán)限管理方案。經(jīng)過充分調(diào)研,我們最終確定了采用 OPA(開放策略代理)開源策略引擎,事實(shí)上,它已經(jīng)被 Netflix,Pinterest 和 Goldman Sachs 等公司用于生產(chǎn),正在成為云原生策略管理的事實(shí)標(biāo)準(zhǔn)。但 OPA 的編寫具有一定的復(fù)雜度,網(wǎng)上的教程和官方文檔也僅僅停留在 Demo 層面。經(jīng)過 Zadig 從 v1.9.0 到 v1.10.0 的迭代,我們已完整實(shí)現(xiàn)了 RBAC 和 ABAC 權(quán)限管理業(yè)務(wù)和技術(shù)方案的落地,這里我們將整套方案的技術(shù)細(xì)節(jié)分享給大家。
背景介紹
OPA
開放策略代理(Open Policy Agent,發(fā)音為“ oh-pa”)是一個(gè)開放源碼的通用策略引擎,它統(tǒng)一了跨技術(shù)棧的策略實(shí)施。OPA 提供了一種高級(jí)聲明性語言 rego,允許您將策略指定為代碼和簡(jiǎn)單的 API,以加載軟件中的策略決策。您可以使用 OPA 在 Microservices、 Kubernetes、 CI/CD 管道、 API 網(wǎng)關(guān)等中強(qiáng)制執(zhí)行策略
圖片來源:opa 官方
權(quán)限模型
RBAC:
基于角色的訪問控制模型(RBAC: Role-based Access Control),顧名思義,給用戶定義角色,通過角色來控制權(quán)限。目前來說基于角色的訪問控制模型是應(yīng)用較廣的一個(gè),特別是 2B 方向 SAAS 領(lǐng)域,應(yīng)用尤其常見。
如上圖示,用戶擁有角色,且可擁有多個(gè)角色,而每個(gè)角色對(duì)應(yīng)不同權(quán)限。這樣的好處是:不必為每一個(gè)用戶去配置權(quán)限,擁有極大的靈活性和便利性。
ABAC:
基于屬性的訪問控制模型(ABAC: Attribute-Based Access Control),被一些人稱為是權(quán)限系統(tǒng)設(shè)計(jì)的未來,不同于常見的將用戶通過某種方式關(guān)聯(lián)到權(quán)限的方式,ABAC 則是通過動(dòng)態(tài)計(jì)算一個(gè)或一組屬性是否滿足某種條件來進(jìn)行授權(quán)判斷(可以編寫簡(jiǎn)單的邏輯)。屬性通常來說分為四類:用戶屬性(如用戶年齡),環(huán)境屬性(如當(dāng)前時(shí)間),操作屬性(如讀?。┖蛯?duì)象屬性(如一篇文章,又稱資源屬性),所以理論上能夠?qū)崿F(xiàn)非常靈活的權(quán)限控制,幾乎能滿足所有類型的需求。Zadig 目前主要是通過標(biāo)簽?zāi)M屬性來實(shí)現(xiàn)細(xì)粒度資源權(quán)限控制。
圖片來源:阿里云幫助文檔
Zadig 權(quán)限場(chǎng)景
- 系統(tǒng)級(jí)別角色-解決全系統(tǒng)級(jí)別的權(quán)限問題(RBAC)
管理員:擁有全系統(tǒng)的所有權(quán)限
普通用戶:擁有公開項(xiàng)目以及其所有資源的查看權(quán)限、測(cè)試管理和數(shù)據(jù)分析的查看權(quán)限
- 項(xiàng)目級(jí)別角色-解決項(xiàng)目級(jí)別的權(quán)限問題(RBAC)
project-admin:擁有該項(xiàng)目下的所有權(quán)限
read-only:擁有該項(xiàng)目下的所有資源的查看權(quán)限
read-project-only(默認(rèn)):擁有該項(xiàng)目下工作流和集成環(huán)境list的權(quán)限(但資源會(huì)被精細(xì)化管理),服務(wù)、構(gòu)建和測(cè)試資源的所有查看權(quán)限
自定義角色:自定義每個(gè)模塊權(quán)限能力
- 項(xiàng)目級(jí)別策略:解決項(xiàng)目級(jí)別資源的精細(xì)化管理(ABAC)
因此 Zadig 基于 OPA 實(shí)現(xiàn) RBAC 解決了系統(tǒng)和項(xiàng)目通用的權(quán)限管理,實(shí)現(xiàn) ABAC 解決了項(xiàng)目級(jí)別資源的精細(xì)化管理。
Zadig 權(quán)限架構(gòu)設(shè)計(jì)
權(quán)限設(shè)計(jì)架構(gòu)圖
Gloo 作為 Zadig 的網(wǎng)關(guān),是 Zadig 所有流量的入口。通過集成 OPA 后,所有經(jīng)過網(wǎng)關(guān)的流量都會(huì)由 OPA 來統(tǒng)一進(jìn)行認(rèn)證鑒權(quán),而只有認(rèn)證鑒權(quán)通過后才會(huì)準(zhǔn)許訪問后端服務(wù)(aslan)。并且 OPA 決策依賴的數(shù)據(jù)會(huì)異步定時(shí)去權(quán)限管理服務(wù)(policy)和后端服務(wù)(aslan)采集決策所需要的權(quán)限和資源數(shù)據(jù),從而實(shí)現(xiàn)高性能決策。
Zadig 權(quán)限數(shù)據(jù)庫模型
zadig-policy 數(shù)據(jù)庫中的相關(guān)數(shù)據(jù)模型
role:
用戶角色定義表,用來定義某項(xiàng)目下角色,下面的一條記錄表示在項(xiàng)目「zadig」下有一個(gè)「dev」角色,該角色擁有查看工作流和執(zhí)行工作流的權(quán)限。
rolebinding:
用戶角色綁定表,用來將角色綁定到用戶身上,下面的一條記錄表示將「zadig」項(xiàng)目下的「dev」角色綁定給 uid 為「71b8aa87-a10b-11ec-af4e-fa012450189e」的用戶
policy_meta:
權(quán)限元信息表,用來將業(yè)務(wù)語意的權(quán)限轉(zhuǎn)換為對(duì)應(yīng) 【endpoint+action】,在提供給 opa 的bundle 數(shù)據(jù)里角色下面的權(quán)限會(huì)被轉(zhuǎn)換成一組 url 的集合,具體轉(zhuǎn)換后的內(nèi)容可以看決策數(shù)據(jù)中的 roles
policy:
用戶策略定義表,用來定義某項(xiàng)目下策略,下面的一條記錄表示在項(xiàng)目「zadig」下有一個(gè)「zadig-dev-system-zhangsan」策略
policy 和 role 表基本一致,主要區(qū)別是 policy 表多了一個(gè) match_attributes 字段,這里表示對(duì)于項(xiàng)目「zadig」下打上label為【key = policy,value = zadig-dev-system-zhangsan-Workflow-zadig-workflow-dev】的workflow有擁有查看工作流和執(zhí)行工作流的權(quán)限
policybinding:
用戶策略綁定表,用來將策略綁定到用戶身上,下面的一條記錄表示將「zadig」項(xiàng)目下的「zadig-dev-system-zhangsan」策略綁定給uid為「4fd92962-a4f6-11ec-af4e-fa012450189e」的用戶
Zadig 數(shù)據(jù)庫中的相關(guān)數(shù)據(jù)模型
label:
標(biāo)簽表,標(biāo)簽會(huì)同時(shí)打在權(quán)限 rule 規(guī)則和資源上,即表示權(quán)限對(duì)此標(biāo)簽的資源有相關(guān)權(quán)限
labelbinding:
標(biāo)簽資源關(guān)聯(lián)表,記錄標(biāo)簽和資源的綁定關(guān)系
RBAC 的實(shí)現(xiàn)
決策數(shù)據(jù)
決策數(shù)據(jù)指的是提供給 OPA 用來執(zhí)行決策的元數(shù)據(jù)集,它包括權(quán)限數(shù)據(jù)和資源數(shù)據(jù),主要來自于權(quán)限管理服務(wù)(policy)和后端服務(wù)(aslan),在 OPA 術(shù)語中叫做 bundle,OPA 會(huì)將 bundle 緩存,提高決策效率,以下為決策數(shù)據(jù)目錄結(jié)構(gòu)。
roles:
角色數(shù)據(jù),數(shù)據(jù)來自上述 role 和 policy_meta 表,采集時(shí)會(huì)將其拼裝,因此此處的 rules 是最終拼裝的結(jié)果
bindings: role_bindings:
角色綁定數(shù)據(jù),數(shù)據(jù)主要來自于上述 rolebinding 表
resources:
資源數(shù)據(jù),Zadig 目前提供項(xiàng)目下細(xì)粒度資源的權(quán)限控制,所以需要采集工作流和環(huán)境相關(guān)資源
Workflow:工作流采集數(shù)據(jù),原始數(shù)據(jù)存儲(chǔ)在后端服務(wù)(aslan)
Environment:采集數(shù)據(jù),原始數(shù)據(jù)存儲(chǔ)在后端服務(wù)(aslan)
exemptions:
特殊 url 采集
Public: zadig 公開的 urls,所有用戶(包括未登錄用戶都能訪問)
Privileged: zaidg 特權(quán) urls,只有系統(tǒng) admin 用戶能訪問
Registered: zadig 所有注冊(cè)的 urls,沒有注冊(cè)的 urls 默認(rèn)登錄用戶就能訪問
OPA 實(shí)現(xiàn)
鑒權(quán)流程:
- 校驗(yàn) url 是否無注冊(cè),如果是無注冊(cè),則返回通過
- 用戶是否是 admin,如果是,則返回通過
- 請(qǐng)求是否滿足,url 不是特權(quán) url,并且用戶為該項(xiàng)目的項(xiàng)目管理員,如果是則返回通過
- 請(qǐng)求是否滿足,url 不是特權(quán) url,并且請(qǐng)求匹配該用戶綁定的角色的權(quán)限,如果是則返回通過(權(quán)限不帶標(biāo)簽,即 rule 中不帶有 matchAttributes
關(guān)鍵代碼(rego):
ABAC 的實(shí)現(xiàn)
決策數(shù)據(jù)
決策數(shù)據(jù)解釋同 RBAC 決策數(shù)據(jù)。
bindings : policy_bindings:
策略綁定數(shù)據(jù),數(shù)據(jù)來自上述 policybinding 表。
policies:
策略數(shù)據(jù),數(shù)據(jù)來自上述 policy 表,相比較于 roles,他的 rule 的 matchAttributes 中會(huì)帶有標(biāo)簽,會(huì)對(duì)相匹配的資源進(jìn)行過濾。
resources:
相比于 rbac 的 resource 采集,這里的資源 spec 中會(huì)帶上 label,用來做細(xì)粒度資源匹配。
OPA 實(shí)現(xiàn)
鑒權(quán)流程:
- 單個(gè)資源請(qǐng)求匹配,請(qǐng)求是否滿足 url 不是特權(quán) url,該用戶綁定的策略權(quán)限規(guī)則匹配該請(qǐng)求,并且該權(quán)限的標(biāo)簽匹配用戶請(qǐng)求資源的標(biāo)簽,如果是則返回通過(權(quán)限帶標(biāo)簽,即 rule 中帶 matchAttributes)
- 如果上述都不滿足,會(huì)進(jìn)行多資源請(qǐng)求匹配,該用戶綁定的策略權(quán)限規(guī)則匹配該請(qǐng)求,如果是則會(huì)對(duì)匹配的資源進(jìn)行過濾(權(quán)限帶標(biāo)簽,即 rule 中帶matchAttributes)
- 如果所有都不滿足,則返回鑒權(quán)失敗
關(guān)鍵代碼(rego):
以上實(shí)現(xiàn)可以參考 Zadig 源碼位置:
pkg/microservice/policy/core/service/bundle/rego/authz.rego
展望
上面我們?cè)斀饬?Zadig 基于 OPA 的權(quán)限架構(gòu)設(shè)計(jì)、數(shù)據(jù)庫模型實(shí)現(xiàn)以及 RBAC、ABAC 的實(shí)現(xiàn),希望能給大家?guī)硭伎己蛶椭?。有了這樣一套權(quán)限管理方案還可以實(shí)現(xiàn)更多實(shí)用的功能,比如接下來的版本中,將提供根據(jù)項(xiàng)目細(xì)粒度權(quán)限控制來隱藏和關(guān)閉前端按鈕、系統(tǒng)角色權(quán)限管理和組管理能力及服務(wù)粒度的權(quán)限控制等等。
官網(wǎng):https://koderover.com/
github: https://github.com/koderover/zadig