Problem

In an event-driven system like Kubernetes, access to a resource can be restricted with RBAC. RBAC is not designed to execute a mandatory or exclusive lock on a particular resource. It is not impossible, but I found it complicated and error-prone.

Sometimes I want:

  • The CronJob named daily-report is constant. No one can DELETE or UPDATE it.
  • A workload payroll can be modified only by the actor with UID aa-dd-f445-d-55-d and no one else.
  • All resources with the label site: for-fun can be updated, but not deleted.

Solution

Using RBAC is possible to partially meet requirements, but still when working in teams messing with operators, different automation tools, etc… Always something can go wrong.

Another option is ValidatingAdmissionWebhook. It can be used to say who can and can not access a certain resource. It is not about authentication or authorization, that part is done by Kubernetes. It is about access, granular access.

Klock as solution

Klock is simple implementation in effort to match above problems. It adds CRD that allows mandatory and exclusive locking. Matching which resource will be protected is done by matching labels. As well as which operation should be restricted.

Configuring ValidatingAdmissionWebhook

For which resource ValidatingAdmissionWebhook(VAW) is applied is done in VAW configuration:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  annotations:
    cert-manager.io/inject-ca-from: klock-system/klock-serving-cert
  name: klock-validating-webhook-configuration
webhooks:
- admissionReviewVersions:
  - v1
  clientConfig:
    service:
      name: klock-webhook-service
      namespace: klock-system
      path: /validate-all
  failurePolicy: Fail
  name: klocks.rnemet.dev
  rules:
  - apiGroups:
    - '*'
    apiVersions:
    - '*'
    operations:
    - DELETE
    - UPDATE
    resources:
    - pods
    - deployments
    - secrets
    - configmaps
  sideEffects: None

Above configuration, you can read as for any api group and any version, whenever UPDATE or DELETE is about to be executed on a pod, a deployment, a secret, or a config map, ask VAW to validate it first.

Mandatory locking

See example:

apiVersion: klock.rnemet.dev/v1
kind: Lock
metadata:
  name: lock-red-blue
  namespace: yellow
spec:
  operations:
    - DELETE
  matcher:
    aura: blue

Now, if VAW has config as above Lock is effective for every pod, deployment, secret, and configmap in the same namespace. It will deny deletion of any pod, deployment, secret, or configmap with the label aura: red.

Exclusive locking

apiVersion: klock.rnemet.dev/v1
kind: Lock
metadata:
  name: lockred
spec:
  operations:
    - UPDATE
    - DELETE
  matcher:
    aura: red
  exclusive:
    name: johny

With exclusive locking operations are forbidden for all except an actor named johny, in this example. So, same as above just ignore Lock for johny.

Conclusion

You can check out Klock and explore it more. See /tests/ for more examples.