projectcapsule / capsule

Multi-tenancy and policy-based framework for Kubernetes.
https://projectcapsule.dev/
Apache License 2.0
1.63k stars 157 forks source link

Dedicated PodSecurityPolicy per Tenant #52

Closed bsctl closed 4 years ago

bsctl commented 4 years ago

Describe the feature

It would be nice to let the cluster admin to set a dedicated Pod Security Policy (PSP) per tenant. This is likely to be a requirement in a multi-tenancy environment.

A PSP is defined at cluster scope. To assign the PSP to users/serviceaccounts in a tenant we can use RoleBindings for each namespace created in the tenant. The Capsule should enforce the creation of RoleBinding assigning the PSP.

What would the new user story look like?

  1. The cluster admin creates a PSP for a given tenant:
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: psp:restricted
spec:
  privileged: false
  # Required to prevent escalations to root.
  allowPrivilegeEscalation: false
  ...
  1. then creates a ClusterRole to assign the PSP
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp:restricted
rules:
- apiGroups:
  - extensions
  resources:
  - podsecuritypolicies
  resourceNames:
  - restricted # the psp we are giving access to
  verbs:
  - use
  1. the cluster admin assign such PSP to the tenant:
  apiVersion: capsule.clastix.io/v1alpha1
  kind: Tenant
  metadata:
      name: oil
  spec:
    podSecurityPolicies:
    - psp:restricted
 ...

Expected behavior

For each namespace created into the tenant, the Capsule controller creates a RoleBinding assigning the PSP to all the services accounts in such namespace:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: psp:restricted
  namespace:
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: psp:restricted
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:serviceaccounts
prometherion commented 4 years ago

@bsctl do we still need discussion or any priority to assign here?

bsctl commented 4 years ago

Definitely a requirement for a strong multi tenancy environment. Also needed by #65. Anyway not a current request from our early adopters, so we can postpone to the next release.

gdurifw commented 4 years ago

@bsctl , @prometherion i would like to provide to our customers a specific PSP for own Tenant in a K8s Cluster with Capsule and i think that this feature would be perfect for our purpose. Is there already a schedule for the implementation of this feature? How can I contribute?

prometherion commented 4 years ago

Thanks for your feedback @gdurifw, really appreciated: having feedbacks and offering help for feature requests is always good!

This specific one looks fuzzy to me, right now: we all know that PSPs aren't yet a graduated v1 API but it seems they're going to be deprecated, although starting from the community.

Rather than this, I think we should start seriously thinking about this enhancement proposal: Make Capsule admission controller programmable.

This could provide more flexibility rather than PSP and a higher layer of additional business logic that could be designed by the Cluster Administrator, and could be an amazing feature and enhancement, even that would add an additional resource as a direct dependency (Gatekeeper/OPA).

Feedback from the early adopters and the community here would be great: @MaxFedotov, please, any thoughts about this?

bsctl commented 4 years ago

@prometherion as #51 is a long term evolution, we should consider #52 as short term solution to address this requirement. Although PSP is going to be deprecated in favor of OPA, it is still widely used. And deprecation seems only in Azure AKS.

d-m commented 4 years ago

This will be useful for me as well. If tying this closely to PodSecurityPolicy resources is a concern due to its potential deprecation, would it make more sense to look at this as a generic RoleBinding feature?

For example,

instead of

  apiVersion: capsule.clastix.io/v1alpha1
  kind: Tenant
  metadata:
      name: oil
  spec:
    podSecurityPolicies:
    - psp:restricted
  ...

it could be

  apiVersion: capsule.clastix.io/v1alpha1
  kind: Tenant
  metadata:
      name: oil
  spec:
    roleBindings:
    - roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: psp:restricted
      subjects:
      - apiGroup: rbac.authorization.k8s.io
        kind: Group
        name: system:serviceaccounts
 ...

This would also be consistent with with the pattern established by the networkPolicies, limitRanges, and resourceQuotas Tenant options.

prometherion commented 4 years ago

thanks for your point @d-m: I'm thinking of a similar approach, like the following:

additionalRoleBindings:
  role-name: psp:restricted
  subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: Group
      name: system:serviceaccounts

The idea is to use the key as the value of the Cluster Role we'd like to apply all over the Tenant's Namespaces, giving the change to personalize the subjects.

I think we can avoid the roleRef since we're expecting to assign always a ClusterRole for the said API Group (rbac.authorization.k8s.io).

@bsctl @MaxFedotov @d-m WDYT?