ABAC - 復(fù)雜場景下訪問控制解決之道

引言

引言

在一個(gè)典型的軟件開發(fā)場景中,你作為一名開發(fā)人員加入到某個(gè)項(xiàng)目后,假設(shè)是“超人組”,你往往需要訪問這個(gè)項(xiàng)目的代碼庫然后才能開始工作。當(dāng)你的 Team Lead 將你加入 Git Organization 后,你自然可以訪問到“超人組”的代碼倉庫,然后就可以愉快的進(jìn)行開發(fā)工作了。但是,當(dāng)你的任務(wù)完成后,可能你需要參與另一個(gè)項(xiàng)目,你自然就沒有權(quán)利去訪問“超人組”的代碼庫,所以你的 TL 會(huì)將你移出。這是一個(gè)典型的訪問控制場景,我們所控制的對象是工程師,資源則是代碼倉庫。

對于軟件工程師來說,類似的場景十分常見,可以說任何一個(gè)系統(tǒng)都存在訪問控制機(jī)制,從操作系統(tǒng)到復(fù)雜的云上應(yīng)用,我們也發(fā)明了很多名詞、技術(shù)來實(shí)現(xiàn)類似的功能,但是核心都是為了控制人或者其他對象,能否訪問資源。

Access Control Mechanism (ACM): The logical component that serves to receive the access request from the subject, to decide, and to enforce the access decision.

RBAC 的缺憾

對于訪問控制模型,大家最熟悉、或者實(shí)現(xiàn)最多的就是 RBAC Role Based Access Control,我們通過賦予不同 role 的不同權(quán)限來進(jìn)行訪問控制。對于一個(gè)主體(往往是組織內(nèi)的人員或者某個(gè)客戶端),他可以擁有多個(gè) role 以應(yīng)對多種不同的操作權(quán)限。RBAC 的流行很重要很大程度上是貼近現(xiàn)實(shí)生活,方便大家理解與使用,例如老王是銷售經(jīng)理,同時(shí)也是技術(shù)委員會(huì)的成員,我們很自然就給他兩個(gè) role:Sales Manager 與 Technology Group Member,而這兩個(gè) role 對應(yīng)的權(quán)限也很清晰明確,Sales Manager 可以查看所有的銷售數(shù)據(jù),并進(jìn)行修改等,而 Technology Group Member 只能查看技術(shù)上的文獻(xiàn),不論是在系統(tǒng)設(shè)計(jì)還是在運(yùn)營時(shí),這些名詞都與我們的 title 相對應(yīng),對于管理人員來說,只是修改不同的 role 對應(yīng)的權(quán)限而已。 當(dāng)老王專心去做技術(shù)研究之后,我們就移除他的 Sales Manager Role,這樣他就無法訪問銷售上的數(shù)據(jù)了。

老王失去了 Sales Manager 的 role 后,就無法繼續(xù)訪問銷售數(shù)據(jù)了

RBAC 在很多時(shí)候是管用的,比如我們的系統(tǒng)是面向銷售公司或者學(xué)校這種組織架構(gòu)很嚴(yán)整的地方,但是在復(fù)雜場景下,RBAC 漸漸就不夠用了,它會(huì)產(chǎn)生很多虛無的 role 而且在管理和控制上更難:在某個(gè)醫(yī)療機(jī)構(gòu)中,我們想要控制一個(gè)科室內(nèi),護(hù)士只能訪問自己所負(fù)責(zé)的病人資料時(shí),我們就無法直接使用 nurse 這個(gè) role,我們需要更細(xì)粒度的 role 去劃分病人老張還是老王,這就會(huì)產(chǎn)生和現(xiàn)實(shí)不對應(yīng)的 role,例如:老張的護(hù)士,老王的護(hù)士。在醫(yī)院這種病人流動(dòng)性很大的場景下,頻繁的創(chuàng)建和銷毀 role 是很容易出問題,我們的確要求很頻繁,但是與現(xiàn)實(shí)不 match 的虛無的 role 很難管理。

另一種情況是,如果管理者考慮醫(yī)療數(shù)據(jù)的安全性與隱私性,不希望護(hù)士在離開醫(yī)院后能夠訪問到病人資料,我們會(huì)更加難辦,常見的策略要么是在底層網(wǎng)絡(luò)層進(jìn)行處理,直接禁止在院外的一切訪問,但是很多企業(yè)的需求往往是,使用 VPN 我依舊可以訪問內(nèi)部的資源,但是我還是希望基于所在地進(jìn)行精確的控制,比如看郵件是可以的,但是看財(cái)務(wù)數(shù)據(jù)是不行的。在 RBAC 下,我們也可以通過虛擬的 role 來控制,比如下班后給與其 Out of Office 的 role,然后給與這個(gè) role 最小的權(quán)限,這自然又需要虛擬的 role 與大量的動(dòng)態(tài)控制。

