kubewarden-controller
kubewarden-controller copied to clipboard
New policy: Disallow Duplicate Deployment ServiceAccount
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
@Martin-Weiss, @raif-ahmed can you check the description of the policy to ensure it matches your requirements?
@flavio Yes this is correct.
@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 - 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
@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
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 thedefault
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) ...
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
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"..