VirtueRed Installation Guide
This guide covers deployment options for VirtueRed, the enterprise AI red teaming platform. It is intended for DevOps and Infrastructure teams responsible for installation, configuration, and maintenance.
Architecture Overview
VirtueRed consists of containerized services that work together to provide AI model security testing capabilities.
Components
| Service | Description | Required |
|---|---|---|
| Database | PostgreSQL database for storing scan configurations, results, and metadata | Yes |
| Backend | Core API service that orchestrates scans, manages datasets, and generates reports | Yes |
| Frontend | Web-based user interface for managing scans and viewing results | Yes |
| Auth | Authentication and authorization service (users, roles, permissions) | Optional |
| Evaluator | Runs LLM-based safety evaluations on scan results. Requires GPU. | Optional |
Service Architecture
- Database must be healthy before other services can start
- Auth must be healthy before the Backend can start (if included)
- Evaluator must be healthy before the Backend can start (if included)
- Frontend waits for the Backend to be available
System Requirements
Hardware Requirements
| Service | vCPU | Memory | Storage | GPU | Notes |
|---|---|---|---|---|---|
| Database | 4 | 4 GB | 50 GB | — | Storage scales with scan history |
| Backend | 16 | 64 GB | 250 GB | — | Higher for more concurrency |
| Auth | 4 | 4 GB | 1 GB | — | Lightweight service |
| Evaluator | 8 | 64 GB | 100 GB | NVIDIA GPU (48+ GB VRAM) | Required for local LLM evaluation |
| Frontend | 4 | 4 GB | 1 GB | — | Static web application |
VirtueRed Estimated Disk Usage
This document provides estimated disk usage per scan for each supported modality in the VirtueRed platform. Estimates assume all test cases within the modality are enabled and are intended for storage capacity planning.
Scope and Assumptions
- Disk usage is calculated per scan
- All test cases under the listed modality are selected
- Stored artifacts include inputs, model outputs, evaluation metadata and logs
- Actual usage may vary based on model behavior, output size, and retention configuration
Disk Usage Summary by Modality
| Modality (Input → Output) | Risk Coverage(assume all the risk categories are selected) | Stored Artifacts | Estimated Disk Usage per Scan |
|---|---|---|---|
| Text → Text | Regulation-based Risks (EU AI Act, AI company policies, GDPR, OWASP LLM Top 10, NIST AI RMF, MITRE ATT&CK, FINRA); Use-Case-Driven Risks (bias, over-cautiousness, hallucination, societal harmfulness, privacy, robustness, finance / healthcare / education brand risk); Domain-specific Risks (healthcare, finance, retail policy compliance, IT/tech policy compliance) | Text prompts; text outputs; evaluation metadata; logs; report | ~45MB (500 prompts) |
| Text / Image → Text | Security attacks; high-risk advice; financial & economic risks; legal & regulatory risks; societal & ethical risks; cybersecurity & privacy risks; hallucinations | Text prompts; image inputs; text outputs; evaluation metadata; logs; report | ~50MB (500 prompts) |
| Text → Image | Hateful image generation; illegal activity image generation; political image generation; self-harm image generation; sexual / NSFW image generation; violence image generation | Text prompts; generated images; evaluation metadata; logs; report | ~3GB (500 prompts) |
| Text → Video | Video violence risks; video hate risks; video self-harm risks; video NSFW risks; video political risks; video illegal activity risks | Text prompts; generated videos; extracted video frames (images); evaluation metadata; logs; report | ~4GB (500 prompts) |
| Text + Image → Video | Guided video violence generation; guided video hate generation; guided video self-harm generation; guided video NSFW generation; guided video illegal activity generation | Text prompts; image inputs; generated videos; extracted video frames (images); evaluation metadata; logs; report | ~4.5GB (500 prompts) |
| Text + Video → Text | Illegal activity video interpretation; self-harm video interpretation; harassment video interpretation; misinformation video interpretation; sexual video interpretation; violence video interpretation | Video inputs; extracted video frames (images); text prompts; text outputs; evaluation metadata; logs; report | ~4GB (500 prompts) |
| Text + Video → Video | Illegal activity video synthesis; self-harm video synthesis; abuse video synthesis; misinformation video synthesis; sexual video synthesis; violence video synthesis | Video inputs; extracted video frames (images); text prompts; generated videos; extracted video frames (images); evaluation metadata; logs; report | ~3GB (207 prompts) |
Notes
- Storage requirements depend on scan history retention, number of scans, and data modalities. These recommendations are subject to refinement based on workload.
- Disk usage increases with:
- Output resolution and duration for image- and video-generating modalities
- Number of enabled test cases per scan
- Artifact retention period
- Image- and video-based scans are highly sensitive to output resolution and video duration and typically consume significantly more storage than text-only scans due to the storage of raw video files and extracted video frames (images).
- Customers may configure retention policies to manage long-term storage consumption
- All values are estimates, not hard limits
Software Requirements
| Component | Version |
|---|---|
| Docker | 25.0+ |
| Docker Compose | 2.24+ |
| Kubernetes | 1.30+ (for Helm deployment) |
| Helm | 3.14+ (for Helm deployment) |
| PostgreSQL | 14+ (EOL Nov 2026), 15+ recommended |
| NVIDIA Driver | 535+ (compatible with CUDA 12.x) |
| NVIDIA Container Toolkit | 1.15+ |
| CUDA (container) | 12.x (via NVIDIA base images) |
Deployment Options
Option 1: Docker Compose (Recommended for PoC/Small Teams)
Docker Compose provides a quick setup suitable for proof-of-concept deployments, development environments, and small teams.
Prerequisites
- Docker 25.0+
- Docker Compose 2.24+
- 32 GB RAM minimum
- 100 GB available disk space
- NVIDIA GPU with CUDA support (required only if using the Evaluator service)
Deployment Flexibility
Note: Not all services are required for every deployment. The configuration provided to you is tailored to your specific requirements.
| Deployment Scenario | Services Included |
|---|---|
| Minimal | Database + Backend + Frontend |
| Standard | Database + Backend + Frontend + Evaluator |
| Full(with auth) | Database + Auth + Backend + Frontend + Evaluator |
The Auth service provides user management, roles, and permissions. The Evaluator service is only required if you need local LLM-based evaluation capabilities—many deployments use external evaluation endpoints instead.
Quick Start
VirtueAI provides customer-specific Docker Compose configurations based on your requirements. Contact your VirtueAI representative to obtain the deployment package and configuration instructions for your environment.
General steps:
- Ensure prerequisites are met (Docker, Docker Compose, GPU drivers if using Evaluator)
- Place the provided
docker-compose.yamland environment configuration in your deployment directory - Configure environment variables as specified in your deployment guide
- Start the services:
docker compose up -d
- Verify all services are healthy:
docker compose ps
Example Reference Configuration (docker-compose.yaml)
⚠️ Note: This is a reference example only. Your actual configuration will differ based on your specific requirements, image names, and environment. Use the configuration provided by your VirtueAI representative.
Default Service URLs: By default, services are accessible at:
- Frontend: http://localhost:3000
- Backend: http://localhost:4401
- Evaluator: http://localhost:8000
services:
db: # PostgreSQL database
evaluator: # LLM evaluation service (GPU required)
backend: # Core API service
frontend: # Web interface
View full docker-compose.yaml example
services:
db:
image: postgres:14
container_name: virtuered-db
ports:
- "${POSTGRES_PORT:-5432}:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-virtuered} -d ${POSTGRES_DB:-virtuered}"]
interval: 10s
timeout: 5s
retries: 5
environment:
POSTGRES_USER: ${POSTGRES_USER:-virtuered}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-virtuered}
POSTGRES_DB: ${POSTGRES_DB:-virtuered}
evaluator:
image: virtuered-evaluator:latest
container_name: virtuered-evaluator
ipc: host
ports:
- "${EVALUATOR_PORT:-8000}:8000"
deploy:
resources:
reservations:
devices:
- driver: nvidia
device_ids: ["${GPU_DEVICE:-0}"]
capabilities: [gpu]
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"]
interval: 30s
timeout: 10s
retries: 10
start_period: 300s
backend:
image: virtuered-backend:latest
container_name: virtuered-backend
ports:
- "${BACKEND_PORT:-4401}:8000"
depends_on:
db:
condition: service_healthy
auth:
condition: service_healthy
evaluator:
condition: service_healthy
volumes:
- ./log:/app/log
- ./runs:/app/runs
- ./application_configs:/app/application_configs
- ./custom_dataset:/app/custom_dataset
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8000/health || exit 1"]
interval: 10s
timeout: 5s
retries: 5
environment:
POSTGRES_HOST: db
POSTGRES_PORT: ${POSTGRES_PORT:-5432}
POSTGRES_USER: ${POSTGRES_USER:-virtuered}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-virtuered}
POSTGRES_DB: ${POSTGRES_DB:-virtuered}
EVAL_KEY: ${EVAL_KEY:-changeme}
MODEL_BASE_URL: ${MODEL_BASE_URL:-http://evaluator:8000/v1}
VIRTUE_AUTH_URL: ${VIRTUE_AUTH_URL:-http://auth:8000/api/v1}
JWT_SECRET: ${JWT_SECRET:-changeme}
frontend:
image: virtuered-frontend:latest
container_name: virtuered-frontend
ports:
- "${FRONTEND_PORT:-3000}:3000"
depends_on:
backend:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:3000 || exit 1"]
interval: 10s
timeout: 5s
retries: 5
environment:
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-http://localhost:4401}
volumes:
pgdata:
Option 2: Kubernetes / Helm (Recommended for Production)
Helm deployment on Kubernetes is recommended for production environments as it supports high availability and scalability.
The virtue-red Helm chart is an umbrella chart containing the following subcharts:
| Subchart | Description | Condition |
|---|---|---|
backend | VirtueRed API service | Always enabled |
frontend | VirtueRed web UI | frontend.create |
auth | Access Control service | auth.create |
auth-frontend | Access Control UI | auth-frontend.create |
postgres | PostgreSQL database | postgres.create |
persistent-volume-resources | PVC for local storage | persistent-volume-resources.create |
Prerequisites
- Kubernetes 1.30+
- Helm 3.14+
kubectlconfigured with cluster access- Ingress controller or GKE Gateway
- For GCP: GCS FUSE CSI driver, Workload Identity
Installation
# Create namespace
kubectl create namespace red
# Pull the Helm chart from repository
helm pull oci://ghcr.io/virtue-ai/virtue-red --version 0.1.3
# Or Install helm chart directly
helm install virtuered oci://ghcr.io/virtue-ai/virtue-red --version 0.1.3 -n red
values.yaml
# Persistent Volume Claim and Persistent Volume using storageClassName: ""
# If dedicated Persistent Volume exists already on your K8s cluster, set create: false and use your own PV
persistent-volume-resources:
create: true
redCommonPvcLocal:
name: "red-common-pvc-local"
accessModes:
- ReadWriteOnce
capacity:
storage: 5Gi
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /var/minikube/red/local/app
type: DirectoryOrCreate
resources:
requests:
storage: "5Gi"
# Postgres Database with Persistent Volume Claim.
# This Database is used by backend service.
# If dedicated Postgres Database exists already on your K8s cluster, set create: false and use your own DB
postgres:
create: true
fullnameOverride: "postgres"
environmentVariables:
POSTGRES_USER: db_user
POSTGRES_PASSWORD: db_password
POSTGRES_DB: app
PGDATA: /var/minikube/red/local/postgresql/pgdata
volume:
enabled: true
className: ""
size: 3Gi
mountPath: /var/minikube/red/local/postgresql
# backend is mandatory service of Virtue-Red
# POSTGRES Secrets values are required. Fill Postgres Secrets values for your own DB or postgres chart above
backend:
image:
repository: "us-docker.pkg.dev/virtueai-staging/virtue-red/backend-all"
tag: "818e958-amd64-only"
configMap:
data:
VIRTUE_IO_TYPE: "posix"
VIRTUE_IO_LOCALHOME: "/app"
VIRTUE_IO_BUCKET_NAME: "<your-bucket-name>"
VIRTUE_AUTH_URL: "http://auth"
secrets:
EVAL_KEY: "<your-eval-api-key>"
POSTGRES_USER: "db_user"
POSTGRES_PASSWORD: "db_password"
POSTGRES_DB: "app"
POSTGRES_HOST: "postgres"
POSTGRES_PORT: "5432"
volumes:
- name: pvc-local
persistentVolumeClaim:
claimName: "red-common-pvc-local"
volumeMounts:
- name: pvc-local
mountPath: /app/log
subPath: backend/app/log
- name: pvc-local
mountPath: /app/runs
subPath: backend/app/runs
- name: pvc-local
mountPath: /app/custom_dataset
subPath: backend/app/custom_dataset
- name: pvc-local
mountPath: /app/application_configs
subPath: backend/app/application_configs
# frontend is optional service of Virtue-Red
# If you don't want to use frontend, set create: false. And instead, use Virtue-Red CLI to connect to backend
# https://pypi.org/project/virtuered/
frontend:
create: true
image:
repository: "us-docker.pkg.dev/virtueai-staging/virtue-red/frontend"
tag: "06f8bb9-amd64-only"
# model-server is optional
# this model-server is test model server developed by VirtueAI and it has integration of Together API. (https://www.together.ai/)
model-server:
create: true
image:
repository: "us-docker.pkg.dev/virtueai-staging/virtue-red/model-server"
tag: "ebdfbc5-amd64-only"
secrets:
create: true
TOGETHER_API_KEY: "<your-together-api-key>"
# Not Used for On-Premise
gke-common-sa:
create: false
# Not Used for On-Premise
cloud-sql-proxy:
create: false
# Busybox is for test purpose. change create: false if you don't want to use busybox
busybox:
create: true
image:
repository: "nginx"
tag: "latest"
auth:
create: true
image:
repository: "us-docker.pkg.dev/virtueai-staging/virtue-auth/auth"
tag: "3b8aea8-amd64-only"
configMap:
data:
BOOTSTRAP_ADMIN_USERNAME: "admin@virtueai.com"
secrets:
create: true
secrets:
- BOOTSTRAP_ADMIN_USERNAME: "admin@virtueai.com"
- BOOTSTRAP_ADMIN_PASSWORD: "password1234"
- DATABASE_URL: "postgres://db_user:db_password@postgres:5432/auth"
- SECRET_KEY: "secret1234"
secretProvider:
create: false
auth-frontend:
create: true
image:
repository: "us-docker.pkg.dev/virtueai-staging/virtue-auth/frontend"
tag: "2e8a881-amd64-only"
Database Configuration
Database Setup
VirtueRed requires two databases:
| Database | Purpose | Default Name |
|---|---|---|
| Auth DB | Access Control service (users, tenants, roles) | virtue_auth |
| Backend DB | VirtueRed Backend (scans, models, datasets) | virtuered |
# Auth service connection
DATABASE_URL=postgresql://postgres:password@db-host:5432/virtue_auth
# Backend service connection
POSTGRES_HOST=db-host
POSTGRES_PORT=5432
POSTGRES_USER=virtuered
POSTGRES_PASSWORD=virtuered
POSTGRES_DB=virtuered
Storage Configuration
VirtueRed stores scan artifacts, reports, datasets, and logs. Storage can be configured as either Persistent Volume Claims (PVC) or Object Storage depending on your deployment environment.
Storage Directories
The backend requires the following directories to be persistent:
| Directory | Purpose |
|---|---|
/app/runs | Scan results and outputs |
/app/log | Application logs |
/app/application_configs | User-uploaded model templates |
/app/custom_dataset | Custom test datasets |
Option 1: Persistent Volume Claim (On-Premise / Local)
For on-premise or air-gapped deployments, use a PersistentVolumeClaim with local or network storage.
Helm Configuration:
# Enable PVC-based storage
persistent-volume-resources:
create: true
redCommonPvcLocal:
name: "red-common-pvc-local"
accessModes:
- ReadWriteOnce
capacity:
storage: 5Gi
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /var/data/virtuered
type: DirectoryOrCreate
resources:
requests:
storage: "5Gi"
# Mount PVC in backend and set ConfigMap for Environment variables.
# VIRTUE_IO_TYPE: "posix" | "gcs" | "s3"
# VIRTUE_IO_LOCALHOME: "/app"
# VIRTUE_IO_BUCKET_NAME: {{ YOUR_BUCKET_NAME }} for VIRTUE_IO_TYPE is "gcs" | "s3
# VIRTUE_AUTH_URL: {{ auth_service_server_hostname }}
backend:
...
configMap:
data:
# client_address is target Model Server address.
# In this Chart example, model-server is deployed in the same namespace and its domain is set in client_address
client_address: "http://model-server.red.svc.cluster.local:4299"
VIRTUE_IO_TYPE: "posix"
VIRTUE_IO_LOCALHOME: "/app"
VIRTUE_IO_BUCKET_NAME: "<your-bucket-name>"
VIRTUE_AUTH_URL: "http://auth"
...
volumes:
- name: pvc-local
persistentVolumeClaim:
claimName: "red-common-pvc-local"
volumeMounts:
- name: pvc-local
mountPath: /app/log
subPath: backend/app/log
- name: pvc-local
mountPath: /app/runs
subPath: backend/app/runs
- name: pvc-local
mountPath: /app/config
subPath: backend/app/config
- name: pvc-local
mountPath: /app/custom_dataset
subPath: backend/app/custom_dataset
- name: pvc-local
mountPath: /app/application_configs
subPath: backend/app/application_configs
Option 2: Object Storage (Cloud Deployments)
For cloud deployments, use object storage (GCS, S3) mounted via CSI drivers for better scalability and durability.
Environment Variables:
| Variable | Description |
|---|---|
VIRTUE_IO_TYPE | Storage type: posix, gcs, or s3 |
VIRTUE_IO_LOCALHOME | Base path for storage (default: /app) |
VIRTUE_IO_BUCKET_NAME | Bucket name for cloud storage |
Google Cloud Storage (GCS) example
Use google cloud API to access Google GCS bucket directly Your GKE and Service Account should have proper role/permission to GCS read/write
backend:
configMap:
data:
VIRTUE_IO_TYPE: "gcs"
VIRTUE_IO_LOCALHOME: "/app"
VIRTUE_IO_BUCKET_NAME: "your-gcs-bucket"
serviceAccount:
create: false
name: "YOUR_GKE_SERVICE_ACCOUNT_GCS_ACCESS_ROLE"
AWS S3
Use AWS SDK API to access AWS S3 bucket. Your EKS and Service Account should have proper role/permission to S3 read/write.
backend:
configMap:
data:
VIRTUE_IO_TYPE: "s3"
VIRTUE_IO_LOCALHOME: "/app"
VIRTUE_IO_BUCKET_NAME: "your-s3-bucket"
serviceAccount:
create: false
name: "YOUR_EKS_SERVICE_ACCOUNT_S3_ACCESS_ROLE"
Troubleshooting
Common Issues
| Symptom | Possible Cause | Solution |
|---|---|---|
| Services fail to start | Missing environment variables | Check .env file or K8s secrets |
| Auth errors | VIRTUE_AUTH_URL misconfigured | Verify URL and network connectivity |
| Database connection errors | Incorrect credentials or host | Verify connection string |
| Scans timeout | Target model rate limiting | Adjust rate_limit_* settings in config.toml |
| JWT validation fails | JWT_SECRET mismatch | Ensure backend and auth use same secret |
Log Locations
| Service | Docker Compose | Kubernetes |
|---|---|---|
| Backend | docker-compose logs backend | kubectl logs deploy/virtuered-backend |
| Auth | docker-compose logs virtue-auth | kubectl logs deploy/virtue-auth |
| Logs directory | ./log/ | Pod volume at /app/log/ |
Security Considerations
Secrets Management
- Use Kubernetes secrets or external secret managers (Vault, AWS Secrets Manager)
- Rotate
SECRET_KEYandJWT_SECRETperiodically - Never commit secrets to version control
Support
For assistance with deployment or configuration:
- Email: support@virtueai.com
- Documentation: https://docs.virtueai.com