Photo by Dan Nelson on Unsplash

Open Policy Agent Survey & Simple Try

yanyan
Gemini Open Cloud 雙子星雲端
13 min readFeb 9, 2022

--

Open Policy Agent (OPA,讀音為 歐趴) 最初是由 Styra 所建立,後來貢獻到 CNCF。目前由 Styra、Google、Microsoft、和 VMWare 構成開源專案的主要貢獻者團隊。

OPA 實現了一個輕量的政策管理服務,因此可以作為服務的 sidecar 運行,也能作為獨立的政策管理服務運行於整體服務群內。軟體服務可以基於給定的資訊透過 RESTful API 的方式「查詢」相關政策的判斷結果。

Open Policy Agent 如何運作?

如圖可以看到向 OPA 查詢 Policy 的流程,OPA 可以確保各種 API Request 的權限。

  1. User 發送 Request 至服務的 API Server。
  2. API Server 執行 Request 前先向 Open Policy Agent (OPA)查詢該 User 的操作權限。
  3. OPA 根據事先定義好的 Policy 和 Data 查詢結果並回傳 Permission。
  4. API Server 再根據收到的 Permission 決定是否執行 User Request,最後回傳結果給 User。
API Server 向 OPA 查詢 Policy 流程

部署 Open Policy Agent

1. OPA as a Go library

如果服務是用 Go 語言寫的,那最快導入 OPA 的方式是 import OPA 在 Github 上面的 library。

import "github.com/open-policy-agent/opa/rego"

更多資訊請參考:Try OPA as a Go library

2. OPA as a container sidecar (Deploy on k8s):

  • opa-pod.yaml:
apiVersion: apps/v1
kind: Pod
metadata:
name: opa
labels:
app: opa
spec:
containers:
- name: opa
image: openpolicyagent/opa:0.35.0
ports:
- name: http
containerPort: 8181
args:
- "run"
- "--ignore=.*" # exclude hidden dirs created by Kubernetes
- "--server"
- "/policies"
volumeMounts:
- readOnly: true
mountPath: /policies
name: example-policy
volumes:
- name: example-policy
configMap:
name: example-policy
  • opa-service.yaml:
kind: Service
apiVersion: v1
metadata:
name: opa
labels:
app: opa
spec:
type: NodePort
selector:
app: opa
ports:
- name: http
protocol: TCP
port: 8181

更多資訊請參考:Deployment OPA on Kubernetes

3. OPA on Host-level daemon:

  1. Download Open Policy Agent(OPA)
  • On macOS (64-bit) :
curl -L -k -o opa https://openpolicyagent.org/downloads/v0.35.0/opa_darwin_amd64
  • On Linux (64-bit) :
curl -L -k -o opa https://openpolicyagent.org/downloads/v0.35.0/opa_linux_amd64_static

在 Windows 上使用 OPA,Download here

  • Set permissions on the OPA executable :
chmod 755 ./opa

2. Run OPA for Host daemon

./opa run --server

OPA 預設路由 0.0.0.0:8181,可透過 opa run — help,查看更多設定,例如:change default listening address、enable TLS 等等設定。

範例

1. 定義使用情境

假設今天希望針對 site 的操作實施以下規則:

使用者可以操作自己的 site,管理者可以操作所有的 site

API Server 在執行 site 的操作之前,先送一個 Request 到 OPA 去詢問該使用者是否具有權限操作 site。

  • 一般 User 送往 OPA 的 Request :
{
"input":{
"subject": {
"id": "Brown",
"type": "user"
},
"object": {
"id": "site-1",
"type": "site",
"owner": "Brown"
},
"action": "delete"
}
}
  • Sys Admin 送往 OPA 的 Request :
{
"input":{
"subject": {
"id": "admin",
"type": "admin"
},
"object": {
"id": "site-1",
"type": "site",
"owner": "Brown"
},
"action": "delete"
}
}

2. 撰寫 Policy

定義好使用情境和要送往 OPA 的 Request 後,就可以針對要執行的 Policy 撰寫 Policy file,而 OPA 的 Policy file 是透過 Rego 撰寫而成的,更多 Rego 相關資訊請參考官網

  • Rule 1 :

使用者可以操作自己的 site

先針對第一條規則撰寫我們的 Rego Policy file

  1. 首先 import request 中的 input 資源
  2. 將 allow 的權限預設為 false
  3. 撰寫 allow function,當 function 中的各個判斷式都成立時,將會回傳 true 允許使用者執行 request
package example

import input.subject
import input.object

default allow = false

allow {
subject.type == "user"
object.type == "site"
subject.id == object.owner
}
  • Rule 2 :

管理者可以操作所有 site

接著根據第二條規則修改 Rego Policy file

  1. 再新增一個 allow function
  2. 判斷使用者的 type 是不是 admin
allow {
subject.type == "admin"
object.type == "site"
}

3. 測試 Policy

撰寫完 Policy file 之後,可以透過以下幾種方式簡單測試設計的 Policy。

  1. Open Policy Agent(OPA) Playground

OPA 官網提供了一個 online playground,可以自行輸入 input、Data、Policy,驗證撰寫的結果是否符合預期。

