Deploy Cerbos as a sidecar

The sidecar deployment model might be a preferrable option under the following circumstances:

  • You have a self-contained application that does not need to share policies with other applications in your environment.

  • You prefer to ship policy changes as application updates by bundling the two together.

  • You are concerned about network latency.

Cerbos supports serving the API over a Unix domain socket. This allows your application container to securely communicate with the Cerbos service with no network overhead. Because the Cerbos server is only listening over a Unix domain socket, no other applications in your network will be able to communicate with it — thus providing secrecy as a bonus side effect.

The following example illustrates a Kubernetes deployment with Cerbos as a sidecar.

We are using ghostunnel as the application container for demonstration purposes only. In a real production deployment the Cerbos endpoint should not be exposed to the network.
---
# Config map used to configure Cerbos. 
apiVersion: v1
kind: ConfigMap
metadata:
  name: cerbos-sidecar-demo
  labels:
    app.kubernetes.io/name: cerbos-sidecar-demo
    app.kubernetes.io/component: cerbos
    app.kubernetes.io/version: "0.0.1"
data:
  "config.yaml": |-
      server:
        # Configure Cerbos to listen on a Unix domain socket.
        httpListenAddr: "unix:/sock/cerbos.sock"
      storage:
        driver: disk
        disk:
          directory: /policies
          watchForChanges: false
---
# Application deployment with Cerbos as a sidecar.
# Note that in this example we are simply proxying requests received
# by the main application (application container) to the Cerbos
# sidecar (`cerbos` container) for demonstration purposes. In a real
# production deployment the main application would not expose Cerbos
# to the outside world at all. It would communicate with the Cerbos
# sidecar privately to make policy decisions about the actions that
# it is performing.
#
# Bonus: You can re-purpose this example to deploy Cerbos in an
# environment that requires SPIFFE workload identities and/or
# regular certificate rotation and access restrictions. See the
# ghostunnel documentation at https://github.com/ghostunnel/ghostunnel
# for more information.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cerbos-sidecar-demo
  labels:
    app.kubernetes.io/name: cerbos-sidecar-demo
    app.kubernetes.io/component: cerbos-sidecar-demo
    app.kubernetes.io/version: "0.0.1"
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: cerbos-sidecar-demo
      app.kubernetes.io/component: cerbos-sidecar-demo
  template:
    metadata:
      labels:
        app.kubernetes.io/name: cerbos-sidecar-demo
        app.kubernetes.io/component: cerbos-sidecar-demo
    spec:
      containers:
        ########################################################################
        # Application container. Replace with your own application definition. #
        ########################################################################
        - name: application
          image: "ghostunnel/ghostunnel"
          imagePullPolicy: IfNotPresent
          args:
            - "server"
            - "--listen=:3592"
            - "--target=unix:/sock/cerbos.sock"
            - "--cert=/certs/tls.crt"
            - "--key=/certs/tls.key"
            - "--disable-authentication"
          ports:
            - name: http
              containerPort: 3592
          livenessProbe:
            httpGet:
              path: /_cerbos/health
              port: http
              scheme: HTTPS
          readinessProbe:
            httpGet:
              path: /_cerbos/health
              port: http
              scheme: HTTPS
          volumeMounts:
            # Mount the shared volume containing the socket
            - name: sock
              mountPath: /sock
            - name: certs
              mountPath: /certs
        ##################
        # Cerbos sidecar #
        ##################
        - name: cerbos
          image: "ghcr.io/cerbos/cerbos:0.9.0"
          imagePullPolicy: IfNotPresent
          args:
            - "server"
            - "--config=/config/config.yaml"
            - "--log-level=INFO"
          volumeMounts:
            # Mount the shared volume containing the socket
            - name: sock
              mountPath: /sock
            - name: config
              mountPath: /config
              readOnly: true
            - name: policies
              mountPath: /policies
      volumes:
        # Shared volume containing the socket.
        - name: sock
          emptyDir: {}
        - name: config
          configMap:
            name: cerbos-sidecar-demo
        - name: certs
          secret:
            secretName: cerbos-sidecar-demo
        - name: policies
          emptyDir: {}
---
# Use cert-manager to issue a certificate to the application.
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: cerbos-sidecar-demo
  labels:
    app.kubernetes.io/name: cerbos-sidecar-demo
    app.kubernetes.io/component: cerbos-sidecar-demo
    app.kubernetes.io/version: "0.0.1"
spec:
  isCA: true
  secretName: cerbos-sidecar-demo
  dnsNames:
    - cerbos-sidecar-demo.default.svc.cluster.local
    - cerbos-sidecar-demo.default.svc
    - cerbos-sidecar-demo.default
    - cerbos-sidecar-demo
  issuerRef:
    name: selfsigned-cluster-issuer
    kind: ClusterIssuer
    group: cert-manager.io