capsule icon indicating copy to clipboard operation
capsule copied to clipboard

feat: Allow subjects to act as Owner to bypass the webhook

Open KristianTrifork opened this issue 1 year ago • 10 comments

As a group of us have been discussing here: https://github.com/projectcapsule/capsule/discussions/1311

This feature adds a new flag in additionalRoleBindings which allows the subject to actAsOwner. When a namespace is created, Capsule checks if the requester is owner of the Tenant, or if the Tenant has the actAsOwner flag set to true. If so, the requester is allowed to create the namespace.

Here is a the Tenant used for testing:

apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: oil
spec:
  owners:
  - name: alice
    kind: User
  - name: system:serviceaccount:tenant-system:tenant-gitops
    kind: ServiceAccount
  additionalRoleBindings:
    - clusterRoleName: admin
      actAsOwner: true # This is how the code is made in this PR
      subjects:
        - name: tenant-gitops
          kind: ServiceAccount

While this PR was being developed, we had a talk about what actAsOwner means. And where it should be. In the discussion we aired a few places, and talked about the differences between them.

We believe the name and placement, should reflect what a delveoper would expect it to do. And so we came up with a new idea, which would fit more in with the default of how the owners field works. I'll paste a yaml example of how it could look like:

apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: oil
spec:
  owners:
  - name: alice
    kind: User
  - name: system:serviceaccount:tenant-system:tenant-gitops
    kind: ServiceAccount
  additionalRoleBindings:
    - clusterRoleName: admin
      subjects:
        - name: tenant-gitops
          kind: ServiceAccount
  nameSpaceProvisioner: # This is the new field
    subjects:
        - name: tenant-gitops
          kind: ServiceAccount
          clusterRoleName: admin # If this is not set, it could default to a role simmilar to `capsule-namespace-provisioner`

The pros of the solution as it is this PR, the flag would be set, in the same place as the rolebindings are set. The also means if the role giving does not have the RBAC to create a namespace, it would not be able to create a namespace.

In the second solution, the nameSpaceProvisioner would be a new field, which would be a list of subjects, which would be allowed to create namespaces. This would match how owners works, and would be more intuitive for a developer to understand.

I would like to hear your thoughts on this, and if you have any other ideas on how to implement this feature. The PR is set to WIP, as I still don't think we have settled on the best solution. And I think it's better to talk from code.

KristianTrifork avatar Jan 24 '25 19:01 KristianTrifork

Deploy Preview for capsule-documentation ready!

Name Link
Latest commit a587ce62975492ddc1145ff7e4e13ef222a3de99
Latest deploy log https://app.netlify.com/sites/capsule-documentation/deploys/679883af37a57600081d2663
Deploy Preview https://deploy-preview-1332--capsule-documentation.netlify.app
Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

netlify[bot] avatar Jan 24 '25 19:01 netlify[bot]

@prometherion @maxgio92 @oliverbaehler

I've made a PR. My first time around Go and kubernetes operators. So I might need some pointers.

But I think it's easier if we have some code to talk from. And we had a busy week, so we didn't want it to run out in the sand. But I'd like to hear your thoughts.

KristianTrifork avatar Jan 24 '25 19:01 KristianTrifork

I have time on the weekend to draft my proposal, thanks for your initial code

oliverbaehler avatar Jan 27 '25 16:01 oliverbaehler

Is more required on my end before I could get feedback on this? :) I will make sure workflows work, but I am unsure if the current implementation is working as we discussed.

KristianTrifork avatar Feb 21 '25 13:02 KristianTrifork

@oliverbaehler Hey.

Do you need anything more from me?

KristianTrifork avatar Mar 11 '25 14:03 KristianTrifork

@oliverbaehler hey, have you had time to look at this? We (me @KristianTrifork and a few others) are very interested in some variation of this contribution to ensure our tenants have a nice experience with Capsule.

devantler avatar May 08 '25 09:05 devantler

Hey sorry for being unresponsive.

Alright so this is surely a feature we want to have in our next release, but i would rather take the approach of designing a new stable api and combining CRBs and CRs.

For me the api should look like this:

apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: oil
spec:
  owners:
  - name: alice
    kind: User
  - name: system:serviceaccount:tenant-system:tenant-gitops
    kind: ServiceAccount
  permissions:
    - clusterRoles: 
       - admin
       clusterRoleBindings:
       - capsule-namespace-editor
      subjects:
        - name: tenant-gitops
          kind: ServiceAccount
          actAsOwner: true

Let's create a new API block called permissions. We then track for each subject, if it can actAsOwner. In the same Context we add the clusterRoles assigned to the subjects + define ClusterRoleBindings where the subjects are synced to.

