将OPA(Rego)作为Go库使用时如何加载外部JSON数据供策略调用
实现方案
你可以通过以下两种方式加载外部JSON文件作为Rego的数据源:
方案1:随策略文件静态加载(最简单)
rego.Load本身支持同时加载.rego策略文件和.json/.yaml数据文件,OPA会自动将数据挂载到data命名空间下:
- 如果你希望通过
data.wantedName直接访问,将JSON文件命名为wantedName.json,文件内容直接为对应的值/对象 - 将JSON文件路径加入
rego.Load的路径列表即可
示例代码:
r := rego.New( rego.Query("x = data.example.allow"), // 新增JSON文件路径到加载列表 rego.Load([]string{"./example.rego", "./wantedName.json"}, nil) ) // 后续查询逻辑不变 query, err := r.PrepareForEval(ctx) // ... rs, err := query.Eval(ctx, rego.EvalInput(input))
方案2:动态加载自定义挂载(灵活可控)
如果需要自定义数据挂载路径、或者运行时动态加载JSON数据,可以手动解析JSON后通过存储实例注入:
- 导入OPA内置的内存存储依赖
github.com/open-policy-agent/opa/storage/inmem - 读取并解析JSON文件
- 初始化内存存储实例,将解析后的数据注入
- 将存储实例传入
rego.New构造函数
示例代码:
import ( "encoding/json" "os" "github.com/open-policy-agent/opa/rego" "github.com/open-policy-agent/opa/storage/inmem" ) // 读取JSON文件 jsonBytes, err := os.ReadFile("./data.json") if err != nil { // 处理文件读取错误 } // 解析JSON为Go通用结构 var jsonData map[string]interface{} err = json.Unmarshal(jsonBytes, &jsonData) if err != nil { // 处理JSON解析错误 } // 初始化内存存储,将JSON数据直接挂载到data命名空间根路径 store := inmem.NewFromObject(jsonData) // 构造rego实例时传入存储 r := rego.New( rego.Query("x = data.example.allow"), rego.Load([]string{"./example.rego"}, nil), rego.Store(store), // 注入自定义存储 ) // 后续查询逻辑不变
此时如果你的data.json内容为{"wantedName": "demo"},直接在Rego中用data.wantedName即可访问对应值。
注意事项
- 两种方式可以同时使用,数据会自动合并,命名冲突时
rego.Load加载的数据优先级更高 - JSON中的数组、嵌套对象会自动映射为Rego对应的语法类型,无需额外转换
内容的提问来源于stack exchange,提问作者bogg
相关产品推荐
相关产品推荐