給在辦公室外的同事創(chuàng)建了與職位不對稱的 role

一般來說,在 RBAC 中濫用 role 所帶來的問題被稱為 “role explosion”,跟“曹操”與“曹操小時(shí)候”這個(gè)笑話很類似,但的確我們的訪問控制系統(tǒng)中存在很多這樣的 role。

ABAC

介紹

所以,直覺上來說我們需要更多的“東西”來進(jìn)行更精細(xì)的訪問控制,用來匹配我們復(fù)雜的業(yè)務(wù)場景,同時(shí),我們也希望這個(gè)新的模型易于理解和實(shí)現(xiàn),也利于控制與運(yùn)維,這就是 ABAC —— 基于屬性的訪問控制 (Attribute Based Access Control) —— 想要解決的問題。簡單來說,對于 ABAC 我們判斷一個(gè)用戶是否能訪問某項(xiàng)資源,是對其很多不同屬性的計(jì)算而得到的。

傳統(tǒng)的 RBAC 與 ACL 等訪問控制機(jī)制中,可以認(rèn)為是 ABAC 的子集,對于 RBAC,只是我們的訪問機(jī)制的實(shí)現(xiàn)只是基于屬性 role 而已,ACL 則是基于屬性是 identity 的 AC。

術(shù)語

要理解 ABAC 首先需要從一些領(lǐng)域內(nèi)的術(shù)語說起,按照我個(gè)人的習(xí)慣,對于專業(yè)性的術(shù)語一向是不翻譯的,因?yàn)榈拇_是受夠了每次討論授權(quán)、認(rèn)證、驗(yàn)權(quán)、驗(yàn)證等區(qū)別,雖然技術(shù)討論時(shí)彼此都理解要說的是什么,但是在場景中這是需要獨(dú)一無二的、易于理解的名字的(此處插入 DDD 的通用語言),此外還有一個(gè)好處就是好寫代碼,正確的名字可以幫助你的代碼易于理解和維護(hù)。

Attribute:屬性,用于表示 subject、object 或者 environment conditions 的特點(diǎn),attribute 使用 key-value 的形式來存儲(chǔ)這些信息,比如我在公司的 role 是 developer,role 是 key,developer 是 value,而我的小組昵稱袋熊,key 是 team,value 是 wombat。

Subject:常常指代使用系統(tǒng)的人或者其他使用者(non-person entity,NPE),比如說客戶端程序,訪問 API 的 client 或者移動(dòng)設(shè)備等等。當(dāng)然一個(gè) subject 可以有多個(gè)的 attributes,就像用戶屬性這些我們曾經(jīng)用過的名詞一樣。

Object:指代我們這個(gè) ACM 需要管理的資源,比如文件,比如某項(xiàng)記錄,比如某臺(tái)機(jī)器或者某個(gè)網(wǎng)站,任何你需要進(jìn)行訪問控制的資源都可以稱為 object,同樣 object 也可以有多項(xiàng)屬性,比如袋熊組的桌子,或者洛克組的線上實(shí)例,我們也常常使用 resource 來描述這些資源,但是在 ABAC 的環(huán)境下,我們稱為 object。

Operation:有了 object 有了 subject,自然就有了 subject 需要做的事情,比如查看某條記錄,登錄某臺(tái)服務(wù)器,使用某個(gè) SaaS 服務(wù)進(jìn)行報(bào)銷或者查看候選人的作業(yè)。往往包括我們常說的讀、寫、修改、拷貝等等,一般 operation 是會(huì)表達(dá)在 request 中的,比如 HTTP method。

Policy:通過 subject、object 的 attribute 與 environment conditions 一起來判斷 subject 的請求是否能夠允許的關(guān)系表示,比如說:policy 可以用人類語言這樣表達(dá),只有袋熊組的人才能訪問這幾臺(tái)服務(wù)器,或者只有在辦公室才能訪問這些資源,但對于機(jī)器來說,無非就是一個(gè)判斷語句罷了。當(dāng)然了,policy 可以是一堆這樣 boolean 邏輯判斷的組合,比如只有公司的正式員工、并且在公司的六樓區(qū)域的網(wǎng)絡(luò)中,才能訪問某個(gè)服務(wù)。你可以使用 Specification Pattern 來實(shí)現(xiàn) policy,其實(shí)沒那么復(fù)雜。

