声明转换规则语言Claims Transformation Rules Language

适用于:Windows Server 2016、Windows Server 2012 R2、Windows Server 2012Applies To: Windows Server 2016, Windows Server 2012 R2, Windows Server 2012

利用跨林声明转换功能,可以通过在跨林信任上设置声明转换策略来跨林边界桥接用于动态访问控制的声明。The across-forest claims transformation feature enables you to bridge claims for Dynamic Access Control across forest boundaries by setting claims transformation policies on across-forest trusts. 所有策略的主要组件都是用声明转换规则语言编写的规则。The primary component of all policies is rules that are written in claims transformation rules language. 本主题提供有关此语言的详细信息,并提供有关创作声明转换规则的指导。This topic provides details about this language and provides guidance about authoring claims transformation rules.

跨林信任上的转换策略的 Windows PowerShell cmdlet 具有设置常见方案中所需的简单策略的选项。The Windows PowerShell cmdlets for transformation policies on across-forest trusts have options to set simple policies that are required in common scenarios. 这些 cmdlet 将用户输入转换为声明转换规则语言中的策略和规则,然后以规定的格式将其存储在 Active Directory 中。These cmdlets translate the user input into policies and rules in the claims transformation rules language, and then store them in Active Directory in the prescribed format. 有关用于声明转换的 cmdlet 的详细信息,请参阅适用于动态访问控制的 AD DS cmdletFor more information about cmdlets for claims transformation, see the AD DS Cmdlets for Dynamic Access Control.

根据对 Active Directory 林中的跨林信任的声明配置和要求,声明转换策略可能比用于 Active Directory 的 Windows PowerShell cmdlet 支持的策略更复杂。Depending on the claims configuration and the requirements placed on the across-forest trust in your Active Directory forests, your claims transformation policies may have to be more complex than the policies supported by the Windows PowerShell cmdlets for Active Directory. 若要有效地创作此类策略,必须了解声明转换规则语言语法和语义。To effectively author such policies, it is essential to understand the claims transformation rules language syntax and semantics. 此声明转换规则语言 ( "language" ) 在 Active Directory 中是Active Directory 联合身份验证服务用于类似用途的语言子集,并且具有非常相似的语法和语义。This claims transformation rules language ("the language") in Active Directory is a subset of the language that is used by Active Directory Federation Services for similar purposes, and it has a very similar syntax and semantics. 但允许的操作较少,并且其他语法限制会置于语言的 Active Directory 版本中。However, there are fewer operations allowed, and additional syntax restrictions are placed in the Active Directory version of the language.

本主题简要介绍了中的声明转换规则语言的语法和语义,以及在创作策略时应考虑的注意事项 Active Directory。This topic briefly explains the syntax and semantics of the claims transformation rules language in Active Directory and considerations to be made when authoring policies. 它提供了几组示例规则来帮助您入门,并举例说明了如何在编写规则时破译错误消息。It provides several sets of example rules to get you started, and examples of incorrect syntax and the messages they generate, to help you decipher error messages when you author the rules.

用于创作声明转换策略的工具Tools for authoring claims transformation policies

适用于 Active Directory 的 Windows PowerShell cmdlet:这是创作和设置声明转换策略的首选和推荐方式。Windows PowerShell cmdlets for Active Directory: This is the preferred and recommended way to author and set claims transformation policies. 这些 cmdlet 提供简单策略的开关,并验证为更复杂的策略设置的规则。These cmdlets provide switches for simple policies and verify rules that are set for more complex policies.

Ldap:通过轻型目录访问协议 (ldap) ,可以在 Active Directory 中编辑声明转换策略。LDAP: Claims transformation policies can be edited in Active Directory through Lightweight Directory Access Protocol (LDAP). 但是,不建议这样做,因为策略具有几个复杂的组件,而你使用的工具可能在将策略写入 Active Directory 之前不会对其进行验证。However, this is not recommended because the policies have several complex components, and the tools you use may not validate the policy before writing it to Active Directory. 这可能需要花费相当长的时间来诊断问题。This may subsequently require a considerable amount of time to diagnose problems.

Active Directory 声明转换规则语言Active Directory claims transformation rules language

语法概述Syntax overview

