How to write a psp in k8s only for a specific user? - kubernetes

minikube start
--extra-config=apiserver.enable-admission-plugins=PodSecurityPolicy
--addons=pod-security-policy
we have a default namespace in which the nginx service account does not have the rights to launch the nginx container
when creating a pod, use the command
kubectl run nginx --image=nginx -n default --as system:serviceaccount:default:nginx-sa
as a result, we get an error
Error: container has runAsNonRoot and image will run as root (pod: "nginx_default(49e939b0-d238-4e04-a122-43f4cfabea22)", container: nginx)
as I understand it, it is necessary to write a psp policy that will allow the nginx-sa service account to run under, but I do not understand how to write it correctly for a specific service account
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-sa
namespace: default
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nginx-sa-role
namespace: default
rules:
- apiGroups: ["extensions", "apps",""]
resources: [ "deployments","pods" ]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nginx-sa-role-binding
namespace: default
subjects:
- kind: ServiceAccount
name: nginx-sa
namespace: default
roleRef:
kind: Role
name: nginx-sa-role
apiGroup: rbac.authorization.k8s.io

...but I do not understand how to write it correctly for a specific service account
After you get your special psp ready for your nginx, you can grant your nginx-sa to use the special psp like this:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: role-to-use-special-psp
rules:
- apiGroups:
- policy
resourceNames:
- special-psp-for-nginx
resources:
- podsecuritypolicies
verbs:
- use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: bind-to-role
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: role-to-use-special-psp
subjects:
- kind: ServiceAccount
name: nginx-sa
namespace: default

Related

kubernetes ServiceAccount Role Verification failed