Environment Conditions:表示目前進(jìn)行的訪問請求發(fā)生時(shí),的操作或情境的上下文。Environment conditions 常常用來描述環(huán)境特征,是獨(dú)立于 subject 與 object 的,常用來描述系統(tǒng)的情況:比如時(shí)間,當(dāng)前的安全等級(jí),生產(chǎn)環(huán)境還是測試環(huán)境等等。

基本場景與概念

一個(gè)典型的 ABAC 場景描述如下圖,當(dāng) subject 需要去讀取某一條記錄時(shí),我們的訪問控制機(jī)制在請求發(fā)起后遍開始運(yùn)作,該機(jī)制需要計(jì)算,來自 policy 中記錄的規(guī)則,subject 的 attribute,object 的 attribute 以及 environment conditions,而最后會(huì)產(chǎn)生一個(gè)是否允許讀取的結(jié)果。

From NIST 800-162: Basic ABAC Scenario
  1. 嘗試訪問
  2. ACM 進(jìn)行計(jì)算:subject attributes + object attributes + environment conditions = allow or deny?
  3. 進(jìn)行訪問

在 NIST 的描述中,我們對 ACM 內(nèi)部進(jìn)行進(jìn)一步的抽象,可以得出這兩個(gè)核心模塊:Policy Decision Point (PDP) 與 Policy Enforcement Point (PEP),如下圖:

PDP + PEP

所以,實(shí)現(xiàn) ABAC 的核心機(jī)制是在請求發(fā)起后,subject attributes、object attributes 與 environment conditions 作為輸入,PDP 根據(jù) PEP 的數(shù)據(jù)去獲取 policy 與環(huán)境條件,再進(jìn)行計(jì)算,最后確定是否有權(quán)進(jìn)行請求。ABAC 的邏輯并不復(fù)雜,根據(jù)之前我們所畫的基本場景與機(jī)制的圖中,你可以很輕松的開始進(jìn)行架構(gòu)設(shè)計(jì),往往最開始你需要定義出 subject、object 以及其相關(guān)的 attribute,同時(shí)你也需要思考,當(dāng)去進(jìn)行 object 訪問時(shí),你該如何表達(dá) request 以及 operation。

From NIST 800-162: An Example of ACM Functional Points

RESTful 是我們常用的設(shè)計(jì)風(fēng)格,RESTful 的流行是與 HTTP 協(xié)議密不可分的,其中我們很看重 HTTP 協(xié)議中的 methods,并且賦予了這些 methods 易于理解的語義,我們會(huì)很自然的認(rèn)為 GET 是獲取資源,而 POST 是創(chuàng)建新的資源,PUT 則是修改,使用這些 methods 是與控制資源聯(lián)系在一起。但是,在 HTTP 協(xié)議中,并沒有規(guī)定 GET 是否可以進(jìn)行資源上的修改和更新,因?yàn)檫@只是個(gè)傳輸協(xié)議罷了,是我們在這個(gè)協(xié)議之上發(fā)明了新的東西,所以也沒有“官方的、標(biāo)準(zhǔn)的” RESTful。之所以在這里提到 RESTful 與 HTTP 的關(guān)系,是想讓大家理解在進(jìn)行 ABAC 系統(tǒng)設(shè)計(jì)時(shí),operation 是可以有很多種表達(dá)的,而重要的是定義這些 operation 與 request 的關(guān)系,你可以使用 SOAP 或者其他協(xié)議,或者在 RESTful 之上自己發(fā)明一些字段,或者加入進(jìn) HTTP header,但是一定需要有清楚的 operation 描述。

為什么 ABAC 能解決復(fù)雜場景下的問題

在學(xué)習(xí) ABAC 的過程中我發(fā)現(xiàn),ABAC 和很多創(chuàng)新一樣,并不是因?yàn)榭萍嫉耐黄菩赃M(jìn)展,而只是在 RBAC 的思維上前進(jìn)了一點(diǎn),理解 ABAC 的術(shù)語時(shí),你能很快的聯(lián)想到已有的技術(shù)實(shí)踐,比如 AWS IAM。而且,這些術(shù)語也如同我們做面向?qū)ο缶幊虝r(shí),是很好的描述現(xiàn)實(shí)的。

Attribute 易于管理

