Kubernetes

Deploy Reviewate on Kubernetes for production and enterprise environments.

Overview

Kubernetes deployment gives you high availability, scalability, and stronger isolation for code review jobs. The backend creates Kubernetes Jobs for each review, which are automatically cleaned up after completion.

Prerequisites

  • Kubernetes cluster (1.25+)
  • kubectl configured
  • PostgreSQL and Redis (managed or in-cluster)

Images

ServiceImagePortHealth check
Backendreviewate/backend:latest8000GET /health
Frontendreviewate/frontend:latest3000GET /
Code reviewerreviewate/code-reviewer:latest(runs as Job)
The code reviewer image is not deployed directly — it is pulled by the backend when creating review Jobs.

Configuration

Deploy the backend and frontend using your preferred method (Helm, Kustomize, raw manifests, etc.).

The only Kubernetes-specific setting is the config file — set REVIEWATE_CONFIG=/app/configs/kubernetes.yaml on the backend. This tells it to spawn review Jobs via the Kubernetes API instead of Docker.

For secrets management, use whatever fits your infrastructure — External Secrets, Vault, sealed-secrets, or plain Kubernetes Secrets.

You must configure the required environment variables and secrets in your backend deployment. See Environment Variables for the full reference.

Architecture

┌──────────────────────────────────────────────────────────┐
│                   Kubernetes Cluster                     │
├──────────────────────────────────────────────────────────┤
│                                                          │
│  ┌─────────────┐  ┌─────────────┐                        │
│  │   Backend   │  │  Frontend   │                        │
│  └──────┬──────┘  └─────────────┘                        │
│         │                                                │
│         │ creates Jobs via K8s API                       │
│         ▼                                                │
│  ┌────────────────────────────────────────────────────┐  │
│  │  Review Jobs (batch/v1 Jobs)                       │  │
│  │  - Hardened security context (non-root, read-only) │  │
│  │  - Resource limits enforced                        │  │
│  │  - Automatically cleaned up after completion       │  │
│  └────────────────────────────────────────────────────┘  │
│                                                          │
└──────────────────────────────────────────────────────────┘

The backend creates a Kubernetes Job for each review. Each Job gets an ephemeral Secret with the necessary env vars, runs to completion, and the backend reads the pod logs for results.

RBAC

The backend's ServiceAccount needs permissions to manage Jobs, read pod logs, and create ephemeral Secrets:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: reviewate-backend
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: reviewate-backend
rules:
  # List pods belonging to a Job, read their logs for results
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["list"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get"]
  # Create, watch, and clean up review Jobs
  - apiGroups: ["batch"]
    resources: ["jobs"]
    verbs: ["create", "get", "list", "watch", "delete"]
  # Create ephemeral Secrets with job env vars, patch ownerReferences for cleanup
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["create", "get", "list", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: reviewate-backend
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: reviewate-backend
subjects:
  - kind: ServiceAccount
    name: reviewate-backend

Review job containers themselves need no RBAC permissions — they only need network access to the LLM API and the platform API (GitHub/GitLab).

Job Security Context

Review Jobs are created with a hardened security context. These settings are not configurable — they are the secure defaults required by most clusters (including those running Kyverno or Pod Security Admission):

  • runAsNonRoot: true
  • runAsUser: 1000 / runAsGroup: 1000 (configurable)
  • readOnlyRootFilesystem: true
  • allowPrivilegeEscalation: false
  • /tmp mounted as emptyDir (1Gi by default, configurable via tmp_size_limit) for scratch space (cloning repos)

For production, run review jobs in a separate namespace with NetworkPolicy rules that block access to internal services and restrict egress to only the domains the agent needs.

Namespace and Ingress Deny

apiVersion: v1
kind: Namespace
metadata:
  name: reviewate-jobs
---
# Block all incoming traffic to review pods
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: reviewate-jobs
spec:
  podSelector: {}
  policyTypes:
    - Ingress
  ingress: []

Egress Restriction

By default, pods have unrestricted outbound access. This policy limits review pods to HTTPS only and blocks access to private IP ranges (your cluster services, databases, etc.):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-external-egress-only
  namespace: reviewate-jobs
spec:
  podSelector: {}
  policyTypes:
    - Egress
  egress:
    # Allow DNS resolution
    - to:
        - namespaceSelector: {}
      ports:
        - protocol: UDP
          port: 53
        - protocol: TCP
          port: 53
    # Allow HTTPS to external IPs only (blocks 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except:
              - 10.0.0.0/8
              - 172.16.0.0/12
              - 192.168.0.0/16
      ports:
        - protocol: TCP
          port: 443

This ensures review pods can reach GitHub, GitLab, and the Anthropic API over HTTPS, but cannot reach your database, Redis, backend, or other cluster services.

If your Anthropic API proxy or self-hosted GitLab runs on a private IP, add specific to rules for those addresses. See the Security Hardening guide for more options.