questions:
Create a service account name dev-sa in default namespace, dev-sa can create below components in dev namespace:
Deployment
StatefulSet
DaemonSet
result:
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: default
name: dev-sa
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: dev
name: sa-role
rules:
- apiGroups: [""]
resources: ["deployment","statefulset","daemonset"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: sa-rolebinding
namespace: dev
subjects:
- kind: ServiceAccount
name: dev-sa
namespace: default
roleRef:
kind: Role
name: sa-role
apiGroup: rbac.authorization.k8s.io
Validation:
kubectl auth can-i create deployment -n dev \
--as=system:serviceaccount:default:dev-sa
no
This is an exam question, but I can't pass
Can you tell me where the mistake is? thx
in Role, use * on api group, and add s on resource name.
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: default
name: dev-sa
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: dev
name: sa-role
rules:
- apiGroups: ["*"]
resources: ["deployments", "statefulsets", "daemonsets"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: sa-rolebinding
namespace: dev
subjects:
- kind: ServiceAccount
name: dev-sa
namespace: default
roleRef:
kind: Role
name: sa-role
apiGroup: rbac.authorization.k8s.io
First, the apiGroups of Deployment, daemonSet, and statefulSet is apps, not core. So, for the apiGroups value, instead of "", put "apps". (an empty string representing core)
Second, remember: resources always define in Plural of "kind". So, for resources values, you always should use plural names. e.g. instead of deployment, you use deployments
So, your file should be something like this:
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: default
name: dev-sa
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: dev
name: sa-role
rules:
- apiGroups: ["apps"]
resources: ["deployments","statefulsets","daemonsets"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: sa-rolebinding
namespace: dev
subjects:
- kind: ServiceAccount
name: dev-sa
namespace: default
roleRef:
kind: Role
name: sa-role
apiGroup: rbac.authorization.k8s.io
For apiGroups's values, be sure to check the docs
I suggest you read this article about Users and Permissions in Kubernetes.

Restricted user in K8s need CRD's access

In my scenario user has access to four namespaces only, he will switch between namespaces using contexts below. How can I give him access to CRD's along with his exiting access to four namespaces.
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* dev-crd-ns-user dev dev-crd-ns-user dev-crd-ns
dev-mon-fe-ns-user dev dev-mon-fe-ns-user dev-mon-fe-ns
dev-strimzi-operator-ns dev dev-strimzi-operator-ns-user dev-strimzi-operator-ns
dev-titan-ns-1 dev dev-titan-ns-1-user dev-titan-ns-1
hifi#101common:/root$ kubectl get secret
NAME TYPE DATA AGE
default-token-mh7xq kubernetes.io/service-account-token 3 8d
dev-crd-ns-user-token-zd6xt kubernetes.io/service-account-token 3 8d
exfo#cmme101common:/root$ kubectl get crd
Error from server (Forbidden): customresourcedefinitions.apiextensions.k8s.io is forbidden: User "system:serviceaccount:dev-crd-ns:dev-crd-ns-user" cannot list resource "customresourcedefinitions" in API group "apiextensions.k8s.io" at the cluster scope
Tried below two options. Option 2 is the recommendation but didn't work with either one.
Error from server (Forbidden): customresourcedefinitions.apiextensions.k8s.io is forbidden: User "system:serviceaccount:dev-crd-ns:dev-crd-ns-user" cannot list resource "customresourcedefinitions" in API group "apiextensions.k8s.io" at the **cluster scope**
Option 1: Adding CRD to existing role
role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
name: dev-ns-user-full-access
namespace: dev-crd-ns
rules:
- apiGroups:
- ""
- extensions
- apps
- networking.k8s.io
- apiextensions.k8s.io
resources:
- '*'
- customresourcedefinitions
verbs:
- '*'
- apiGroups:
- batch
resources:
- jobs
- cronjobs
verbs:
- '*'
role binding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
annotations:
name: dev-crd-ns-user-view
namespace: dev-crd-ns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dev-crd-ns-user-full-access
subjects:
- kind: ServiceAccount
name: dev-crd-ns-user
namespace: dev-crd-ns
Option 2 : Adding CRD as a new role to "dev-crd-ns" namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev-crd-ns
name: crd-admin
rules:
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: crd-admin
namespace: dev-crd-ns
subjects:
- kind: ServiceAccount
name: dev-crd-ns-user
namespace: dev-crd-ns
roleRef:
kind: Role
name: crd-admin
apiGroup: rbac.authorization.k8s.io
You need to create Role and RoleBinding for each service account like dev-crd-ns-user.
For dev-crd-ns-user:
Update the existing Role or create a new one:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: dev-crd-ns
name: crd-admin
rules:
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
$ kubectl apply -f crd-admin-role.yaml
Update the existing RoleBinding with this new Role or create a new one:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: crd-admin
namespace: dev-crd-ns
subjects:
- kind: ServiceAccount
name: dev-crd-ns-user
namespace: dev-crd-ns
roleRef:
kind: Role
name: crd-admin
apiGroup: rbac.authorization.k8s.io
$ kubectl apply -f crd-admin-role-binding.yaml
Now, the SA dev-crd-ns-user will have all the access to customresourcedefinitions.
Follow similar steps for the rest of the service accounts.

how can I create a service account for all namespaces in a kubernetes cluster?

So I have namespaces
ns1, ns2, ns3, and ns4.
I have a service account sa1 in ns1. I am deploying pods to ns2, ns4 that use sa1. when I look at the logs it tells me that the sa1 in ns2 can't be found.
error:
Error creating: pods "web-test-2-795f5fd489-" is forbidden: error looking up service account ns2/sa: serviceaccount "sa" not found
Is there a way to make service accounts cluster wide? Or, can I create multiple service accounts with the same secret? in different namespaces?
you can use that
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kubernetes-enforce
rules:
- apiGroups: ["apps"]
resources: ["deployments","pods","daemonsets"]
verbs: ["get", "list", "watch", "patch"]
- apiGroups: ["*"]
resources: ["namespaces"]
verbs: ["get", "list", "watch"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubernetes-enforce
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-enforce-logging
namespace: cattle-logging
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-enforce
subjects:
- kind: ServiceAccount
name: kubernetes-enforce
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-enforce-prome
namespace: cattle-prometheus
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-enforce
subjects:
- kind: ServiceAccount
name: kubernetes-enforce
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-enforce-system
namespace: cattle-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-enforce
subjects:
- kind: ServiceAccount
name: kubernetes-enforce
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-enforce-default
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-enforce
subjects:
- kind: ServiceAccount
name: kubernetes-enforce
namespace: kube-system
No there is no way to create a cluster wide service account as service account is a namespace scoped resources. This follows the principle of least privilege.
You can create a service account with same name(for example default) into all the necessary namespaces where you are deploying pod pretty easily by applying the service account yaml targeting those namespaces.
Then you can deploy the pod using yaml. This way you don't need to change anything in the pod because the service account name is same although it will have different secret and that should not matter as long as you have defined RBAC via role and rolebinding to all the service accounts across those namespaces.
While service accounts can not be cluster scoped you can have clusterrole and clusterrolebinding which are cluster scoped.
If your namespaces for example are in values.yaml (that is they are somehow dynamic), you could do:
apiVersion: v1
kind: List
items:
{{- range $namespace := .Values.namespaces }}
- kind: ServiceAccount
apiVersion: v1
metadata:
name: <YourAccountName>
namespace: {{ $namespace }}
{{- end }}
where in values.yaml you would have:
namespaces:
- namespace-a
- namespace-b
- default
# define a clusterrole.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: supercr
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
# define a serviceaccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: supersa
namespace: namespace-1
---
# bind serviceaccount to clusterrole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: supercrb
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: supercr
subjects:
- kind: ServiceAccount
name: supersa
namespace: namespace-1
Please note serviceaccount is namespaced. You can't create a cluster-wide serviceaccount. However you can bind a serviceaccount to a clusterrole with permissions to all api resources.

how can you grant read-only access to the K8s dashboard?

I've tried creating a cluster role that only has access to view pods, however, for some reason that account can still see everything; secrets, deployments, nodes etc. I also enabled skip-login, and it seems like by default anonymous users don't have any restrictions either.
Service account:
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-example
namespace: default
Cluster Role:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cr-example
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
Cluster Role Binding:
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: crb-example
roleRef:
apiGroup: rbac.authorization.k8s.io
name: cr-example
kind: ClusterRole
subjects:
- kind: ServiceAccount
name: sa-example
namespace: default
Context:
K8s version: 1.17.3
Dashboard version: v2.0.0-rc5
Cluster type: bare metal
authorization-mode=Node,RBAC
How did You check if it works or no?
I made a reproduction of your issue with below yamls
apiVersion: v1
kind: ServiceAccount
metadata:
name: sa-example
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cr-example
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: crb-example
roleRef:
apiGroup: rbac.authorization.k8s.io
name: cr-example
kind: ClusterRole
subjects:
- kind: ServiceAccount
name: sa-example
namespace: default
And I used kubectl auth can-i to verify if it works
kubectl auth can-i get pods --as=system:serviceaccount:default:sa-example
yes
kubectl auth can-i get deployment --as=system:serviceaccount:default:sa-example
no
kubectl auth can-i get secrets --as=system:serviceaccount:default:sa-example
no
kubectl auth can-i get nodes --as=system:serviceaccount:default:sa-example
no
And it seems like everything works just fine
The only thing which if different in my yaml is
kind: ClusterRole
metadata:
name: cr-example instead of cr-<role>
So it actually match ClusterRoleBinding
I hope it help you with your issues. Let me know if you have any more questions.

How to give all Kubernetes service accounts access to a specific namespace?

I have a RBAC enabled Kubernetes cluster in GCP
There are one namespace for Tiller and multiple for Services
Right now, I can assign reader role for a specific service account given it's full name
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
name: tiller-reader
namespace: tiller
rules:
- apiGroups: [""]
resources: ["pods"]
verbs:
- "get"
- "watch"
- "list"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tiller-reader-role-binding
namespace: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: tiller-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: system:serviceaccount:my-namespace-1:my-namespace-1-service-account
The Service namespaces and accounts are created dynamically. How do I automatically give all services accounts access to the Tiller namespace, for example: to get pods?
to grant a role to all service accounts you must use the Group system:serviceaccounts.
you can try the following config :
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
name: tiller-reader
namespace: tiller
rules:
- apiGroups: [""]
resources: ["pods"]
verbs:
- "get"
- "watch"
- "list"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tiller-reader-role-binding
namespace: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tiller-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:serviceaccounts