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