2

Is it possible to create a kubernetes RBAC rule that allows creating a Job from an existing CronJob, but prevents creating a Job any other way?

We want to keep our clusters tightly locked down to avoid arbitrary deployments not managed by CICD - but we also need to facilitate manual testing of CronJobs, or rerunning failed jobs off schedule. I'd like developers to be able to run a command like:

kubectl create job --from=cronjob/my-job my-job-test-run-1

But not be able to run something like:

kubectl create job my-evil-job -f evil-job.yaml

Is that possible?

Gavin Clarke
  • 379
  • 3
  • 15
  • Which kubernetes version do you use? Since there are some changes introduced all the time. Which account the developers are using? Like user ones or SA for apps – RadekW Feb 28 '22 at 09:31
  • We're currently using v1.21 on EKS and we map developers to the `view` cluster role. Only the devops team and the CICD pipelines have write access at the moment – Gavin Clarke Feb 28 '22 at 10:53

1 Answers1

3

In this scenario in order to successfully execute this command:

kubectl create job --from=cronjob/<cronjob_name>  

User/ServiceAccount should have proper RBAC rules (at least two from the output provided below, create Jobs and get CronJobs.

In first example I granted access to create Jobs and get CronJobs and I was able to create Job and Job --from CronJob

user@minikube:~$ cat test_role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: job
rules:
- apiGroups: ["batch"]
  resources: ["jobs"]
  verbs: ["create"]
- apiGroups: ["batch"]
  resources: ["cronjobs"]
  verbs: ["get"]
user@minikube:~$ kubectl create job --image=inginx testjob20
job.batch/testjob20 created
user@minikube:~$ kubectl create job --from=cronjobs/hello testjob21
job.batch/testjob21 created

But if I granted access only to create Job without get CronJob, I was be able to create Job but not to create Job --from CronJob

user@minikube:~$ cat test_role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: job
rules:
- apiGroups: ["batch"]
  resources: ["jobs"]
  verbs: ["create"]
user@minikube:~$ kubectl create job --image=nginx testjob3
job.batch/testjob3 created
user@minikube:~$ kubectl create job --from=cronjobs/hello testjob4
Error from server (Forbidden): cronjobs.batch "hello" is forbidden: User "system:serviceaccount:default:t1" cannot get resource "cronjobs" in API group "batch" in the namespace "default"

When I deleted access to create Jobs, I couldn't create Job and also Job --from CronJob

user@minikube:~$ cat test_role
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: job
rules:
- apiGroups: ["batch"]
  resources: ["cronjobs"]
  verbs: ["get"]
user@minikube:~$ kubectl create job --image=inginx testjob10
error: failed to create job: jobs.batch is forbidden: User "system:serviceaccount:default:t1" cannot create resource "jobs" in API group "batch" in the namespace "default"  
user@minikube:~$ kubectl create job --from=cronjobs/hello testjob11
error: failed to create job: jobs.batch is forbidden: User "system:serviceaccount:default:t1" cannot create resource "jobs" in API group "batch" in the namespace "default"

As you can see if User/ServiceAccount doesn't have both permission in this scenario it's impossible to create (Job or Job --from CronJob) so it's impossible to create such restrictions using only RABC rules.

One possible solution is to split this permission into two different User/ServiceAccount for two different tasks (first user can create Jobs + get CronJobs, second user without permission to create Jobs).

Another possibility is to try to use k8s admission Controller with f.e. Open Policy agent

RadekW
  • 439
  • 1
  • 11