下面是该语言的语法和语义的简要概述:Here is a brief overview of the syntax and semantics of the language:

  • 声明转换规则集包含零个或多个规则。The claims transformation rule set consists of zero or more rules. 每个规则都有两个活动部分: "选择条件列表" 和 "规则操作"。Each rule has two active parts: Select Condition List and Rule Action. 如果 "选择条件" 列表的计算结果为 TRUE,则执行相应的规则操作。If the Select Condition List evaluates to TRUE, the corresponding rule action is executed.

  • 选择条件列表中有零个或多个选择条件Select Condition List has zero or more Select Conditions. 所有选择条件的计算结果都必须为 True,选择条件列表的计算结果为 true。All of the Select Conditions must evaluate to TRUE for the Select Condition List to evaluate to TRUE.

  • 每个选择条件都具有一组零个或多个匹配条件Each Select Condition has a set of zero or more Matching Conditions. 所有匹配条件的计算结果都必须为 true,否则,Select 条件的计算结果为 true。All the Matching Conditions must evaluate to TRUE for the Select Condition to evaluate to TRUE. 所有这些条件都针对单个声明进行评估。All of these conditions are evaluated against a single claim. 选择条件匹配的声明可由标识符标记,并在规则操作中引用。A claim that matches a Select Condition can be tagged by an Identifier and referred to in the Rule Action.

  • 每个匹配条件都通过使用不同的条件运算符字符串文本来指定匹配声明的类型值****的条件Each Matching Condition specifies the condition to match the Type or Value or ValueType of a claim by using different Condition Operators and String Literals.

    • 为某个指定匹配条件时,还必须为特定ValueType指定匹配条件,反之亦然。When you specify a Matching Condition for a Value, you must also specify a Matching Condition for a specific ValueType and vice versa. 这些条件必须在语法中彼此相邻。These conditions must be next to each other in the syntax.

    • ValueType匹配条件只能使用特定的ValueType文本。ValueType matching conditions must use specific ValueType literals only.

  • 规则操作可以复制用标识符标记的一个声明,或者根据用标识符和/或给定字符串文本标记的声明发出一个声明。A Rule Action can copy one claim that is tagged with an Identifier or issue one claim based on a claim that is tagged with an Identifier and/or given String Literals.

示例规则Example rule

此示例显示了一个规则,该规则可用于在两个林之间转换声明类型,前提是它们使用相同的声明具有,并对此类型的声明值具有相同的解释。This example shows a rule that can be used to translate the claims Type between two forests, provided that they use the same claims ValueTypes and have the same interpretations for claims Values for this type. 此规则具有一个匹配条件和一个使用字符串文本和匹配声明引用的发出语句。The rule has one matching condition and an Issue statement that uses String Literals and a matching claims reference.

C1: [TYPE=="EmployeeType"]
                 => ISSUE (TYPE= "EmpType", VALUE = C1.VALUE, VALUETYPE = C1.VALUETYPE);
[TYPE=="EmployeeType"] == Select Condition List with one Matching Condition for claims Type.
ISSUE (TYPE= "EmpType", VALUE = C1.VALUE, VALUETYPE = C1.VALUETYPE) == Rule Action that issues a claims using string literal and matching claim referred with the Identifier.

运行时操作Runtime operation

务必要了解声明转换的运行时操作,以便有效地创作规则。It is important to understand the runtime operation of claims transformations to author the rules effectively. 运行时操作使用三组声明:The runtime operation uses three sets of claims:

  1. 输入声明集:向声明转换操作提供的输入声明集。Input claims set: The input set of claims that are given to the claims transformation operation.

  2. 工作声明集:在声明转换期间从或写入的中间声明。Working claims set: Intermediate claims that are read from and written to during the claims transformation.

  3. 输出声明集:声明转换操作的输出。Output claims set: Output of the claims transformation operation.

下面是运行时声明转换操作的简要概述:Here is a brief overview of the runtime claims transformation operation:

  1. 声明转换的输入声明用于初始化工作声明集。Input claims for claims transformation are used to initialize the working claims set.

    1. 处理每个规则时,工作声明集用于输入声明。When processing each rule, the working claims set is used for the input claims.

    2. 规则中的 "选择条件" 列表与工作声明集中的所有可能声明集相匹配。The Selection Condition List in a rule is matched against all possible sets of claims from the working claims set.

    3. 每组匹配声明用于在该规则中运行操作。Each set of matching claims is used to run the action in that rule.

    4. 运行规则操作将生成一个声明,并将其追加到输出声明集和工作声明集。Running a rule action results in one claim, which is appended to the output claims set and the working claims set. 因此,规则的输出用作规则集中后续规则的输入。Thus, the output from a rule is used as input for subsequent rules in the rule set.

  2. 规则集中的规则按从第一条规则开始的顺序进行处理。The rules in the rule set are processed in sequential order starting with the first rule.

  3. 处理整个规则集时,将处理输出声明集以删除重复的声明和其他安全问题。生成的声明是声明转换过程的输出。When the entire rule set is processed, the output claims set is processed to remove duplicate claims and for other security issues.The resulting claims are the output of the claims transformation process.

