Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New policy: Disallow Duplicate Deployment ServiceAccount #595

Open
flavio opened this issue Dec 14, 2023 · 7 comments
Open

New policy: Disallow Duplicate Deployment ServiceAccount #595

flavio opened this issue Dec 14, 2023 · 7 comments

Comments

@flavio
Copy link
Member

flavio commented Dec 14, 2023

Description

Policy to check if every Deployment is using a unique service account, and rejects if the deployment's service account is already in use by a existing deployment.

In the 1st iteration the policy ensures no duplicated Service Account are used between Deployment resources located inside of the same Namespace. Future iterations should also look for duplication between other workload related Kubernetes resources. For example, it should deny the creation of a Deployment/Pod that uses the Service Account assigned to a CronJob.

Configuration

The policy uses this configuration format:

deny_usage_of_default_service_account: true # false by default

By default, the policy allows the usage of the default Service Account that Kubernetes maintains inside of each Namespace. However, the Kubewarden administrator can prevent the usage of the default namespace by setting deny_usage_of_default_service_account to true.

Examples

Given the following Deployment is already defined:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      serviceAccountName: nginx
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

The creation of the following Deployment is going to be accepted:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-deployment
  namespace: default
  labels:
    app: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      serviceAccountName: wordpress
      containers:
      - name: wordpress
        image: wordpress:latest
        ports:
        - containerPort: 80

The creation is allowed because the serviceAccountName is different.

The creation of the following Deployment is not going to be allowed:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-deployment
  namespace: default
  labels:
    app: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      serviceAccountName: nginx
      containers:
      - name: wordpress
        image: wordpress:latest
        ports:
        - containerPort: 80

The creation is rejected because the nginx service account is already in use by the nginx-deployment resource.

The creation of the following Deployment is going to be accepted:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-deployment
  namespace: internal
  labels:
    app: wordpress
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wordpress
  template:
    metadata:
      labels:
        app: wordpress
    spec:
      serviceAccountName: nginx
      containers:
      - name: wordpress
        image: wordpress:latest
        ports:
        - containerPort: 80

The creation is allowed despite the workload using the nginx service account. That happens because this deployment is done inside of a different Namespace (staging vs default).

Notes

This is going to be a context aware policy that requires access to the Deployment resources

@flavio
Copy link
Member Author

flavio commented Dec 14, 2023

@Martin-Weiss, @raif-ahmed can you check the description of the policy to ensure it matches your requirements?

@raif-ahmed
Copy link

@flavio Yes this is correct.

@Martin-Weiss
Copy link

@flavio - do we know if the applications we deliver with rancher already follow this rule (not to use the same service account for more than one deployment / daemon set / stateful set / jobs?

And - would this policy not be required for all sets of "deployment / daemon set / stateful set / jobs"?

One more thing - we might need a policy that denies the usage of the "default service account in any namespace" forcing applications to create their own, always... (in case someone does not specify a service account in the "deployment / daemon set / stateful set / jobs" at all)

@flavio
Copy link
Member Author

flavio commented Dec 15, 2023

@flavio - do we know if the applications we deliver with rancher already follow this rule (not to use the same service account for more than one deployment / daemon set / stateful set / jobs?

I don't know about that. We can deploy this policy in monitor mode and then rely on the audit scanner report to identify all the workloads that are violating it.

And - would this policy not be required for all sets of "deployment / daemon set / stateful set / jobs"?

Sorry, I didn't understand it. Can you elaborate a bit on that?

One more thing - we might need a policy that denies the usage of the "default service account in any namespace" forcing applications to create their own, always... (in case someone does not specify a service account in the "deployment / daemon set / stateful set / jobs" at all)

Is using the default service account considered a bad security practice?

According to the official docs, the privileges given to it are really really thin:

The default service accounts in each namespace get no permissions by default other than the default API discovery permissions that Kubernetes grants to all authenticated principals if role-based access control (RBAC) is enabled.

If using the default service account is not considered a bad security practice, we should ensure this policy doesn't enforce the uniqueness of it. Meaning, any number of workloads can use the default Service Account

@Martin-Weiss
Copy link

@flavio - do we know if the applications we deliver with rancher already follow this rule (not to use the same service account for more than one deployment / daemon set / stateful set / jobs?

I don't know about that. We can deploy this policy in monitor mode and then rely on the audit scanner report to identify all the workloads that are violating it.

Maybe I misundestood as well - does the policy just look at deployments or at pods or even statefulset/daemonset/job as well?

I understood that this policy seems to verify "service account in deployment A vs. service account in deployment B" - but it could also be "service account in deployment A vs. service account in statefulset C".

-> so checking for "duplicate / multiple usage of the same service account might need to be done cross-<deployment/daemon-set/job/statefulset/pod> and not just vs

And - would this policy not be required for all sets of "deployment / daemon set / stateful set / jobs"?

Sorry, I didn't understand it. Can you elaborate a bit on that?

See above.

One more thing - we might need a policy that denies the usage of the "default service account in any namespace" forcing applications to create their own, always... (in case someone does not specify a service account in the "deployment / daemon set / stateful set / jobs" at all)

Is using the default service account considered a bad security practice?

According to the official docs, the privileges given to it are really really thin:

Similar to using the "default" namespace I would see "using separe service accounts" as a security recommendation similar to "do not share security accounts".

This might be relevant from an auditing point of view - which process used which account do do x,y,z..?
And this might be relevant from a security point of view - for pod A we give the default service account a rolebinding for "much more rights" and then pod B is using / getting this as well..

So a policy that denies the usage of the default service account might also improve security (but not sure what this will break :-))

The default service accounts in each namespace get no permissions by default other than the default API discovery permissions that Kubernetes grants to all authenticated principals if role-based access control (RBAC) is enabled.

If using the default service account is not considered a bad security practice, we should ensure this policy doesn't enforce the uniqueness of it. Meaning, any number of workloads can use the default Service Account

What is "best" practice ;-) and what is the attach surface.. - IMO using a default user in general is not a good practice these days.. (root / administrator) ...

@flavio
Copy link
Member Author

flavio commented Dec 20, 2023

Maybe I misundestood as well - does the policy just look at deployments or at pods or even statefulset/daemonset/job as well?

I understood that this policy seems to verify "service account in deployment A vs. service account in deployment B" - but it could also be "service account in deployment A vs. service account in statefulset C".

You're right. The check was not going to be done across different Kubernetes types. I'll update the card.

Similar to using the "default" namespace I would see "using separe service accounts" as a security recommendation similar to "do not share security accounts".

This might be relevant from an auditing point of view - which process used which account do do x,y,z..?
And this might be relevant from a security point of view - for pod A we give the default service account a rolebinding for "much more rights" and then pod B is using / getting this as well..

So a policy that denies the usage of the default service account might also improve security (but not sure what this will break :-))

I'm afraid many things would break by denying the usage of the default Service Account. We can leave that as an optional setting. Something like:

settings:
  deny_usage_of_default_service_account: true # false by default

EDIT: I've updated the description of the issue to reflect the new requirements

@Martin-Weiss
Copy link

Thanks - and yes - I am sure that many things will break when we deny usage of default service account.

From a security point if view I still think that "personalized service accounts" should be better than "default" - especially when looking into auditing... (bumpy road in front of us ;-) ) - but let users decide and I agree with the default "false"..

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: No status
Development

No branches or pull requests

4 participants