rbac-manager icon indicating copy to clipboard operation
rbac-manager copied to clipboard

Add dynamic service accounts in namespace matchLabel

Open cnelson opened this issue 5 years ago • 15 comments
trafficstars

When a namespace is created with a given label, I'd like to provision a service account in that namespace, and create rolebindings for it in other static namespaces

For example,

I have a static namespace named foo that always exists. Now when I create a new namespace with the label access: foo I'd like to

  • Automatically create a service account in the the newly created namespace
  • Create a rolebinding in the foo namespace that references this dynamically created account.

Is this possible?

cnelson avatar Jun 03 '20 20:06 cnelson

Yep, that is possible. Please take a look at https://github.com/FairwindsOps/rbac-manager#dynamic-namespaces-and-labels

In this case your subject will be a service account, but that example should get you going.

sudermanjr avatar Jun 04 '20 14:06 sudermanjr

@sudermanjr I'm not quite getting how to make this work. I've got a config that looks like this:

rbacBindings:
  - name: foo
    subjects:
      - kind: ServiceAccount
        name: some-name
    roleBindings:
      - clusterRole: admin
         namespace: foo
         namespaceSelector:
           matchLabels:
             access: foo

which leads to two issues:

  • I can't specify the namespace for the service account in question, because I don't know it (I want it to be in whatever namespace matches the namespace selector. Leaving it unset, causes this error in the logs: Error creating Service Account: an empty namespace may not be set during creation

  • Assuming there is a way to create the service account in this manner, It doesn't appear that I can use namespace: foo to attempt to create a rolebinding in that namespace, while also using the namespace selector to do this based on labels. I end up with a rolebinding in the namespace matching the selector, not in in the foo namespace.

Does this make sense? I'm happy to provide more detail if needed

cnelson avatar Jun 04 '20 20:06 cnelson

Hmmm. This is interesting.

I am fairly certain that even if you specify the namespace on the serviceAccount (which you have to, you are correct), that it will create the first SA in that namespace, and then create additional ones in each namespace for matchLabels.

This may be a flaw in the logic for namespace selector. I will need to test that out.

sudermanjr avatar Jun 04 '20 21:06 sudermanjr

Oh, and to create the label-matched bindings and the single-namespace binding, you'll need to specify multiple bindings, like so:

rbacBindings:
  - name: foo
    subjects:
      - kind: ServiceAccount
        name: some-name
        namespace: foo
    roleBindings:
      - clusterRole: admin
         namespaceSelector:
           matchLabels:
             access: foo
      - clusterRole: admin
         namespace: foo

I'm going to test that config on a local cluster here in a bit

sudermanjr avatar Jun 04 '20 21:06 sudermanjr

apiVersion: rbacmanager.reactiveops.io/v1beta1
kind: RBACDefinition
metadata:
  name: testing
rbacBindings:
  - name: foo
    subjects:
      - kind: ServiceAccount
        name: test-service-account
        namespace: foo
    roleBindings:
      - clusterRole: admin
        namespaceSelector:
          matchLabels:
            access: foo
      - clusterRole: admin
        namespace: foo
└─ k get sa -n foo
NAME                   SECRETS   AGE
default                1         54s
test-service-account   1         6s

└─ kubectl get rolebinding -n foo
NAME                ROLE                AGE
testing-foo-admin   ClusterRole/admin   13s

└─ kubectl create ns foo2
namespace/foo2 created
└─ k label ns foo2 access=foo
namespace/foo2 labeled

└─ k get sa -n foo2
NAME      SECRETS   AGE
default   1         88s

└─ k get rolebinding -n foo2
NAME                ROLE                AGE
testing-foo-admin   ClusterRole/admin   84s

On inspecting that rolebinding in foo2:

  subjects:
  - kind: ServiceAccount
    name: test-service-account
    namespace: foo

Looks like I was entirely wrong initially. Sorry about the confusion.

sudermanjr avatar Jun 04 '20 21:06 sudermanjr

This might be a good feature request, but I would have to look at the code to make sure.

sudermanjr avatar Jun 04 '20 21:06 sudermanjr

If this use case is a feature you'd accept, I could submit a PR for it, provided we figure out how this should actually work first :)

cnelson avatar Jun 05 '20 22:06 cnelson

@sudermanjr checking in on this? Thoughts on if this is a use case you'd want to support in this tool?

cnelson avatar Jul 10 '20 23:07 cnelson

Sorry for dropping this.

I think it is something we would be willing to support. I need to ask my fellow maintainers. I posed the question internally.

sudermanjr avatar Jul 13 '20 17:07 sudermanjr

Talked to @lucasreed and I think this is something we would accept a PR, but it will be a non-trivial amount of effort. Because of that, we probably won't be able to dedicate a large amount of time to it.

sudermanjr avatar Jul 13 '20 20:07 sudermanjr

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Oct 17 '20 20:10 stale[bot]

Was there any progress made on a PR for this?

I'm in a situation where I'd like to reduce friction for our developers. They are creating Argo workflows for ETL and we have each client process in its own namespace. I'd like to make this self-service for them, however, Argo requires elevated namespace privileges to manage the different pods it creates for each workflow step.

While I can submit workflows and specify a service account argo submit --serviceaccount <name>, AFAICT that service account must exist within the namespace where the workflows are created. If no sa is specified, it will use default.

I'd like for my devs to be able to create their namespace (along with other resources) from source control (Bitbucket pipelines in our case) and have rbac-manager automatically create the argo-bot service account and role binding within the namespace.

---
apiVersion: rbacmanager.reactiveops.io/v1beta1
kind: RBACDefinition
metadata:
  name: data-ops-default
  namespace: rbac-manager
rbacBindings:
  - name: argo-controller
    subjects:
      - kind: ServiceAccount
        name: argo-bot
    roleBindings:
      - clusterRole: admin
        namespaceSelector:
          matchLabels:
            workflows: argo
---
apiVersion: v1
kind: Namespace
metadata:
  labels:
    ci: edit
    workflows: argo
  name: data-ops-rbac-test

What is the LOE to accomplish something like this?

jjtroberts avatar Dec 30 '20 16:12 jjtroberts

@jjtroberts I don't believe any progress has been made on this. I definitely see the need for this, and it is something we would accept a PR for.

The one big consideration that I think will make this tricky to implement is backward compatibility. It's possible that we a new field to the CRD that is something along the lines of createSAInNamespace: <bool>. However, this means we would have a potentially breaking change to the CRD, which would require some careful consideration.

I believe the actual implementation would be relatively straightforward, but I haven't looked at adding this just yet.

sudermanjr avatar Dec 30 '20 17:12 sudermanjr

Understood, and thanks for the quick response. As tradeoff we'll probably allow developer PRs with required approval by our engineers into a central rbac repo. It doesn't get us away from having copies of similar definitions, but it would still be quicker than a ticket in a backlog.

jjtroberts avatar Dec 30 '20 17:12 jjtroberts

Makes sense. Thanks for all the feedback and info. I'll make sure we at least discuss this feature going forward.

sudermanjr avatar Dec 30 '20 18:12 sudermanjr