我們可以很容易的為不同的用戶設(shè)計(jì) attribute,往往在很多企業(yè)的實(shí)現(xiàn)中存在一個(gè) consumer profile 或者 user details 的服務(wù),這些服務(wù)中很多字段比如職位、職級(jí)、辦公室、項(xiàng)目等就是天然的 attribute,對于需要管理的 object,如果是一臺(tái)虛擬機(jī),那么 IP 地址、歸屬組織、cost code 等都可以是 attribute,而且因?yàn)?attribute 是 K-V 式的,往往一張一對多的表就可以控制好 subject、object 與 attribute 的對應(yīng)。

細(xì)粒度授權(quán)支持

ABAC 能做到細(xì)粒度的授權(quán)管理,我們知道,在 policy 中,我們的準(zhǔn)許訪問的判斷是可以寫的很靈活的,我們甚至可以判斷請求中的某個(gè)屬性是否滿足于一個(gè)正則表達(dá)式,或者字符串相等(這個(gè)很常見,特別是在使用 AWS IAM 做最小權(quán)限原則時(shí)),我們也可以使用邏輯與、邏輯或的關(guān)系自由組合很多不同的訪問規(guī)則。你可以使用之前提到的 Specification Pattern 很輕松的實(shí)現(xiàn)靈活的 policy,解析 JSON 或者 XML 去動(dòng)態(tài)的創(chuàng)建規(guī)則,而這些含有規(guī)則的 JSON 或 XML,則是可以被編程實(shí)現(xiàn)的(可編程的 policy 是動(dòng)態(tài)的授權(quán)驗(yàn)權(quán)的前提)。你的 policy 甚至可以做到,只有姓張的工程師在某個(gè)項(xiàng)目時(shí)才能訪問某個(gè)資源,在 RBAC 的時(shí)代,這是很難的。

訪問控制管理成本很低

ABAC 對系統(tǒng)管理員是友好的,在 RBAC 的時(shí)代,如果我需要實(shí)現(xiàn)細(xì)粒度的資源管理或者經(jīng)常 subject 與 object 的對應(yīng)關(guān)系經(jīng)常變動(dòng),那么管理員難以操作的,也很容易出現(xiàn)問題,其中常常被采用的解決方案就是創(chuàng)建那些本不應(yīng)該存在的 role。但是在 ABAC 時(shí)代,管理員的管理對象會(huì)縮減到 policy,也就是只處理訪問控制。我們再回到醫(yī)療機(jī)構(gòu)的那個(gè)例子中,如果某個(gè)護(hù)士負(fù)責(zé)照顧老張,系統(tǒng)管理員只需要新建一個(gè) policy 并寫上允許訪問即可,當(dāng)老張出院后,只需要?jiǎng)h除或者失效這個(gè) policy 就可以了。在 RBAC 的環(huán)境中,你可能需要為某個(gè)虛擬的 role 動(dòng)態(tài)的添加 permission,而 permission 如果到了針對單個(gè)病人的情況下,是絕對多如牛毛的,特別是有兩個(gè)叫做老張的病人時(shí)。

往往,我們會(huì)使用 JSON 或者 XML 定義這個(gè) policy,那么,這一切都可以完全自動(dòng)化,而不需要使用管理員點(diǎn)擊。再現(xiàn)實(shí)一些的話,我們可以完全實(shí)現(xiàn)一個(gè)審批的流程,如果你使用過 Google Drive,你會(huì)對這個(gè)請求訪問的過程絕不陌生。

Require Access

動(dòng)態(tài)的總體控制

Environment conditions 也能夠提供統(tǒng)一的系統(tǒng)級(jí)別的控制,比如威脅等級(jí)或者按照區(qū)域劃分安全級(jí)別,不同的區(qū)域使用 ABAC 時(shí),可能環(huán)境上會(huì)有變化。例如我們常用紅區(qū)來表示最高安全級(jí)別,那么我們默認(rèn)就需要 deny 所有請求,并且會(huì)觸發(fā)警報(bào)等等,但是在綠區(qū)這種辦公區(qū)域,可能默認(rèn)所有的請求都是被允許的等等。Environment conditions 可以提供“拉閘”這樣的功能,而且它也是可以動(dòng)態(tài)調(diào)整的。

ABAC 在落地上的一些經(jīng)驗(yàn)和故事

AWS IAM

如果誰能作為 ABAC 比較好的實(shí)現(xiàn)榜樣的話,我第一個(gè)想起的就是 AWS IAM 的實(shí)現(xiàn)。如果當(dāng)你的企業(yè)正在使用公有云時(shí),對公有云的資源進(jìn)行控制是非常難以管理的,你當(dāng)然可以為每個(gè)小組安排好虛擬機(jī)或者 RDS 之類的,但是這太靜態(tài)了,而且也不足以細(xì)粒度。比如,當(dāng)我們想實(shí)現(xiàn)最小權(quán)限原則時(shí)就很難辦到(例如你的數(shù)據(jù)庫只想被你確定的幾臺(tái)實(shí)例所訪問到),往往這種需求會(huì)實(shí)現(xiàn)為,在某個(gè)網(wǎng)段內(nèi),大家都可以訪問到某個(gè)數(shù)據(jù)庫或者中間件,那自然是不夠理想的。