So the question is, do you need help with this?

oliverbaehler avatar May 09 '25 04:05 oliverbaehler

Hey sorry for being unresponsive.

Alright so this is surely a feature we want to have in our next release, but i would rather take the approach of designing a new stable api and combining CRBs and CRs.

For me the api should look like this:

apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: oil
spec:
  owners:
  - name: alice
    kind: User
  - name: system:serviceaccount:tenant-system:tenant-gitops
    kind: ServiceAccount
  permissions:
    - clusterRoles: 
       - admin
       clusterRoleBindings:
       - capsule-namespace-editor
      subjects:
        - name: tenant-gitops
          kind: ServiceAccount
          actAsOwner: true

Let's create a new API block called permissions. We then track for each subject, if it can actAsOwner. In the same Context we add the clusterRoles assigned to the subjects + define ClusterRoleBindings where the subjects are synced to.

So the question is, do you need help with this?

@oliverbaehler

As I understand this change, it is because currently Capsule will create rolebindings for the clusterRoles if we use the additionalRoleBinding, and with the new change it can create clusterRolesBindings to clusterRoles?

Under the permissions field, as I read it:

  • clusterRoles is a list of clusterRoles the subject should have a roleBinding to, in each namespace in the tenant.
  • clusterRoleBindings is a list of CRBs the subject should be added to.
  • subjects.ActAsOwner is a bool, for the webhook to check when the subject tries to create a new namespace in that tenant.

At least, I feel with the new API block, it should be possible to keep the old funtionality, of having Capsule create the roleBindings in each tenant namespace, but I do really like the addition of having Capsule controle CRBs too.

We'll discuss it in the team if it's something we can assign time to. If not, I am personally quite invested in Capsule, and would like to give it a crack.

But I would love to clarify the funtionallity of permissions first.

KristianTrifork avatar May 09 '25 08:05 KristianTrifork

Yeah you nailed, for me it's mainly important the subjects are the focus of the new config block.

  • clusterRoles = existing functionality from additionalClusterRoles, but use subjects
  • clusterRoleBindings = bind subjects to given CRBs. In case of Serviceaccounts, add namespaced SA
  • subjects = list of users or whatever
    • subjects.ActAsOwner is a bool, for the webhook to check when the subject tries to create a new namespace in that tenant. Default is false.
  • namespaceSelector = select only a subset of namespaces in the tenant to distribute the rbac to

I was even thinking about making a dedicated CRD for Subjects and then just creating selectors from owners or permissions, but that doesn't really add much more benefits.

Since the permissions block is in the context of a tenant's namespaces, i think it would also make sense to add subselectors, so we can grant permissions to a subset of namespaces, so that we can cover a bit more complex compliance scenarios, eg:

  permissions:
   - clusterRoles: 
      - read-only
     subjects:
       - name: operators
         kind: Group
     namespaceSelector:
        matchExpressions:
         - key: environment
           operator: NotIn
           values: ["prod"]

Not part of this PR

My final goal is to also allowing tenant owners to configure these permissions, not directly on the tenant CR, eg.

apiVersion: capsule.clastix.io/v1beta2
kind: TenantPermission
metadata:
 name: solar
 namespace: solar-system
spec:
   clusterRoles: 
      - read-only
   subjects:
       - name: operators
         kind: Group
   namespaceSelector:
        matchExpressions:
         - key: environment
           operator: NotIn
           values: ["prod"]

WDYT.

Btw. we are still looking for maintainers #1363

oliverbaehler avatar May 09 '25 09:05 oliverbaehler

@oliverbaehler Using my private Github account, as I might have to work on this privately. I have been looking into merging the two accounts somehow.

Anyhow. I do like the change, currently I am actually kinda have a little "problem", that some of the tools we're using require permissions on cluster scope, but Capsule only create the rolebinding. So that would be an awesome change.

Also, just adding the actAsOwner field, really only solve one thing. It kinda felt like a bandaid fix to the multi-tanacy problems, where this change feels like it it really adds new features to give a more complete controle of multi-tanacy to Capsule.

For your final goal, I do like the idea, I view Capsule as a way of allowing the Tenants to be "cluster-admins" within the our namespaces. I have thought about a way of giving tenants the ability to "update" the tenant resource, like adding more users to it, but still limit it such that the full admin control is still in the hands of the actual cluster admins.

I'll look into implementing the permissions block to the Tenant resource, so we can discuss the best way to do it.

niuxe avatar May 09 '25 16:05 niuxe

This pull request has been marked as stale because it has been inactive for more than 30 days. Please update this pull request or it will be automatically closed in 30 days.

github-actions[bot] avatar Jun 22 '25 00:06 github-actions[bot]