策略即代码(PaC):从Rego到自动化合规框架
文章目录
一、Rego语言高级策略:函数级访问控制
1.1 基于属性的访问控制(ABAC)
策略定义:
package authz
# 用户属性定义
user_attributes[user] = attributes {
users := data.users
user := users[_].id
attributes := {
"department": users[_].department,
"role": users[_].role,
"clearance": users[_].clearance
}
}
# 资源属性定义
resource_attributes[resource] = attributes {
resources := data.resources
resource := resources[_].id
attributes := {
"sensitivity": resources[_].sensitivity,
"owner_dept": resources[_].owner
}
}
# ABAC授权逻辑
allow {
# 权限需求:用户密级 >= 资源敏感度
user_attributes[input.user].clearance >= resource_attributes[input.resource].sensitivity
# 部门约束:用户部门匹配资源所属部门
user_attributes[input.user].department == resource_attributes[input.resource].owner_dept
# 操作白名单
input.action in {"read", "write"}
}
# 拒绝所有其他请求
default allow = false
1.2 动态策略组合
策略继承机制:
package department_policy
# 基础策略
import data.base_policy
# 金融部门增强策略
enhanced_rules[msg] {
input.user.department == "finance"
input.resource.type == "financial_report"
not base_policy.allow # 基础策略未覆盖
# 附加双人审批
count(input.approvals) >= 2
msg := "财务报告需双人审批"
}
# 组合策略
allow {
base_policy.allow
}
allow {
enhanced_rules[_] = _
}
1.3 时间约束策略
时间窗口访问控制:
package time_based
# 工作时间定义
working_hours {
now := time.now_ns()
hour := time.clock(now)[0]
hour >= 9
hour < 18
time.weekday(now) != "Saturday"
time.weekday(now) != "Sunday"
}
# 紧急访问例外
emergency_access {
input.reason == "incident_response"
input.approver == "security-admin"
}
# 访问策略
allow {
working_hours
}
allow {
emergency_access
}
二、Styra DAS的Go工作流集成
2.1 架构概览
2.2 SDK集成实战
策略执行引擎:
import (
"github.com/open-policy-agent/opa/sdk"
)
type PolicyEngine struct {
opa *sdk.OPA
}
func NewPolicyEngine() (*PolicyEngine, error) {
config := []byte(`
services:
styra:
url: https://styra.example.com
credentials:
bearer:
token: ${
{ secrets.STYRA_TOKEN }}
bundles:
main:
service: styra
resource: bundles/main
decision_logs:
service: styra
`)
opa, err := sdk.New(context.Background(), sdk.Options{
Config: config,
})
if err != nil {
return nil, err
}
return &PolicyEngine{
opa: opa}, nil
}
func (e *PolicyEngine) Authorize(user, action, resource string) bool {
input := map[string]interface{
}{
"user": user,
"action": action,
"resource": resource,
}
result, err := e.opa.Decision(context.Background()