我们如何限制服务帐户只能创建、列出、删除等在给定命名空间内具有特定标签的对象?
我们设计了一个服务层次结构(映射到 Kubernetes 命名空间)和组件层次结构(由persona
各种对象上的标签表示),并将其与 vault 集成,以便您可以访问的机密特定于服务组件对。这有助于隔离事物。例如,想象一个管理大量部署的团队,其中只有一些部署处理 PII 数据。我们可以使用该标签有选择地授予对这些机密的访问权限。
# only approximatively k8s objects
---
kind: Deployment
metadata:
name: backend
namespace: banana
labels:
persona: backend
spec: ...
# pods in this deployment have access to banana§backend secrets via a vault sidecar
---
kind: Deployment
metadata:
name: frontend
labels:
persona: frontend
spec: ...
# pods in this deployment have access to banana§frontend secrets via a vault sidecar
然而,这意味着我们不想仅仅创建一个可以管理全部该命名空间中的 pod — 如果该服务帐户的机密被泄露,攻击者可以使用它来启动带有恶意映像的 pod 并访问 PII。
所以我想要类似的东西:(请注意,我对服务帐户、角色和角色绑定的了解极其有限)
# even more approximatively so k8s objects
kind: Role
metadata:
name: deploy-frontend
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
selector:
labels:
persona: frontend
# even if compromised, this service account cannot access banana§backend secrets
好像是 k8s可能支持类似这样的模糊内容,例如通过提供特定资源名称的列表(#),但这不是 k8s 目前所支持的东西?还是我遗漏了什么?
我们唯一的选择是设置一个具有广泛访问权限的集群范围的服务帐户,然后在使用令牌之前启动一个执行自己的自定义身份验证和授权例程的 Web 服务吗?如果是这样,我们如何尽可能地限制这个“上帝帐户”的范围?
答案1
Kubernetes 没有办法限制列表动词逐个对象。如果你能列出一个集合,你就能读取该集合中的所有对象。
也许有一天这种情况会改变,但现在 Kubernetes 在集合和读取访问方面的工作方式就是这样的。这包括对 Secrets 的读取访问……
但是,如果你想限制写道到对象,你可以这样做。你可以使用以下方法限制写入特定命名对象的能力:
- 外部验证准入 webhook
- (测试版)ValidatingAdmissionPolicy
- 授权 webhook
或使用精心制定的 RBAC 规则。
可能有助于您管理访问权限的是分层命名空间控制器,允许团队管理放每个命名空间都有自己的限制。如果您的集群支持 ValidatingAdmissionPolicies,您可以使用它们来进一步委派访问权限和限制写入访问权限(尽管这是一个相当复杂的话题)。
如果您想要一个可以执行操作但委托控制这些操作的 ServiceAccount,您可以在每个目标命名空间中使用 RoleBinding 创建 ServiceAccount,然后允许整体 ServiceAccount 模拟特定的 ServiceAccount。同样,这是一个相当复杂的事情,但这是可能的。