跳到內容

授權——誰能做什麼,以及你如何證明

Control Center 回答兩個授權問題,而它們確實截然不同。**「這個人是否可 呼叫這項操作?」談的是人、角色與儲存庫。「這個代理是否可造成這個 效果?」**談的是動作、引數與影響範圍——那個問題屬於 護欄。

本頁談的是第一個問題,以及兩者共同留下的紀錄。

每一項與人有關的授權決策,都透過單一函式得出結果:

can(principal, permission, resource) → allow | deny + why

一項權限的形式是 <domain>:<tier>——tickets:write、 members:administer、repos:read。這份目錄是衍生而來,而非人工 撰寫:它由操作本身計算得出(操作名稱的前綴決定領域,它原本就強制的 角色下限決定層級),因此全部約 550 項操作都帶有權限,無需任何人逐一 手打。

這項衍生正是值得保護的特性。它意味著新增的操作預設就會受到管制—— 手動標註模型的失效模式,就是有人忘了標,而他忘掉的正是那道關卡。 一項棘輪測試會固定住衍生出的領域集合,因此在新前綴下新增操作,會是 人為做出的命名決定,而不是一場意外。

這四個層級恰好對應內建角色:

層級 角色下限 範例
read 訪客 tickets:read
write 成員 tickets:write
administer 管理員 members:administer
own 擁有者 workspace:own

五個內建角色——擁有者、管理員、成員、檢視者、訪客——是這份目錄上 的預設組合。每個工作區只有一個擁有權席次,必須透過轉移擁有權明確 移交(離開的擁有者否則無法移除:SCIM 取消佈建會拒絕任何工作區擁有者 ——請先轉移)。

**自訂角色是減法式的。**自訂角色會指定一個基礎預設組合(admin、 member、viewer 或 guest——絕不會是 owner),以及一組從中移除的 權限——「管理員,但不能管理成員」。它永遠不會授予比其基礎更多的權限, 這正是它能安全導入既有安裝的原因:每一項既有的檢查仍然是有力的上限。 成員以 custom:<id> 持有它們,而太舊、無法理解該值的用戶端會退回訪客, 而不是自行猜測。

角色之下還有個別儲存庫授權(none / read / review / write):工作區成員身分絕不會悄悄給予高於程式碼託管服務的權限。每一 個會接觸程式碼的介面都會檢查它們——包括從側面觸及程式碼的介面,例如 在空間工作樹上開啟的終端機或編輯器工作階段。

有些操作與工作區完全無關:整台安裝層級的設定、SSO 設定、供應商憑證、 模型管理、整台安裝的備份。這些操作會宣告伺服器權限,除了這台安裝 的操作者(記錄中的伺服器擁有者)之外,對所有人都會被拒絕。這裡刻意只 保留一個操作者身分,以及它唯一的定義。

每一項授權決策——允許與拒絕——都會附加到每個工作區各自持有的 雜湊鏈稽核軌跡。

只記錄拒絕的日誌能回答「我們阻擋了什麼?」,卻無法回答「這個代理實際 做了什麼,又是誰授權的?」,而後者正是事件檢討的起點。因此每一筆項目 都會記錄完整的歸屬鏈:實際行動的主體、它代表的人、它是透過哪一項委派 而來的、動作及其引數(以摘要表示)、決策,以及做出決定的規則。

項目之間彼此串鏈:每一筆的雜湊都涵蓋前一筆,因此只要編輯、刪除或重新 排序任何一列,就會使其後每一筆雜湊失效。驗證鏈會重新推導整條鏈, 並指出第一個不成立的環節。無法查核的稽核日誌只是日誌;能重新推導的 才是證據。

有兩個值得知道的後果:

  • 稽核資料表豁免於以時間為基礎的修剪。雜湊鏈無法從中段修剪。保留 策略是先匯出再截斷,而截斷會留下一個檢查點,帶著被移除區段的最終 雜湊,因此留存下來的部分仍可一路驗證回開頭。
  • 它位於活動時間軸旁邊,而不是疊在其上。時間軸記錄人們做了什麼; 這裡記錄的是什麼被授權、什麼被拒絕。共用的關聯 id 讓同一通呼叫能 貫穿兩者來閱讀。

它會以換行分隔的 JSON 匯出,並可串流到 SIEM(Splunk、Elastic、 Sentinel——一個帶有 bearer token 的 HTTP 端點)。串流在設計上採盡力 而為:SIEM 停機絕不應阻擋代理的工具呼叫,而可持久、可驗證的副本無論 如何都保存在磁碟上。

一台安裝可以設定工作階段最長存續時間與閒置逾時。兩者都會在 每一條已驗證管道必經的裝置憑證檢查點強制執行——一個用戶端能忽略的 工作階段期限,應付的是問卷,而不是攻擊者。一台安裝也可以要求使用 SSO, 這會停用新裝置的手動配對(並有鎖定防護:在沒有可用 SSO 連線時會拒絕 啟用)。

  • **不是以個別物件為單位的 ACL。**這裡刻意不提供以個別工單或個別訊息 為單位的權限。團隊真正需要的是儲存庫層級的區隔,而這樣的功能確實 存在;以個別物件分享會帶來組合爆炸的介面,且在此處沒有展現出需求。
  • **不是讓你在 DSL 中設定的原則引擎。**詞彙刻意保持封閉,因此整套原則 可以被呈現、解釋與列舉。
  • **只在伺服器端強制執行。**用戶端檢查的存在,只是為了避免提供一個 會被拒絕的控制項。具權威性的決策永遠由伺服器做出。