简体   繁体   English

OPA 中 kubernetes.admission 政策之间的隔离

[英]Isolation between kubernetes.admission policies in OPA

I use the vanilla Open Policy Agent as a deployment on Kubernetes for handling admission webhooks.我使用 vanilla Open Policy Agent 作为 Kubernetes 上的部署来处理准入 webhook。

The behavior of multiple policies evaluation is not clear to me, see this example:我不清楚多策略评估的行为,请参见以下示例:

## 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"
]

It seems that all of my policies are being evaluated as just one flat file, but i would expect that each policy will be evaluated independently from the others似乎我的所有政策都被评估为一个平面文件,但我希望每项政策都将独立于其他政策进行评估

What am I missing here?我在这里想念什么?

Files don't really mean anything to OPA, but packages do.文件对 OPA 没有任何意义,但包有。 Since both of your policies are defined in the kubernetes.admission module, they'll essentially be appended together as one.由于您的两个策略都在kubernetes.admission模块中定义,因此它们基本上将作为一个附加在一起。 This works in your case only due to one of the check_user and check_namespace respectively evaluating to undefined given your input.这仅适用于您的情况,因为根据您的输入, check_usercheck_namespace分别评估为 undefined 。 If they hadn't you would see an error message about conflict, since complete rules can't evalutate to different results (ie allow can't be both true and false ).如果他们没有,您将看到有关冲突的错误消息,因为完整的规则无法评估不同的结果(即allow不能同时为truefalse )。

If you rather use a separate package per policy, like, say kubernetes.admission.policy1 and kubernetes.admission.policy2 , this would not be a concern.如果您更愿意为每个政策使用单独的 package,例如kubernetes.admission.policy1kubernetes.admission.policy2 ,这不会是一个问题。 You'd need to update your main policy to collect an aggregate of the allow rules from all of your policies though.不过,您需要更新您的主要策略以从您的所有策略中收集allow规则的聚合。 Something like:就像是:

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

This would iterate over all the sub-packages in kubernetes.admission and collect the allow rule result from each.这将遍历kubernetes.admission中的所有子包,并从每个子包中收集allow规则结果。 This pattern is called dynamic policy composition, and I wrote a longer text on the topic here .这种模式称为动态策略组合,我在 这里写了一篇关于该主题的较长文本。

(As a side note, you probably want to aggregate deny rules rather than allow. As far as I know, clients like kubectl won't print out the reason from the response unless it's actually denied... and it's generally less useful to know why something succeeded rather than failed. You'll still have the OPA decision logs to consult if you want to know more about why a request succeeded or failed later). (作为旁注,您可能想要聚合拒绝规则而不是允许。据我所知,像 kubectl 这样的客户端不会从响应中打印出原因,除非它实际上被拒绝了......而且知道它通常不太有用为什么某事成功而不是失败。如果您想了解更多有关请求成功或失败的原因,您仍然可以查阅 OPA 决策日志)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM