題幹與適用情境
平台團隊希望把「禁止公開資料庫」「只允許簽章映像檔」「某角色只能存取自己的租戶」等規則,從文件變成可測試、可審查、可自動執行的策略。面試官要求你解釋 Policy as Code,並畫出策略決策與業務執行的邊界。
預設假設:請求來自 API、CI/CD 或基礎設施變更;策略輸入是結構化 JSON;策略需要版本、回復和稽核。題目討論通用邊界,不綁定 OPA、Rego 或任何一家公司的實作。
面試官考察重點
- 能否把策略定義、決策計算和強制執行拆成清楚的職責。
- 是否知道策略引擎可以回傳結構化結果,而不只是布林值。
- 能否處理策略與輸入資料的版本一致性、逾時、快取和預設拒絕。
- 能否把策略程式碼納入程式碼審查、測試、發布和稽核,而不是當成設定檔複製。
普通回答只說「用 OPA 做授權」。強回答會說明 PEP 在請求邊界阻擋動作,PDP 只負責計算決定,而且每個決定都能解釋、重播和追蹤。
回答前需要釐清的問題
- 決定的是執行期存取,還是部署前合規檢查?執行期更在意延遲與可用性,部署前更在意回饋與阻斷。
- 策略輸入由誰提供,身分、租戶、資源標籤和環境狀態是否可信?輸入不完整時不能默默放行。
- 失敗時預設拒絕、降級放行還是進入人工審批?取決於動作的破壞性和業務可用性目標。
- 是否允許策略發布與業務程式碼獨立上線?獨立發布需要版本綁定、相容性檢查和快速回復。
- 稽核需要看到哪些欄位?若輸入含個人或機密資料,日誌必須先去識別或遮罩。
30 秒回答框架
「Policy as Code 把可執行規則放進版本控制、審查和測試流程。請求先由 PEP 收集並正規化主體、動作、資源和環境,再呼叫 PDP 計算結構化決定,例如允許、拒絕、原因和策略版本。PEP 負責真正阻擋或繼續執行,不能把 PDP 回傳當成安全控制已經完成。我會為決定綁定策略與輸入版本,採用預設拒絕、受控快取和逾時策略,並記錄可去識別的決定日誌。發布前做重播和金絲雀,緊急放行也要有期限、審批和稽核。」
分步驟深入解答
1. 先定義策略物件和決策邊界
把自然語言規則拆成主體、動作、資源、條件和結果。例如「服務不得公開暴露未加密連接埠」可以表達為:主體是部署流程,動作是建立服務,資源是服務設定,條件是連接埠與網路屬性,結果是拒絕並附帶修正訊息。
PDP 讀取正規化輸入和策略,回傳 allow、deny、warn 或更豐富的結構化資料。PEP 位於 API、Admission Controller、CI job 或服務呼叫邊界,負責把決定落實為阻擋、繼續、修改或人工升級。
caller -> PEP: subject, action, resource, context
PEP -> PDP: normalized input + policy version
PDP -> PEP: decision, reasons, obligations, decision_id
PEP -> target: enforce decision or stop request
PEP -> audit: redacted decision recordOPA 官方文件明確強調決策與執行解耦,AWS 設計指南也把 PDP 與 API 上的 PEP 分開。這個邊界讓同一套規則可用於多個入口,但不會誤以為策略引擎能替業務完成交易。
2. 正規化輸入並處理缺少欄位
不同入口的原始格式不同:CI 可能給 YAML 計畫,API 給 HTTP 請求,服務間呼叫給物件。PEP 或授權中介層應先轉成穩定的內部結構,並標記來源、時間和資料版本。
缺少租戶、資源擁有者或環境狀態時,預設拒絕比猜測安全。策略要區分「明確拒絕」和「無法判斷」,讓 PEP 決定是否人工審批或稍後重試;不能把 undefined 當成 allow。
{
"subject": {"id": "u-17", "tenant": "t-3", "roles": ["reader"]},
"action": "read",
"resource": {"type": "invoice", "id": "inv-9", "tenant": "t-3"},
"context": {"environment": "prod", "authn_level": "mfa"},
"policy_version": "2026-06-18.4"
}3. 讓策略成為可測試的軟體
策略檔進入 Git,經過語法檢查、單元測試、對抗樣例和程式碼審查。測試不只驗證 allow,也要驗證相鄰租戶、缺少欄位、過期身分、衝突規則和預設路徑。
package invoices
default allow := false
allow if {
input.action == "read"
input.subject.tenant == input.resource.tenant
"reader" in input.subject.roles
}測試輸入應固定策略版本和資料快照。若規則依賴即時目錄或網路呼叫,先定義逾時和陳舊資料上限,再決定是否允許本地快取。
4. 設計發布、快取和回復
策略發布要像服務發布一樣有版本號、相容性檢查和回復。PDP 可以用本地 sidecar、函式庫或集中服務部署:本地模式降低網路延遲,集中模式便於統一管理;選擇取決於策略更新速度、故障半徑和一致性要求。
快取只能快取有明確存活期的決定,並綁定主體、資源、策略版本和輸入資料版本。權限撤銷、租戶遷移或高風險動作不應使用無法及時失效的長快取。PDP 逾時後,PEP 應按動作風險選擇拒絕、人工審批或有限的預先核准路徑。
5. 記錄可解釋且可去識別的決定
每次決定至少需要策略版本、輸入摘要、結果、原因、決定 ID 和 PEP 標識,才能在事故後重播。輸入可能含使用者名稱、權杖或機密,日誌系統應在上傳前刪除或遮罩敏感欄位。
「允許」也可以帶義務,例如必須寫稽核事件、限制欄位或要求二次確認。PDP 回傳義務,PEP 負責執行並在無法執行時拒絕或升級。
高品質示範回答
我會把 Policy as Code 定義為:把安全、合規和運作約束寫成可版本化、可測試的機器可讀規則。請求先到 PEP,由它驗證身分、組裝並正規化主體、動作、資源和上下文,再把輸入和策略版本交給 PDP。PDP 只計算決定,回傳 allow、deny、原因、義務和決定 ID;PEP 才負責阻擋請求、繼續業務或發起人工審批。
我會為策略和輸入綁定版本,策略進入 Git、審查、單元測試和重播流程。執行期優先預設拒絕,快取綁定策略版本和授權資料版本;撤銷權限等高風險變化要快速失效。PDP 不可用時不能一概降級放行,我會按動作風險分別處理。最後記錄經過去識別的決定日誌,支援稽核和回復。這樣同一規則能重用在 API、CI 和基礎設施入口,同時保留每個入口的執行責任。
常見錯誤
- 錯誤表現 → 讓 PDP 直接修改資料庫或執行部署 → 失敗原因 → 決策與副作用混在一起,難以重試和稽核 → 修正方法 → PDP 回傳決定與義務,PEP 或業務服務執行副作用。
- 錯誤表現 → PDP 逾時就預設放行 → 失敗原因 → 網路故障變成權限繞過 → 修正方法 → 按動作風險採用拒絕、人工審批或短期預核准。
- 錯誤表現 → 只記錄 allow/deny → 失敗原因 → 無法解釋哪條規則和哪份輸入導致結果 → 修正方法 → 記錄策略版本、原因、決定 ID 與去識別輸入摘要。
- 錯誤表現 → 把策略快取當成永久真相 → 失敗原因 → 撤銷或租戶變更無法及時生效 → 修正方法 → 綁定資料版本和失效時間,關鍵事件主動清除快取。
追問及應對
如果 PDP 集中服務不可用,所有讀取請求都要失敗嗎?
先按風險分級。修改權限、轉帳、跨租戶讀取等高風險動作預設拒絕;低風險唯讀動作可以使用短期、版本綁定的本地決定,但必須記錄使用了快取,並在恢復後補做稽核。不能把可用性作為所有資源的統一放行理由。
如果策略和身分目錄同時更新,怎樣避免舊決定覆蓋新權限?
讓決定攜帶策略版本與身分資料版本,PEP 在執行前檢查版本或租約。撤銷事件觸發快取失效;無法確認版本時走拒絕或重新評估。測試中加入並行更新和延遲訊息,驗證舊決定不會被重新寫回。
如果兩條規則一條 allow、一條 deny,誰優先?
優先順序必須明確定義,不能依賴檔案順序。可以採用預設拒絕、明確 deny 優先,或將規則合併成帶原因和風險等級的決定。規則衝突應有測試案例和發布阻斷,避免不同入口解讀不一致。
如何支援緊急放行而不破壞稽核?
把緊急放行建模成有審批人、範圍、原因、開始和到期時間的臨時策略或義務;PEP 每次使用時記錄它。到期自動撤銷,重播工具能區分正常規則和緊急例外,不能透過手工改資料庫繞過策略版本。