這種方式的好處是可以跨語言, 不侷限於Go, 透過標準RESTFUL API的方式來與OPA Server相互溝通。
流程
環境準備
使用Docker來架設OPA Server。
# pull docker image
docker pull openpolicyagent/opa:0.29.1
# start with server
docker run --rm -p 8181:8181 openpolicyagent/opa:0.29.1 run --server --addr :8181
情境:
- UserA要對某一篇文章進行編輯。
- 透過OPA檢驗是否具有編輯文章的權限。
準備資料並上傳到OPA Server
Data
- 定義使用者具有哪些角色。
- 定義各個角色分別有哪些操作權限。
- data.json。
{
"user_roles": {
"userA": ["editor"]
},
"role_permissions": {
"editor": [
{ "action": "edit", "object": "article" }
]
}
}
將data.json上傳到OPA Server
# 上傳Data檔 ↓ 自己定義的路徑
curl -X PUT <http://127.0.0.1:8181/v1/data/rbac/authz/acl> --data-binary @data.json
策略制定
- 簡單的RBAC驗證。
- 檢查用戶被賦予的角色是否能夠對文章進行編輯。
- rbac.authz.rego。
package rbac.authz
import data.rbac.authz.acl
import input
default allow = false
allow {
# 將user所擁有的角色整理起來
roles := acl.user_roles[input.user]
# 對每一個角色進行處理
r := roles[_]
# 取出每個角色擁有哪些操作權限
permissions := acl.role_permissions[r]
# 準備對每一個權限進行檢查
p := permissions[_]
# 檢查權限是否與請求的功能、操作相互匹配
p == {"action": input.action, "object": input.object }
}
將Data及Policy上傳到OPA Server
# 上傳Policy檔
curl -X PUT <http://127.0.0.1:8181/v1/policies/rbac.authz> --data-binary @rbac.authz.rego
設計請求資料並進行驗證
{
"input": {
"user": "userA",
"object": "article",
"action": "edit"
}
}
curl -X POST <http://127.0.0.1:8181/v1/data/rbac/authz/allow> --data-binary @input.json
# Response
{"result":true}
結論
- Policy通常制定好之後就不容易在進行變更。
- Data是比較常變動的地方,例如: 今天新增角色或修改角色對應的權限...等操作,就會產生新的Data檔, 這時候就得PUT更新回OPA Server。
- 透過API傳輸可能會有一些延遲, 當然也可以直接以Library的方式嵌入到Go,這就看團隊如何取捨了。