When deployed as a platform, each code review runs in an isolated container that is destroyed after completion. This ensures:
The security model is built around one-way communication:
Backend ──watches──▶ Container Runtime API
(Docker events / K8s watch)
Container ──pulls code──▶ GitHub/GitLab
Container ──posts review──▶ GitHub/GitLab
Container ──✗ cannot reach──▶ Backend, Database, Other Containers
The backend never:
The backend only handles: user auth, webhook events, job dispatching, and status tracking.
--cap-drop ALL, --security-opt no-new-privileges, read-only root filesystem, and PID limits. Can be placed on isolated networksSee the Security Hardening guide for detailed network isolation configuration
Both backends enforce resource limits to prevent runaway processes:
| Resource | Docker Default | Kubernetes Default |
|---|---|---|
| Memory | 4 GB | 4 Gi (request: 512 Mi) |
| CPU | 2 cores | 2 cores (request: 500m) |
| Timeout | 10 minutes | 10 minutes |
Containers run as a non-root user (UID 1000) by default. On Kubernetes, this is enforced via pod security context:
run_as_non_root: true
run_as_user: 1000
run_as_group: 1000
Containers are destroyed after completion. Nothing persists between reviews:
Containers receive short-lived tokens (GitHub installation tokens, GitLab PATs) that provide access only to the repository being reviewed.
Kubernetes provides additional isolation layers:
| Feature | Description |
|---|---|
| Namespace isolation | Review jobs run in a dedicated namespace (reviewate-jobs) |
| NetworkPolicy | Deny all ingress to the jobs namespace |
| ServiceAccount RBAC | Minimal permissions—review pods have no Kubernetes API access |
| Pod security context | Non-root, read-only root filesystem capable |
| Node selectors | Optional: run reviews on dedicated nodes |