Search anything...
K
Back to Docs
  • Introduction
  • Quick Start
  • Account Setup
  • AI Studio
  • Chat
  • Agents
  • Voice
  • MCP Servers
  • Workflows
  • Authentication
  • Studio API
  • Chat API
  • Agents API
  • Voice API
  • Workflows API
  • Webhooks
  • Error Codes
  • Creating Custom Agents
  • MCP Integration
  • Building Workflows
  • Prompt Engineering
  • Team Management
  • Billing & Plans
  • Usage Monitoring
  • Single-Tenant Cloud
  • Private VPC Deployment
  • SSO Configuration
  • Security Policies
  • Compliance
  • Troubleshooting
  • API Versioning
DocsEnterpriseSingle-Tenant Cloud

Single-Tenant Cloud

Dedicated cloud deployment

This guide covers deploying Girard AI as a dedicated single-tenant instance for enterprise customers who require isolated infrastructure.


Overview

Single-tenant deployment provides:

  • Complete isolation - Dedicated compute, database, and storage
  • Custom domain - Your own branded domain (e.g., ai.yourcompany.com)
  • Data residency - Choose deployment region for compliance
  • Enhanced security - Network isolation, dedicated encryption keys
  • Custom SLAs - Guaranteed uptime and support response times

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                    Single-Tenant Architecture                    │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐      │
│  │   Vercel     │    │    Neon      │    │ Cloudflare   │      │
│  │  (Compute)   │───▶│  (Database)  │    │   R2/CDN     │      │
│  │  Dedicated   │    │  Dedicated   │    │  Dedicated   │      │
│  └──────────────┘    └──────────────┘    └──────────────┘      │
│         │                   │                   │                │
│         └───────────────────┴───────────────────┘                │
│                             │                                    │
│                    ┌────────▼────────┐                          │
│                    │   Customer VPC   │                          │
│                    │   (Optional)     │                          │
│                    └─────────────────┘                          │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Deployment Options

Option 1: Vercel Enterprise (Recommended)

Best for: Most enterprise customers wanting managed infrastructure.

Prerequisites

  • Vercel Enterprise account
  • Custom domain configured
  • DNS access for domain verification

Setup Steps

  1. Create Dedicated Vercel Project
# Clone repository to customer-specific branch
git clone https://github.com/Girard-Media/girardai-com.git
cd girardai-com
git checkout -b customer/acme-corp

# Install Vercel CLI
npm i -g vercel

# Link to new project
vercel link --project acme-girardai
  1. Configure Environment Variables

Set these in Vercel Dashboard → Project Settings → Environment Variables:

# Application
NEXT_PUBLIC_APP_URL="https://ai.acme.com"
ENCRYPTION_KEY="<unique-32-char-key>"

# Database (Dedicated Neon Project)
DATABASE_URL="postgresql://user:pass@ep-acme-xxx.region.aws.neon.tech/neondb?sslmode=require"

# Authentication (Dedicated Clerk Instance)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_live_acme_..."
CLERK_SECRET_KEY="sk_live_acme_..."
CLERK_WEBHOOK_SECRET="whsec_acme_..."

# Payments (Customer's Stripe Account or Connected Account)
STRIPE_SECRET_KEY="sk_live_acme_..."
STRIPE_WEBHOOK_SECRET="whsec_acme_..."
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_live_acme_..."

# AI Providers (Customer-provided or Girard AI managed)
ANTHROPIC_API_KEY="sk-ant-..."
OPENAI_API_KEY="sk-..."

# Storage (Dedicated R2 Bucket)
R2_ACCOUNT_ID="acme_account_id"
R2_ACCESS_KEY_ID="acme_access_key"
R2_SECRET_ACCESS_KEY="acme_secret_key"
R2_BUCKET_NAME="acme-girardai-uploads"
R2_PUBLIC_URL="https://cdn.ai.acme.com"

# Caching (Dedicated Upstash Instance)
UPSTASH_REDIS_REST_URL="https://acme-xxx.upstash.io"
UPSTASH_REDIS_REST_TOKEN="acme_token"
  1. Configure Custom Domain
# Add custom domain in Vercel
vercel domains add ai.acme.com

# Configure DNS (customer's DNS provider)
# Add CNAME record: ai.acme.com → cname.vercel-dns.com
  1. Deploy
vercel --prod
  1. Run Database Migrations
# Set DATABASE_URL locally
export DATABASE_URL="postgresql://..."

# Run migrations
npx prisma migrate deploy

Option 2: AWS Deployment

Best for: Customers requiring AWS-specific compliance or existing AWS infrastructure.

Infrastructure Components

ComponentAWS ServiceConfiguration
ComputeECS Fargate2 vCPU, 4GB RAM minimum
DatabaseRDS PostgreSQLdb.r6g.large, Multi-AZ
CacheElastiCache Rediscache.r6g.large
StorageS3Private bucket with CloudFront
CDNCloudFrontCustom domain, WAF enabled
SecretsSecrets ManagerAll sensitive configuration
DNSRoute 53Customer domain delegation

