eval - 开放策略代理 - CI 管道中的显式逻辑与
问题描述
我正在尝试编写一个管理管理员用户名兼容性的策略,该策略由三个规则组成:字母数字值,不是不允许的名称(管理员、管理员等)的一部分,以及超过 5 个字符。
我发现当使用 OPA 作为 CI 管道(这是我的用例)的一部分时,最舒适的解决方案是创建一个包含策略结果的对象(字典),以便我可以直接查询它们。我在 CI 管道中的行将如下所示:
for file in rego_directory:
opa eval -i file -d data.json "package_name.policy"
它不会打印我在 rego 文件中使用的所有变量和临时资源(这会节省大量日志和输出)。为了制作这个“策略”对象,我在我的 rego 文件中有以下模式:
policy[policy_name] = result {
policy_name :=
...
computations...
...
result := <logical condition>
}
现在,我的问题如下:这对我来说似乎不是最佳实践。有没有另一种方法可以简单地从输出中省略变量?以前我使用过单独的值(即像这样:
default policy_1 = false
default policy_2 = false
policy_1 = {
<logical condition>
}
policy_2 = {
<logical condition>
}
第二个问题:如何创建一个可以满足多个条件的输出字典(毕竟字典的 JSON 输出是一种很好的格式)?回顾我的例子,我不能写这样的东西:
policy[policy_name] = result {
policy_name :=
...
computations...
...
result := <logical condition>
result := <logical condition 2>
}
由于这是双重分配,这是无效的。即使我使用=
而不是:=
,如果一个术语为真而另一个为假,它也会产生冲突,并且错误不是我要寻找的(我需要布尔答案)。我如何创建一个复杂的规则,我可以把它的输出放在这个字典中?
提前致谢。
解决方案
TLDR;明确回答您的问题:
现在,我的问题如下:这对我来说似乎不是最佳实践。有没有另一种方法可以简单地从输出中省略变量?
让您的软件查询某些规则生成的值没有任何问题。事实上,规则是在策略中定义抽象的基本方式,这样您就可以将策略决策(即产生决策的逻辑)与策略执行(即基于策略决策所采取的逻辑/行动)分离。 )
唯一真正的选择是在一个或多个包中查询一组规则,就像你展示的那样。
第二个问题:如何创建一个可以满足多个条件的输出字典(毕竟字典的 JSON 输出是一种很好的格式)?回顾我的例子,我不能写这样的东西:
您在问如何表达逻辑 OR。在这种情况下,您将创建policy
规则的多个定义(我们在某些地方称它们为“增量定义”):
policy[policy_name] = result {
policy_name :=
...
computations...
...
result := <logical condition>
}
policy[policy_name2] = result2 {
policy_name2 :=
...
some other computations...
...
result2 := <some other logical condition>
}
policy
此代码段定义了一个映射policy_name
到result
和policy_name2
的对象(名为) result2
。我们称这种规则为Partial Object。您还可以定义部分集。当你定义一个 Partial Object 时,你需要确保每个键映射到最多一个值(否则你会得到一个运行时错误。)
构建策略的另一种方法是(基本上)使用部分集定义拒绝列表:
package usernames
deny["username must use alphanumeric characters"] {
re_match("[a-zA-Z0-9]", input.username)
}
deny["username must be at least 5 characters long"] {
count(input.username) < 5
}
deny["username is reserved"] {
reserved_usernames[input.username]
}
reserved_usernames := {"admin", "root"}
然后您的 CI 管道可以简单地查询deny
:
opa eval -i input.json 'data.usernames.deny'
结果将包含不应允许该用户名的原因。
推荐阅读
- c# - ASP.Net FileUpload:如果已经存在,则在保存之前重命名文件名
- java - 如何将动态添加的文本框传递给spring MVC控制器java
- javascript - 带有指向其他对象的链接的对象映射
- python - Gmail API - 使用“原始”输出查看奇怪的德语字符并解码为 utf-8
- javascript - 在所有具有 HTML、CSS 和 Js 的屏幕类型中,如何使 div 保持在特定元素旁边?
- android - 禁用 Android 中所有应用的分屏模式
- java - 用mybatis + spring配置连接池
- php - 找不到脚本“D:/xampp/htdocs/wp-login.php”或无法统计
- javascript - 而不是 document.write,输出 id/class 的 div
- spring - Spring Autowiring 错误:java.lang.IllegalStateException:方法 [名称] 只能包含 1 个方法字段。找到:[PUT,POST]