公有云的資源是租用的,你可以按照自己的需求動(dòng)態(tài)的擴(kuò)容或者降低你的資源,那么這種場景下,資源是動(dòng)態(tài)的,而且變化很大(可能會(huì)根據(jù)流量動(dòng)態(tài)的啟動(dòng)實(shí)例或者關(guān)閉),那在這種情況下如何做到訪問控制與最小權(quán)限原則,那你就不能再基于 users 與 roles 進(jìn)行操作,這時(shí)候你就需要 ABAC。好消息是,AWS 作為云計(jì)算的領(lǐng)導(dǎo)者,很早就實(shí)現(xiàn)了類似的功能,而使用 IAM 則是 operations 的必修課。

請參考這個(gè)視頻,來自 AWS Senior Manager,個(gè)人認(rèn)為是講的最好的 IAM 與 ABAC 介紹。

一些實(shí)踐經(jīng)驗(yàn)

最開始實(shí)踐 ABAC 是因?yàn)槲覀冊谶M(jìn)行一個(gè)內(nèi)部云的資源控制項(xiàng)目,在設(shè)計(jì)時(shí)我們參考了 AWS 的玩法,并進(jìn)行了類似的設(shè)計(jì)。實(shí)際上 ABAC 是與你要管理的資源無關(guān)的,更像是一種模式,在云資源控制中大多數(shù) subject 不是用戶或者真正的人,而是客戶端、實(shí)例機(jī)器等。實(shí)現(xiàn)一個(gè)類似 policy 的策略管理并不是很難,主要的工作在管理端的開發(fā)以及為客戶端提供 SDK 上了,此外還有集成策略。我們也考慮過 XACML & NGAC (Next Generation Access Control) 去描述 policy 或者直接使用,但 XACML 過于復(fù)雜以及并不成熟,最后還是采取了自研的策略。故事這里是很多的,但是篇幅有限不予展開。

總結(jié)

ABAC 在概念上的設(shè)計(jì)的確是有先進(jìn)性的,對于有 RBAC 知識(shí)的人,ABAC 不難理解,也就是“基于用戶屬性進(jìn)行訪問權(quán)限判斷”,但是當(dāng)我去閱讀 NIST 的文章或者參考 XACML 實(shí)現(xiàn)時(shí),卻擔(dān)心 ABAC 的復(fù)雜實(shí)現(xiàn),畢竟 NIST 給與的企業(yè)級(jí)實(shí)現(xiàn)考慮的長度占文章的一半。對于 ABAC 的概念,這并不是復(fù)雜度的來源,而是授權(quán)這件事本身的復(fù)雜性,對于系統(tǒng)的設(shè)計(jì)者與管理者來說,一旦需要關(guān)注細(xì)粒度的授權(quán)管理,那么復(fù)雜是無法避免的。

微服務(wù)的流行與 ABAC 的配合值得寫另一篇文章,特別是分布式身份驗(yàn)證之后,怎么做到分布式的授權(quán)與驗(yàn)權(quán),怎么實(shí)現(xiàn) PEP、PDP 等 ABAC 提倡的模塊設(shè)計(jì),這些東西可否做成應(yīng)用程序透明的方式,可否與 security sidecar 集成等等,這些都是可以進(jìn)一步完善的。

業(yè)務(wù)人員希望有一種業(yè)務(wù)語言能夠描述授權(quán)策略,但是 gap 在于技術(shù)人員無法理解與實(shí)現(xiàn),對于 ABAC 這種授權(quán)模式中,我們需要的是一位能夠同時(shí)說業(yè)務(wù)與技術(shù)兩種語言的人,將真正的業(yè)務(wù)需要轉(zhuǎn)為技術(shù)語言,從而指導(dǎo)落地。

參考文獻(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Docker 小棧-【docker ps】 2019-08-13 8:00:00 今天來講用的最多的docker命...
    siguadantang閱讀 1,017評論 0 0
  • 人活在世上,就是跟時(shí)間的較量,精彩不精彩,全憑自己決定,你所走過的路,做過的選擇,是好是壞,時(shí)間會(huì)給你答案。今天過...
    羅沫沫66閱讀 717評論 0 1

友情鏈接更多精彩內(nèi)容