Terraform Configuration

# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

provider "aws" {
  region = var.aws_region
}

# Variables
variable "customer_name" {
  description = "Customer identifier"
  type        = string
}

variable "aws_region" {
  description = "AWS region for deployment"
  type        = string
  default     = "us-east-1"
}

variable "domain_name" {
  description = "Custom domain for the application"
  type        = string
}

# VPC
module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "${var.customer_name}-girardai-vpc"
  cidr = "10.0.0.0/16"

  azs             = ["${var.aws_region}a", "${var.aws_region}b"]
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]

  enable_nat_gateway = true
  single_nat_gateway = false

  tags = {
    Customer    = var.customer_name
    Environment = "production"
  }
}

# RDS PostgreSQL
module "rds" {
  source = "terraform-aws-modules/rds/aws"

  identifier = "${var.customer_name}-girardai-db"

  engine               = "postgres"
  engine_version       = "15"
  family               = "postgres15"
  major_engine_version = "15"
  instance_class       = "db.r6g.large"

  allocated_storage     = 100
  max_allocated_storage = 500

  db_name  = "girardai"
  username = "girardai_admin"
  port     = 5432

  multi_az               = true
  db_subnet_group_name   = module.vpc.database_subnet_group_name
  vpc_security_group_ids = [aws_security_group.rds.id]

  backup_retention_period = 30
  deletion_protection     = true

  performance_insights_enabled = true

  tags = {
    Customer = var.customer_name
  }
}

# ElastiCache Redis
resource "aws_elasticache_cluster" "redis" {
  cluster_id           = "${var.customer_name}-girardai-redis"
  engine               = "redis"
  node_type            = "cache.r6g.large"
  num_cache_nodes      = 1
  parameter_group_name = "default.redis7"
  port                 = 6379

  subnet_group_name  = aws_elasticache_subnet_group.redis.name
  security_group_ids = [aws_security_group.redis.id]

  snapshot_retention_limit = 7

  tags = {
    Customer = var.customer_name
  }
}

# ECS Cluster
resource "aws_ecs_cluster" "main" {
  name = "${var.customer_name}-girardai-cluster"

  setting {
    name  = "containerInsights"
    value = "enabled"
  }

  tags = {
    Customer = var.customer_name
  }
}

# ECS Task Definition
resource "aws_ecs_task_definition" "app" {
  family                   = "${var.customer_name}-girardai"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = 2048
  memory                   = 4096
  execution_role_arn       = aws_iam_role.ecs_execution.arn
  task_role_arn            = aws_iam_role.ecs_task.arn

  container_definitions = jsonencode([
    {
      name  = "girardai"
      image = "${aws_ecr_repository.app.repository_url}:latest"

      portMappings = [
        {
          containerPort = 3000
          hostPort      = 3000
          protocol      = "tcp"
        }
      ]

      environment = [
        { name = "NODE_ENV", value = "production" },
        { name = "NEXT_PUBLIC_APP_URL", value = "https://${var.domain_name}" }
      ]

      secrets = [
        { name = "DATABASE_URL", valueFrom = "${aws_secretsmanager_secret.app.arn}:DATABASE_URL::" },
        { name = "ENCRYPTION_KEY", valueFrom = "${aws_secretsmanager_secret.app.arn}:ENCRYPTION_KEY::" },
        { name = "CLERK_SECRET_KEY", valueFrom = "${aws_secretsmanager_secret.app.arn}:CLERK_SECRET_KEY::" }
        # ... additional secrets
      ]

      logConfiguration = {
        logDriver = "awslogs"
        options = {
          "awslogs-group"         = "/ecs/${var.customer_name}-girardai"
          "awslogs-region"        = var.aws_region
          "awslogs-stream-prefix" = "ecs"
        }
      }

      healthCheck = {
        command     = ["CMD-SHELL", "wget -q --spider http://localhost:3000/api/health || exit 1"]
        interval    = 30
        timeout     = 5
        retries     = 3
        startPeriod = 60
      }
    }
  ])
}

# Application Load Balancer
resource "aws_lb" "main" {
  name               = "${var.customer_name}-girardai-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = [aws_security_group.alb.id]
  subnets            = module.vpc.public_subnets

  enable_deletion_protection = true

  tags = {
    Customer = var.customer_name
  }
}

# S3 Bucket for uploads
resource "aws_s3_bucket" "uploads" {
  bucket = "${var.customer_name}-girardai-uploads"

  tags = {
    Customer = var.customer_name
  }
}

resource "aws_s3_bucket_versioning" "uploads" {
  bucket = aws_s3_bucket.uploads.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "uploads" {
  bucket = aws_s3_bucket.uploads.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "aws:kms"
    }
  }
}

Deployment Steps

# Initialize Terraform
terraform init

# Plan deployment
terraform plan -var="customer_name=acme" -var="domain_name=ai.acme.com"

# Apply
terraform apply -var="customer_name=acme" -var="domain_name=ai.acme.com"

