【问题标题】:Isolation between kubernetes.admission policies in OPAOPA 中 kubernetes.admission 策略之间的隔离
【发布时间】:2022-01-02 03:05:30
【问题描述】:

我使用 vanilla Open Policy Agent 作为 Kubernetes 上的部署来处理准入 webhook。

我不清楚多策略评估的行为,请看这个例子:

## policy-1.rego

package kubernetes.admission

check_namespace {
   # evaluate to true
   namespaces := {"namespace1"}
   namespaces[input.request.namespace]
}

check_user {
    # evaluate to false
    users := {"user1"}
    users[input.request.userInfo.username]
}

allow["yes - user1 and namespace1"] {
  check_namespace
  check_user
}

.

## policy-2.rego

package kubernetes.admission

check_namespace {
   # evaluate to false
   namespaces := {"namespace2"}
   namespaces[input.request.namespace]
}

check_user {
    # evaluate to true
    users := {"user2"}
    users[input.request.userInfo.username]
}

allow["yes - user2 and namespace12] {
  check_namespace
  check_user
}

.

## main.rego

package system

import data.kubernetes.admission

main = {
  "apiVersion": "admission.k8s.io/v1",
  "kind": "AdmissionReview",
  "response": response,
}

default uid = ""

uid = input.request.uid

response = {
    "allowed": true,
    "uid": uid,
} {
    reason = concat(", ", admission.allow)
    reason != ""
}
else = {"allowed": false, "uid": uid}

.

 ## example input
{
  "apiVersion": "admission.k8s.io/v1beta1",
  "kind": "AdmissionReview",
  "request": {
    "namespace": "namespace1",
    "userInfo": {
        "username": "user2"
    }
  }
}

.

## Results

"allow": [
    "yes - user1 and namespace1",
    "yes - user2 and namespace2"
]

似乎我的所有政策都被评估为一个平面文件,但我希望每个政策都将独立于其他政策进行评估

我在这里错过了什么?

【问题讨论】:

  • 我猜是因为您导入了这两个策略并且它们共享名称允许。由于名称是共享的,因此它最终成为一个允许结果。

标签: kubernetes opa open-policy-agent


【解决方案1】:

文件 对 OPA 没有任何意义,但包确实如此。由于您的两个策略都在kubernetes.admission 模块中定义,因此它们基本上将作为一个附加在一起。这仅适用于您的情况,因为 check_usercheck_namespace 之一根据您的输入分别评估为未定义。如果他们没有,您会看到有关冲突的错误消息,因为完整的规则无法评估不同的结果(即allow 不能同时是true false)。

如果您宁愿为每个策略使用单独的包,例如 kubernetes.admission.policy1kubernetes.admission.policy2,则无需担心。不过,您需要更新您的主要策略以从所有策略中收集 allow 规则的集合。比如:

reason = concat(", ", [a | a := data.kubernetes.admission[policy].allow[_]])

这将遍历kubernetes.admission 中的所有子包,并从每个子包中收集allow 规则结果。这种模式被称为动态策略组合,我在here这个话题上写了一篇较长的文字。

(作为旁注,您可能想要聚合 deny 规则而不是允许。据我所知,像 kubectl 这样的客户端不会从响应中打印出原因,除非它实际上被拒绝...而且知道为什么某事成功而不是失败通常不太有用。如果您想了解更多有关请求成功或失败的原因,您仍然可以咨询 OPA decision logs

【讨论】:

  • 好帖子!非常有用的东西。至于你的旁注,同意,我只是举个例子:)
猜你喜欢
  • 2021-05-25
  • 2016-04-03
  • 2022-10-22
  • 1970-01-01
  • 2022-08-24
  • 2021-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多