可以根据以前的运行时行为编写复杂的声明转换。It is possible to write complex claims transformations based on the previous runtime behavior.

示例:运行时操作Example: Runtime operation

此示例演示使用两个规则的声明转换的运行时操作。This example shows the runtime operation of a claims transformation that uses two rules.

     C1:[Type=="EmpType", Value=="FullTime",ValueType=="string"] =>
                Issue(Type=="EmployeeType", Value=="FullTime",ValueType=="string");
     [Type=="EmployeeType"] =>
               Issue(Type=="AccessType", Value=="Privileged", ValueType=="string");
Input claims and Initial Evaluation Context:
  {(Type= "EmpType"),(Value="FullTime"),(ValueType="String")}
{(Type= "Organization"),(Value="Marketing"),(ValueType="String")}
After Processing Rule 1:
 Evaluation Context:
  {(Type= "EmpType"),(Value="FullTime"),(ValueType="String")}
{(Type= "Organization"), (Value="Marketing"),(ValueType="String")}
  {(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}
Output Context:
  {(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}

After Processing Rule 2:
Evaluation Context:
  {(Type= "EmpType"),(Value="FullTime"),(ValueType="String")}
{(Type= "Organization"),(Value="Marketing"),(ValueType="String")}
  {(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}
  {(Type= "AccessType"),(Value="Privileged"),(ValueType="String")}
Output Context:
  {(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}
  {(Type= "AccessType"),(Value="Privileged"),(ValueType="String")}

Final Output:
  {(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}
  {(Type= "AccessType"),(Value="Privileged"),(ValueType="String")}

特殊规则语义Special rules semantics

下面是规则的特殊语法:The following are special syntax for rules:

  1. 空规则集 = = 无输出声明Empty Rule Set == No Output Claims

  2. 空选择条件列表 = = 每个声明都匹配选择条件列表Empty Select Condition List == Every Claim matches the Select Condition List

    示例:空选择条件列表Example: Empty Select Condition List

    以下规则匹配工作集中的每个声明。The following rule matches every claim in the working set.

    => Issue (Type = "UserType", Value = "External", ValueType = "string")
  3. 空选择匹配列表 = = 每个声明都匹配选择条件列表Empty Select Matching List == Every claim matches the Select Condition List

    示例:空的匹配条件Example: Empty Matching Conditions

    以下规则匹配工作集中的每个声明。The following rule matches every claim in the working set. 如果单独使用,则这是基本的 "全部允许" 规则。This is the basic "Allow-all" rule if it is used alone.

    C1:[] => Issule (claim = C1);

安全注意事项Security considerations

输入林的声明Claims that enter a forest

需要对传入林的主体所提供的声明进行彻底的检查,以确保仅允许或发出正确的声明。The claims presented by principals that are incoming to a forest need to be inspected thoroughly to ensure that we allow or issue only the correct claims. 不正确的声明可能会危及林的安全性,因此,在为进入林的声明创建转换策略时,应该考虑到这一点。Improper claims can compromise the forest security, and this should be a top consideration when authoring transformation policies for claims that enter a forest.

Active Directory 具有以下功能来防止错误配置输入林的声明:Active Directory has the following features to prevent misconfiguration of claims that enter a forest:

  • 如果林信任没有为输入林的声明设置声明转换策略,则为安全起见,Active Directory 删除进入林的所有主体声明。If a forest trust has no claims transformation policy set for the claims that enter a forest, for security purposes, Active Directory drops all the principal claims that enter the forest.

  • 如果在输入林的声明上运行规则集导致声明未在林中定义,则会从输出声明中删除未定义的声明。If running the rule set on claims that enters a forest results in claims that are not defined in the forest, the undefined claims are dropped from the output claims.

离开林的声明Claims that leave a forest

与进入林的声明相比,离开林的声明为林带来的安全问题更少。Claims that leave a forest present a lesser security concern for the forest than the claims that enter the forest. 即使不存在相应的声明转换策略,也允许声明将林保留原样。Claims are allowed to leave the forest as-is even when there is no corresponding claims transformation policy in place. 在转换离开林的声明的过程中,还可以发出未在林中定义的声明。It is also possible to issue claims that are not defined in the forest as part of transforming claims that leave the forest. 这就是通过声明轻松设置跨林信任。This is to easily set up across-forest trusts with claims. 管理员可以确定进入林的声明是否需要转换,并设置相应的策略。An administrator can determine if claims that enter the forest need to be transformed, and set up the appropriate policy. 例如,如果需要隐藏声明以防止信息泄露,管理员可以设置策略。For example, an administrator could set a policy if there is a need to hide a claim to prevent information disclosure.

声明转换规则中的语法错误Syntax errors in claims transformation rules

如果给定的声明转换策略具有语法不正确的规则集,或者存在其他语法或存储问题,则该策略被视为无效。If a given claims transformation policy has a rules set that is syntactically incorrect or if there are other syntax or storage issues, the policy is considered invalid. 此值的处理方式不同于前面提到的默认条件。This is treated differently than the default conditions mentioned earlier.

在这种情况下 Active Directory 无法确定目的并进入防故障模式,在该模式下,不会在该信任 + 遍历方向上生成输出声明。Active Directory is unable to determine the intent in this case and goes into a fail-safe mode, where no output claims are generated on that trust+direction of traversal. 若要解决此问题,需要管理员干预。Administrator intervention is required to correct the issue. 如果 LDAP 用于编辑声明转换策略,则会发生这种情况。This could happen if LDAP is used to edit the claims transformation policy. 适用于 Active Directory 的 Windows PowerShell cmdlet 进行了验证,以防止编写带有语法问题的策略。Windows PowerShell cmdlets for Active Directory have validation in place to prevent writing a policy with syntax issues.

其他语言注意事项Other language considerations

  1. 在这种语言中,有几个关键字或字符是特殊的 (称为终端) 。There are several key words or characters that are special in this language (referred to as terminals). 本主题后面的语言终端表中提供了这些项。These are presented in the Language terminals table later in this topic. 错误消息将这些终端的标记用于消除歧义。The error messages use the tags for these terminals for disambiguation.

  2. 终端有时可以用作字符串文本。Terminals can sometimes be used as string literals. 但是,这种用法可能与语言定义冲突,或者会产生意外后果。However, such usage may conflict with the language definition or have unintended consequences. 不建议使用这种用法。This kind of usage is not recommended.

  3. 规则操作无法对声明值执行任何类型转换,并且包含此类规则操作的规则集被视为无效。The rule action cannot perform any type conversions on claim Values, and a rule set that contains such a rule action is considered invalid. 这将导致运行时错误,并且不生成任何输出声明。This would cause a runtime error, and no output claims are produced.

  4. 如果规则操作引用规则的 "选择条件" 列表部分中未使用的标识符,则该标识符无效。If a rule action refers to an Identifier that was not used in the Select Condition List portion of the rule, it is an invalid usage. 这会导致语法错误。This would cause a syntax error.

    示例:错误的标识符引用以下规则说明了规则操作中使用的错误标识符。Example: Incorrect Identifier reference The following rule illustrates an incorrect Identifier used in rule action.

    C1:[] => Issue (claim = C2);

示例转换规则Sample transformation rules

  • 允许特定类型的所有声明Allow all claims of a certain type

    精确类型Exact type

    C1:[type=="XYZ"] => Issue (claim = C1);

    使用 RegexUsing Regex

    C1: [type =~ "XYZ*"] => Issue (claim = C1);
  • 禁止某个声明类型精确类型Disallow a certain claim type Exact type

    C1:[type != "XYZ"] => Issue (claim=C1);

    使用 RegexUsing Regex

    C1:[Type !~ "XYZ?"] => Issue (claim=C1);

规则分析器错误示例Examples of rules parser errors

声明转换规则由自定义分析器进行分析,以检查是否存在语法错误。Claims transformation rules are parsed by a custom parser to check for syntax errors. 在 Active Directory 中存储规则之前,此分析器由相关的 Windows PowerShell cmdlet 来运行。This parser is run by related Windows PowerShell cmdlets before storing rules in Active Directory. 分析规则(包括语法错误)中的任何错误都将打印在控制台上。Any errors in parsing the rules, including syntax errors, are printed on the console. 域控制器还会在使用用于转换声明的规则之前运行分析器,并在事件日志中记录错误 (将事件日志号添加) 。Domain controllers also run the parser before using the rules for transforming claims, and they log errors in the event log (add event log numbers).

本部分说明了使用不正确的语法编写的规则以及分析器生成的相应语法错误的一些示例。This section illustrates some examples of rules that are written with incorrect syntax and the corresponding syntax errors that are generated by the parser.

  1. 示例:Example:


    此示例使用分号代替了冒号。This example has an incorrectly used semicolon in place of a colon. 错误消息: POLICY0002:无法分析策略数据。 行号:1,列号:2,错误令牌:;。行: ' c1;[] =>发出 (声明为 c1) ; "。 分析器错误: "POLICY0030:语法错误,意外的"; 应为以下其中一项: ":"。 "Error message: POLICY0002: Could not parse policy data. Line number: 1, Column number: 2, Error token: ;. Line: 'c1;[]=>Issue(claim=c1);'. Parser error: 'POLICY0030: Syntax error, unexpected ';', expecting one of the following: ':' .'

  2. 示例:Example:


    在此示例中,复制颁发语句中的标识符标记是不确定的。In this example, the Identifier tag in the copy issuance statement is undefined. 错误消息POLICY0011:声明规则中的条件与 CopyIssuanceStatement 中指定的条件标记不匹配: "c2"。Error message: POLICY0011: No conditions in the claim rule match the condition tag specified in the CopyIssuanceStatement: 'c2'.

  3. 示例:Example:

    c1:[type=="x1", value=="1", valuetype=="bool"]=>Issue(claim=c1)

    "bool" 不是语言的终端,它不是有效的 ValueType。"bool" is not a Terminal in the language, and it is not a valid ValueType. 以下错误消息中列出了有效的终端。Valid terminals are listed in the following error message. 错误消息: POLICY0002:无法分析策略数据。Error message: POLICY0002: Could not parse policy data. 行号:1,列号:39,错误标记: "bool"。Line number: 1, Column number: 39, Error token: "bool". 行: "c1: [type = =" x1 ",值 = =" 1 ",valuetype = =" bool "] =>发出 (声明 = c1) ;"。Line: 'c1:[type=="x1", value=="1",valuetype=="bool"]=>Issue(claim=c1);'. 分析器错误: "POLICY0030:语法错误,意外的" STRING ",应为以下其中一项:" INT64_TYPE "" UINT64_TYPE "" STRING_TYPE "" BOOLEAN_TYPE "" 标识符 "Parser error: 'POLICY0030: Syntax error, unexpected 'STRING', expecting one of the following: 'INT64_TYPE' 'UINT64_TYPE' 'STRING_TYPE' 'BOOLEAN_TYPE' 'IDENTIFIER'

  4. 示例:Example:

    c1:[type=="x1", value==1, valuetype=="boolean"]=>Issue(claim=c1);

    在此示例中,数字1不是语言中的有效令牌,并且不允许在匹配条件中使用此类。The numeral 1 in this example is not a valid token in the language, and such usage is not allowed in a matching condition. 必须用双引号引起来,使其成为字符串。It has to be enclosed in double quotes to make it a string. 错误消息: POLICY0002:无法分析策略数据。 行号:1,列号:23,错误标记:1。行: ' c1: [type = = "x1",值 = = 1,valuetype = = "bool"] =>问题 (声明 = c1) ; '。分析器错误: "POLICY0029:意外的输入。Error message: POLICY0002: Could not parse policy data. Line number: 1, Column number: 23, Error token: 1. Line: 'c1:[type=="x1", value==1, valuetype=="bool"]=>Issue(claim=c1);'.Parser error: 'POLICY0029: Unexpected input.

  5. 示例:Example:

    c1:[type == "x1", value == "1", valuetype == "boolean"] =>
         Issue(type = c1.type, value="0", valuetype == "boolean");

    此示例使用了双等号 (= =) ,而不是使用单个等号 (=) 。This example used a double equal sign (==) instead of a single equal sign (=). 错误消息: POLICY0002:无法分析策略数据。 行号:1,列号:91,错误标记: = =。行: "c1: [type = =" x1 ",值 = =" 1 ", valuetype = =" boolean "] =>问题 (类型 = c1。 type,value =" 0 ",valuetype = =" boolean ") ;"。 分析器错误: "POLICY0030:语法错误,意外的" = = ",应为以下之一:" = "Error message: POLICY0002: Could not parse policy data. Line number: 1, Column number: 91, Error token: ==. Line: 'c1:[type=="x1", value=="1", valuetype=="boolean"]=>Issue(type=c1.type, value="0", valuetype=="boolean");'. Parser error: 'POLICY0030: Syntax error, unexpected '==', expecting one of the following: '='

  6. 示例:Example:

    c1:[type=="x1", value=="boolean", valuetype=="string"] =>
          Issue(type=c1.type, value=c1.value, valuetype = "string");

    此示例在语法和语义上是正确的。This example is syntactically and semantically correct. 然而,使用 "boolean" 作为字符串值会导致混淆,应避免此问题。However, using "boolean" as a string value is bound to cause confusion, and it should be avoided. 如前文所述,应尽可能避免使用语言终端作为声明值。As previously mentioned, using language terminals as claims values should be avoided where possible.

语言终端Language terminals

下表列出了在声明转换规则语言中使用的一组完整的终端字符串和关联的语言终端。The following table lists the complete set of terminal strings and the associated language terminals that are used in the claims transformation rules language. 这些定义使用不区分大小写的 UTF-16 字符串。These definitions use case-insensitive UTF-16 strings.

字符串String 终端Terminal
"=>""=>" 隐含IMPLY
";"";" 之间SEMICOLON
":"":" 开头COLON
",""," COMMA
".""." 着重号DOT
"==""==" EQEQ
"!=""!=" NEQNEQ
"=""=" ASSIGN
"&&""&&" ANDAND
本期"issue" 问题ISSUE
类别"type" TYPETYPE
负值"value" VALUE
valuetype"valuetype" VALUE_TYPEVALUE_TYPE
提及"claim" 提及CLAIM
"[_A Za-z] [_A-a-za-z0-9] *""[_A-Za-z][_A-Za-z0-9]*" IDENTIFIERIDENTIFIER
"" \ [^ \ "\n] * \ " ""\"[^\"\n]*\"" STRINGSTRING
uint64"uint64" UINT64_TYPEUINT64_TYPE
int64"int64" INT64_TYPEINT64_TYPE

语言语法Language syntax

以下声明转换规则语言是在 ABNF 窗体中指定的。The following claims transformation rules language is specified in ABNF form. 除了在此处定义的 ABNF 生产外,此定义还使用上表中指定的终端。This definition uses the terminals that are specified in the previous table in addition to the ABNF productions defined here. 规则必须以 UTF-16 编码,并且必须将字符串比较视为不区分大小写。The rules must be encoded in UTF-16, and the string comparisons must be treated as case insensitive.

Rule_set        = ;/*Empty*/
             / Rules
Rules         = Rule
             / Rule Rules
Rule          = Rule_body
Rule_body       = (Conditions IMPLY Rule_action SEMICOLON)
Conditions       = ;/*Empty*/
             / Sel_condition_list
Sel_condition_list   = Sel_condition
             / (Sel_condition_list AND Sel_condition)
Sel_condition     = Sel_condition_body
             / (IDENTIFIER COLON Sel_condition_body)
Sel_condition_body   = O_SQ_BRACKET Opt_cond_list C_SQ_BRACKET
Opt_cond_list     = /*Empty*/
             / Cond_list
Cond_list       = Cond
             / (Cond_list COMMA Cond)
Cond          = Value_cond
             / Type_cond
Type_cond       = TYPE Cond_oper Literal_expr
Value_cond       = (Val_cond COMMA Val_type_cond)
             /(Val_type_cond COMMA Val_cond)
Val_cond        = VALUE Cond_oper Literal_expr
Val_type_cond     = VALUE_TYPE Cond_oper Value_type_literal
claim_prop       = TYPE
             / VALUE
Cond_oper       = EQ
             / NEQ
             / REGEXP_MATCH
             / REGEXP_NOT_MATCH
Literal_expr      = Literal
             / Value_type_literal

Expr          = Literal
             / Value_type_expr
             / (IDENTIFIER DOT claim_prop)
Value_type_expr    = Value_type_literal
Value_type_literal   = INT64_TYPE
             / UINT64_TYPE
             / STRING_TYPE
             / BOOLEAN_TYPE
Literal        = STRING
Rule_action      = ISSUE O_BRACKET Issue_params C_BRACKET
Issue_params      = claim_copy
             / claim_new
claim_copy       = CLAIM ASSIGN IDENTIFIER
claim_new       = claim_prop_assign_list
claim_prop_assign_list = (claim_value_assign COMMA claim_type_assign)
             /(claim_type_assign COMMA claim_value_assign)
claim_value_assign   = (claim_val_assign COMMA claim_val_type_assign)
             /(claim_val_type_assign COMMA claim_val_assign)
claim_val_assign    = VALUE ASSIGN Expr
claim_val_type_assign = VALUE_TYPE ASSIGN Value_type_expr
Claim_type_assign   = TYPE ASSIGN Expr