# Build and push Docker image
docker build -t girardai .
docker tag girardai:latest $ECR_REPO_URL:latest
docker push $ECR_REPO_URL:latest

# Run migrations
aws ecs run-task \
  --cluster acme-girardai-cluster \
  --task-definition acme-girardai-migration \
  --launch-type FARGATE

Option 3: Google Cloud Platform

Best for: Customers with GCP preference or requiring specific GCP compliance certifications.

Infrastructure Components

ComponentGCP ServiceConfiguration
ComputeCloud Run2 vCPU, 4GB RAM
DatabaseCloud SQL PostgreSQLdb-custom-2-4096, HA
CacheMemorystore Redis5GB Standard
StorageCloud StorageRegional bucket
CDNCloud CDNCustom domain
SecretsSecret ManagerAll configuration
DNSCloud DNSCustomer domain

Deployment with Cloud Run

# Set project
gcloud config set project acme-girardai

# Build container
gcloud builds submit --tag gcr.io/acme-girardai/app

# Deploy to Cloud Run
gcloud run deploy girardai \
  --image gcr.io/acme-girardai/app \
  --platform managed \
  --region us-central1 \
  --memory 4Gi \
  --cpu 2 \
  --min-instances 2 \
  --max-instances 10 \
  --set-env-vars "NODE_ENV=production" \
  --set-secrets "DATABASE_URL=girardai-db-url:latest,ENCRYPTION_KEY=girardai-encryption-key:latest"

# Map custom domain
gcloud run domain-mappings create \
  --service girardai \
  --domain ai.acme.com \
  --region us-central1

Data Isolation

Database Isolation

Each single-tenant deployment gets:

  • Dedicated PostgreSQL instance
  • Unique encryption keys
  • Separate backup retention
  • Independent connection pooling

Storage Isolation

  • Dedicated cloud storage bucket
  • Customer-managed encryption keys (CMEK) optional
  • Separate CDN distribution

Network Isolation

  • Dedicated VPC (AWS/GCP) or project (Vercel)
  • Private database connectivity
  • WAF rules per customer

Security Configuration

Encryption

# Generate unique encryption key per customer
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"

# Store in secrets manager (never in environment variables directly)

SSL/TLS

  • All traffic encrypted in transit (TLS 1.3)
  • Customer can provide their own SSL certificates
  • Automatic certificate renewal via Let's Encrypt or AWS ACM

Access Control

# Example: IP allowlist for admin access
security_policies:
  ip_restriction:
    enabled: true
    admin_ips:
      - "203.0.113.0/24"  # Customer office
      - "198.51.100.0/24" # Customer VPN

Monitoring & Observability

Metrics

Each deployment includes:

  • Application metrics (response times, error rates)
  • Infrastructure metrics (CPU, memory, disk)
  • Database metrics (connections, query performance)
  • Custom business metrics

Logging

# Structured logging format
{
  "timestamp": "2026-01-22T10:00:00Z",
  "level": "info",
  "customer": "acme",
  "service": "girardai",
  "message": "Request processed",
  "duration_ms": 125,
  "user_id": "user_xxx",
  "request_id": "req_xxx"
}

Alerting

Configure alerts per customer:

  • Error rate > 1%
  • Response time p99 > 2s
  • Database connections > 80%
  • Storage usage > 80%

Backup & Recovery

Backup Schedule

Data TypeFrequencyRetention
DatabaseContinuous (WAL)30 days
Database snapshotsDaily90 days
File storageVersioned30 days
ConfigurationOn changeUnlimited

Recovery Procedures

See DISASTER_RECOVERY.md for detailed procedures.


Compliance

Available Certifications

  • SOC 2 Type II
  • HIPAA (with BAA)
  • GDPR compliant
  • ISO 27001 (roadmap)

Data Residency

Available regions:

  • US East (Virginia)
  • US West (Oregon)
  • EU West (Ireland)
  • EU Central (Frankfurt)
  • Asia Pacific (Singapore, Sydney)

Pricing

Single-tenant deployments are priced based on:

ComponentBase CostNotes
Platform license$2,000/moIncludes updates, support
ComputeVariableBased on usage
Database~$500/moDepends on size
Storage~$100/moPer TB
SupportIncluded4-hour SLA

Contact sales@girardai.com for custom pricing.


Support

Included Support

  • 24/7 infrastructure monitoring
  • 4-hour response SLA for critical issues
  • Dedicated Slack channel
  • Monthly review calls

Escalation Path

  1. Support ticket → support@girardai.com
  2. Slack channel → #acme-girardai
  3. Account manager escalation
  4. Engineering escalation

Onboarding Checklist

  • Customer agreement signed
  • Infrastructure provisioned
  • Custom domain configured
  • SSL certificates installed
  • Environment variables set
  • Database migrated
  • SSO configured (if applicable)
  • IP allowlist configured
  • Monitoring alerts configured
  • Backup verified
  • Security scan completed
  • Load testing passed
  • Documentation provided
  • Training completed
  • Go-live approved

Last updated: January 22, 2026

Previous
Usage Monitoring
Next
Private VPC Deployment