將上面定義好的 Policy 政策、input data 輸入至 playground 中,就可以在 output 中看到輸出結果,透過這個 OPA playground 可以簡單的測試我們撰寫的 Policy 跟 input request 是否有符合預期。

opa playground 測試頁面

2. Local Run OPA Server

在 local 端安裝好 OPA 之後,透過 ./opa run -s(or --server) 的 command 來執行 OPA server,這樣就能透過 RESTful API 的方式向 OPA 查詢 Policy。

opa server log
  • 執行 OPA server 並啟用 Policy :
./opa run --server ./example.rego
  • 監聽 folder 來啟用多個 Policy or Data :
./opa run --server --watch <your folder>
  • 輸入 input 測試 Policy :
curl -X POST http://localhost:8181/v1/data/example -d @input.json
use postman test opa

3. Policy Test file :

  • 也可以透過撰寫 Test file 來測試 Policy
package example

test_user_allowed {
allow with input as {"subject": {"id": "yan", "type": "user"}, "object": {"id": "site-1", "type": "site", "owner": "yan"}, "action": "get"}
}

test_user_denied {
not allow with input as {"subject": {"id": "rick", "type": "user"}, "object": {"id": "site-1", "type": "site", "owner": "yan"}, "action": "get"}
}

test_admin_allowed {
allow with input as {"subject": {"id": "admin", "type": "admin"}, "object": {"id": "site-1", "type": "site", "owner": "yan"}, "action": "get"}
}

更多 test file 請參考官網

  • 執行 opa test . -v 來查看測試結果
policy test file test result

4. 同步 Policy

在分散式的 Open Policy Agent 中,可以透過以下方式來達到 Policy 的同步,讓每個 OPA Server 之間的 Policy & Data 保持一致。

  1. NFS 同步檔案
    透過 ./opa run -s --watch <your folder> 啟動的 OPA server 會監聽該資料夾下的檔案是否有更新,所以可以使用 NFS 將 folder mount 起來達到同步的效果。
  2. OPA Bundles Feature
    透過將 Policy 或是 Context Data 包成一個 tar.gz 的檔案後,讓 OPA server 將壓縮檔下載後更新 Policy。
    所以需要提供一個 config yaml 檔給 OPA server,讓 OPA 知道該去哪邊下載 Policy 檔案。
services:
- name: acmecorp
url: https://example.com/service/v1
credentials:
bearer:
token: "bGFza2RqZmxha3NkamZsa2Fqc2Rsa2ZqYWtsc2RqZmtramRmYWxkc2tm"

bundles:
authz:
service: acmecorp
resource: somedir/bundle.tar.gz
persist: true
polling:
min_delay_seconds: 10
max_delay_seconds: 20
signing:
keyid: my_global_key
scope: read

設定好 config 之後,就可以透過 opa run -s --config-file <your config yaml> 執行自動下載 Policy 的 OPA server。

更多 Bundle 設定請參考官網
OPA 總共支援 4 種 file storage:Amazon S3、Google Cloud Storage、Azure Blob Storage 以及自建在 Nginx 的 file storage。

結論

透過 OPA 將 Policy 從 Service 中分離,讓 Policy 擁有一個獨立而且統一的規範,也可以透過 sidecar 的部署方式,降低 Service 訪問 Policy Agent 的網路延遲,並同時確保 Policy Agent 的可靠性,也因為 Policy 與 Service 分離,所以可以動態的更新 Policy 而不用重啟 Service。

以上透過一個例子來簡單的介紹 OPA 的基本功能,OPA 也提供了取代 Kubernetes 原有 Admission Controllers 的進階用法,對這部分有興趣的讀者,可以參考官網,或是期待下次有機會再為大家介紹。

OPA as Kubernetes Admission Controllers official docs : here

雙子星雲端為 CNCF 會員,是 CNCF 所認證的 Kubernetes 服務提供商,在雲端技術擁有十多年以上的經驗,為台灣雲端技術早期領先者。目前為國家級 AI 雲的軟體及 Kubernetes 技術與服務提供商,更是諸多企業與單位導入容器與管理平台的最佳夥伴。

雙子星雲端除了既有的產品 AI Console 與 Gemini API Gateway 之外,也提供企業諮詢與導入雲原生與 Kubernetes 相關技術服務,協助企業擁抱 Cloud Natvive,達到數位轉型的目標。

Reference

  1. Open Policy Agent Docs
  2. Open Policy Agent — 快速導入 Authz 至 Microservice 架構
  3. 使用 RESTful API 串接 Open Policy Agent
  4. 初探 Open Policy Agent 實作 RBAC (Role-based access control) 權限控管
  5. Secure Your Service on Kubernetes With Open Policy Agent
  6. Enforce Ingress Best Practices Using OPA
  7. Open Policy Agent (OPA): Up and Running
  8. 從軟體系統中解耦政策(Policy)實作,為組織提供更一致的服務政策管理
  9. 策略即代码 — — Open Policy Agent(开放策略代理 OPA)简介

--

--

yanyan
Gemini Open Cloud 雙子星雲端
0 Followers

菜鳥RD工程師一隻,跟著雙子星雲端運算一起成長茁壯,讓我們一起翱翔在雲端的世界中。