You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:OPA AST库无法反序列化含some关键字的JSON AST

问题:OPA JSON AST反序列化失败(含some关键字时)

问题背景

将OPA生成的JSON格式AST反序列化为Go的ast.Module结构体时,只要Rego代码中包含some关键字,就会触发错误:panic: ast: unable to unmarshal term.


相关代码与输出

1. Rego策略代码(policy.rego)

package example.authz
import rego.v1

allow if {
    some i
    input.users[i].role == "admin"
}

2. 生成JSON AST的命令

opa parse --v1-compatible --format json policy.rego

3. 生成的JSON AST内容

{
  "package": {
    "path": [
      {
        "type": "var",
        "value": "data"
      },
      {
        "type": "string",
        "value": "example"
      },
      {
        "type": "string",
        "value": "authz"
      }
    ]
  },
  "imports": [
    {
      "path": {
        "type": "ref",
        "value": [
          {
            "type": "var",
            "value": "rego"
          },
          {
            "type": "string",
            "value": "v1"
          }
        ]
      }
    }
  ],
  "rules": [
    {
      "body": [
        {
          "index": 0,
          "terms": {
            "symbols": [
              {
                "type": "var",
                "value": "i"
              }
            ]
          }
        },
        {
          "index": 1,
          "terms": [
            {
              "type": "ref",
              "value": [
                {
                  "type": "var",
                  "value": "equal"
                }
              ]
            },
            {
              "type": "ref",
              "value": [
                {
                  "type": "var",
                  "value": "input"
                },
                {
                  "type": "string",
                  "value": "users"
                },
                {
                  "type": "var",
                  "value": "i"
                },
                {
                  "type": "string",
                  "value": "role"
                }
              ]
            },
            {
              "type": "string",
              "value": "admin"
            }
          ]
        }
      ],
      "head": {
        "name": "allow",
        "value": {
          "type": "boolean",
          "value": true
        },
        "ref": [
          {
            "type": "var",
            "value": "allow"
          }
        ]
      }
    }
  ]
}

4. 反序列化的Go代码

var module ast.Module
module.SetRegoVersion(ast.RegoV1)
if err = module.UnmarshalJSON(b); err != nil {
    panic(err)
}

5. 错误信息

panic: ast: unable to unmarshal term.

解决方案

问题根源是opa parse生成的JSON中,some i的结构不符合ast.Module反序列化的预期格式——some关键字需要被标记为特定类型的term,而非当前的terms.symbols结构。有两种解决方式:

方式1:直接解析Rego源代码(推荐)

跳过JSON转换步骤,用OPA原生API直接解析Rego代码到ast.Module,这是最可靠的方案:

import (
    "os"
    "github.com/open-policy-agent/opa/ast"
    "github.com/open-policy-agent/opa/parser"
)

func main() {
    // 读取Rego文件内容
    regoContent, err := os.ReadFile("policy.rego")
    if err != nil {
        panic(err)
    }

    // 解析为ast.Module
    module, err := parser.ParseModule("policy.rego", string(regoContent))
    if err != nil {
        panic(err)
    }
}

方式2:修正JSON AST结构

如果必须使用JSON AST,需要手动调整some i对应的节点结构:
原错误节点:

{
  "index": 0,
  "terms": {
    "symbols": [
      {
        "type": "var",
        "value": "i"
      }
    ]
  }
}

修改为符合要求的格式:

{
  "index": 0,
  "terms": [
    {
      "type": "some",
      "value": [
        {
          "type": "var",
          "value": "i"
        }
      ]
    }
  ]
}

调整后再执行反序列化即可成功。

内容的提问来源于stack exchange,提问作者user27911082

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:52:41