π Kickstart Deployment Guide
The Kickstart deployment model provides a complete, self-hosted Control Core platform on your infrastructure using Docker Compose. This guide works on any cloud or on-premises (AWS EC2, Azure VM, GCP Compute Engine, or your own Linux server)βsame steps and images everywhere.
π Quick path (fits in 30-minute runbook)
DevOps: This sequence is Steps 2β3 of the 30-minute DevOps runbook. Do Before you start first, then:
- Before you start: Linux VM (or local), Docker + Docker Compose, GitHub repo + PAT, strong passwords for admin/DB/Redis. See Prerequisites and Deployment Guide β Before you start.
- Download and configure: Kickstart package or Docker Compose + env from this guide. Copy
.env.exampleto.env; setDATABASE_*,REDIS_*,SECRET_KEY,JWT_SECRET_KEY,CC_BUILTIN_ADMIN_PASS,GITHUB_TOKEN,POLICY_REPO_URL, Control Plane public URL. - Start Control Plane:
docker-compose up -d(or./start.sh). Wait for health checks. - Create API keys: Control Plane UI β Settings β Environments (Sandbox + Production keys).
- Deploy Sandbox Bouncer: Same Compose pattern or second stack; set
PAP_API_URL,API_KEY(Sandbox),ENVIRONMENT=sandbox,RESOURCE_NAME,RESOURCE_TYPE,ORIGINAL_HOST_URL,TARGET_HOST. Start Bouncer. - Configure and verify: Follow Administrator Guide β First steps (GitHub repo, confirm PEP/Resources, test policy). Total with runbook: under 30 min.
Full checklist: Deployment Guide (What to deploy, Where to run it).
Kickstart Readiness Toolkit
Pre-deploy checklist
Post-deploy checklist
π Developer Portal after deploy
In Kickstart, the Developer Portal is served by your Control Plane API container (control-plane-api) and is always in your infrastructure:
- URL:
https://<your-control-plane-host>/devdocs - OpenAPI JSON:
https://<your-control-plane-host>/openapi.json
Post-deploy operator checklist:
- Open
/devdocsand verify title Control Core - Developer. - Use Swagger "Try it out" to run
POST /developer-portal/token. - Generate environment API keys via
POST /developer-portal/api-keys/{environment}/generate. - Confirm runtime readiness using
GET /health/ready.
π Overview
Kickstart is ideal for:
- Small to medium teams (5-50 users)
- Development and testing environments
- Proof-of-concept deployments
- Organizations requiring complete control over infrastructure
- Learning and evaluation purposes
π Prerequisites
System Requirements
Operating System:
- Linux (Ubuntu 20.04+ or Debian 11+ recommended)
- macOS 11.0+ (for development)
- Windows 11 with WSL2 (for development)
Hardware:
- Memory: 4GB RAM minimum, 8GB RAM recommended
- CPU: 2 cores minimum, 4 cores recommended
- Storage: 20GB free space minimum, SSD recommended
- Network: Stable internet connection for initial setup
Software:
- Docker Engine 20.10.0 or higher
- Docker Compose 2.0.0 or higher
- Git (optional, for policy management)
Port Requirements
Ensure these ports are available:
| Port | Service | Description |
|---|---|---|
| 3000 | Policy Administration Console | Web UI for policy management |
| 8080 | Policy Enforcement Point | Bouncer/PEP for request protection |
| 8082 | Policy Administration API | Backend API service |
| 7000 | Policy Bridge | Policy distribution (WebSocket/HTTP) |
| 5432 | PostgreSQL | Database (internal only) |
| 6379 | Redis | Cache (internal only) |
Network Requirements
Firewall Rules:
- Allow inbound on ports 3000, 8080, 8082 (as needed)
- Allow outbound HTTPS (443) for external integrations
- Allow internal communication between Docker containers
π¦ Installation
Step 1: Download Control Core Package
Access your Control Core account and download your personalized Kickstart package:
# Download your package (replace with your actual user ID)
wget https://downloads.controlcore.io/packages/kickstart-{your-user-id}.zip
# Alternative: Use your provided download link
curl -O <your-download-link>
# Extract the package
unzip kickstart-{your-user-id}.zip
cd kickstart-{your-user-id}
The package contains:
docker-compose.yml- Docker Compose configuration.env.example- Environment variable templatesetup.sh- Setup scriptstart.sh- Startup scriptstop.sh- Shutdown scriptREADME.md- Quick reference guide
Step 2: Install Docker and Docker Compose
Ubuntu/Debian:
# Update package index
sudo apt-get update
# Install dependencies
sudo apt-get install -y \
ca-certificates \
curl \
gnupg \
lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up the repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Add your user to docker group
sudo usermod -aG docker $USER
newgrp docker
# Verify installation
docker --version
docker compose version
macOS:
# Install Docker Desktop for Mac
# Download from: https://www.docker.com/products/docker-desktop/
# Or use Homebrew
brew install --cask docker
# Start Docker Desktop and verify
docker --version
docker compose version
CentOS/RHEL:
# Install Docker
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker
# Add user to docker group
sudo usermod -aG docker $USER
Step 3: Configure Environment
Create your environment configuration file:
# Copy the example environment file
cp .env.example .env
# Edit with your preferred editor
nano .env
Key Configuration Options:
# ============================================
# CORE CONFIGURATION
# ============================================
# Tenant Configuration
TENANT_ID=your-organization-name
ENVIRONMENT=production # or development, staging
# API Keys (generate secure random strings)
API_KEY=your-secure-api-key-here
SECRET_KEY=$(openssl rand -base64 32)
JWT_SECRET_KEY=$(openssl rand -base64 32)
# ============================================
# ADMIN ACCOUNT (REQUIRED - Change default password)
# ============================================
CC_BUILTIN_ADMIN_USER=admin
CC_BUILTIN_ADMIN_PASS=ChangeThisSecurePassword123!
# ============================================
# POLICY ADMINISTRATION CONSOLE
# ============================================
CONSOLE_PORT=3000
CONSOLE_HOST=0.0.0.0
# ============================================
# POLICY ADMINISTRATION API
# ============================================
API_PORT=8082
API_HOST=0.0.0.0
API_WORKERS=4
# Admin Account (set strong credentials)
CC_BUILTIN_ADMIN_USER=admin
CC_BUILTIN_ADMIN_PASS=ChangeThisSecurePassword123!
# ============================================
# POLICY ENFORCEMENT POINT (BOUNCER)
# ============================================
BOUNCER_PORT=8080
BOUNCER_HOST=0.0.0.0
# Target application to protect
TARGET_HOST=your-app.example.com:8000
# Caching Configuration
CACHE_ENABLED=true
CACHE_TTL=5m
CACHE_MAX_SIZE=1000
# ============================================
# DATABASE CONFIGURATION
# ============================================
DATABASE_HOST=control-core-db
DATABASE_PORT=5432
DATABASE_NAME=control_core_db
DATABASE_USER=controlcore
DATABASE_PASSWORD=ChangeThisDatabasePassword123!
# Connection Pool
DATABASE_POOL_SIZE=20
DATABASE_MAX_OVERFLOW=10
# Full connection string (auto-generated)
DATABASE_URL=postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}
# ============================================
# REDIS CONFIGURATION
# ============================================
REDIS_HOST=control-core-redis
REDIS_PORT=6379
REDIS_PASSWORD=ChangeThisRedisPassword123!
REDIS_DB=0
# Full connection string
REDIS_URL=redis://:${REDIS_PASSWORD}@${REDIS_HOST}:${REDIS_PORT}/${REDIS_DB}
# ============================================
# POLICY SYNCHRONIZATION
# ============================================
POLICY_SYNC_URL=http://control-core-bridge:7000
POLICY_SYNC_PORT=7000
# ============================================
# GITHUB REPOSITORY CONFIGURATION (REQUIRED)
# ============================================
# GitHub Personal Access Token
# Create at: https://github.com/settings/tokens
# Required scopes: repo, read:org (for private repos)
GITHUB_TOKEN=ghp_your_github_personal_access_token_here
# Policy Repository URL
POLICY_REPO_URL=https://github.com/your-org/control-core-policies
# Policy Repository Branch (default: main)
POLICY_REPO_BRANCH=main
# Policy Repository Polling Interval (seconds)
POLICY_REPO_POLLING_INTERVAL=30
# ============================================
# BOUNCER API KEYS (REQUIRED)
# ============================================
# Generate in Control Plane: Settings β Environments
# Sandbox Environment API Key
BOUNCER_SANDBOX_API_KEY=sk_test_your_sandbox_api_key_here
# Production Environment API Key
BOUNCER_PRODUCTION_API_KEY=sk_live_your_production_api_key_here
# ============================================
# CONTROL PLANE URLS (REQUIRED)
# ============================================
# Public URL for Control Plane UI
PAP_API_PUBLIC_URL=https://controlplane.yourcompany.com
# Internal API URL (for container communication)
PAP_API_URL=http://control-plane-api:8000
# ============================================
# OIDC CONFIGURATION (Optional)
# ============================================
OIDC_ENABLED=false
OIDC_PROVIDER_URL=https://your-oidc-provider.com
OIDC_CLIENT_ID=your-client-id
OIDC_CLIENT_SECRET=your-client-secret
OIDC_REDIRECT_URI=https://controlplane.yourcompany.com/auth/callback
# ============================================
# OAUTH CONFIGURATION (Optional)
# ============================================
OAUTH_REDIRECT_URI=https://controlplane.yourcompany.com/oauth/callback
OAUTH_REDIRECT_URI_TEMPLATE=https://controlplane.yourcompany.com/oauth/callback/{provider}
# ============================================
# LOGGING CONFIGURATION
# ============================================
LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_FORMAT=json # json or text
LOG_OUTPUT=stdout # stdout or file
# File logging (if LOG_OUTPUT=file)
LOG_FILE_PATH=/var/log/controlcore/app.log
LOG_FILE_MAX_SIZE=100MB
LOG_FILE_RETENTION=30 # days
# ============================================
# SECURITY CONFIGURATION
# ============================================
# CORS Settings
CORS_ALLOWED_ORIGINS=http://localhost:3000,https://yourdomain.com
CORS_ALLOW_CREDENTIALS=true
# Session Configuration
SESSION_TIMEOUT=28800 # 8 hours in seconds
SESSION_COOKIE_SECURE=true # Set to false for HTTP (dev only)
SESSION_COOKIE_HTTPONLY=true
# Rate Limiting
RATE_LIMIT_ENABLED=true
RATE_LIMIT_REQUESTS=1000
RATE_LIMIT_WINDOW=3600 # seconds
# ============================================
# AUTH0 INTEGRATION (Optional)
# ============================================
AUTH0_ENABLED=false
AUTH0_DOMAIN=your-domain.auth0.com
AUTH0_CLIENT_ID=your-client-id
AUTH0_CLIENT_SECRET=your-client-secret
AUTH0_AUDIENCE=https://api.controlcore.io
# ============================================
# MONITORING CONFIGURATION
# ============================================
METRICS_ENABLED=true
METRICS_PORT=9090
HEALTH_CHECK_ENABLED=true
HEALTH_CHECK_INTERVAL=30 # seconds
# ============================================
# BACKUP CONFIGURATION
# ============================================
BACKUP_ENABLED=true
BACKUP_SCHEDULE="0 2 * * *" # Daily at 2 AM (cron format)
BACKUP_RETENTION_DAYS=30
BACKUP_PATH=/var/backups/controlcore
Security Best Practices:
- Generate Strong Passwords:
# Generate secure random passwords
openssl rand -base64 32
- Protect Sensitive Files:
chmod 600 .env
- Never Commit
.envto Version Control:
echo ".env" >> .gitignore
Step 4: Run Setup Script
The setup script initializes the database and prepares the environment:
# Make scripts executable
chmod +x setup.sh start.sh stop.sh
# Run setup
./setup.sh
The setup script will:
- Validate Docker installation
- Check port availability
- Pull required Docker images
- Initialize database schema
- Create admin user
- Set up initial configuration
- Validate the installation
Expected Output:
[β] Docker installation validated
[β] Docker Compose installation validated
[β] Port availability checked
[β] Pulling Docker images...
[β] Database initialized
[β] Admin user created
[β] Configuration validated
[β] Setup completed successfully!
Step 5: Start Control Core
Start all Control Core services:
# Start services
./start.sh
# Or manually with Docker Compose
docker-compose up -d
Verify Services are Running:
# Check all services
docker-compose ps
# Expected output shows all services as "Up"
NAME STATUS PORTS
control-core-console Up 0.0.0.0:3000->3000/tcp
control-core-api Up 0.0.0.0:8082->8082/tcp
control-core-bouncer Up 0.0.0.0:8080->8080/tcp
policy-bridge Up 0.0.0.0:7000->7000/tcp
control-core-db Up 5432/tcp
control-core-redis Up 6379/tcp
Step 6: Verify Installation
1. Health Check Endpoints:
# Check Policy Administration Console
curl http://localhost:3000/api/health
# Expected: {"status": "healthy"}
# Check Policy Administration API
curl http://localhost:8082/api/v1/health
# Expected: {"status": "healthy", "database": "connected", "redis": "connected"}
# Check Policy Enforcement Point
curl http://localhost:8080/health
# Expected: {"status": "healthy", "policy-bridge": "connected"}
# Check Policy Synchronization Server
curl http://localhost:7000/health
# Expected: {"status": "healthy"}
2. Access Services:
-
Policy Administration Console: http://localhost:3000
- Login with admin credentials from
.envfile - You should see the dashboard
- Login with admin credentials from
-
API Documentation: http://localhost:8082/devdocs
- Interactive Swagger UI documentation
- Test API endpoints
3. Check Logs:
# View all logs
docker-compose logs
# Follow logs for specific service
docker-compose logs -f control-core-api
# Check for errors
docker-compose logs | grep ERROR
π Cloud Deployment Options
The Kickstart deployment can be hosted on any cloud provider or on-premises infrastructure. This section provides examples for popular cloud platforms.
AWS EC2 Deployment
Deploy Control Core on Amazon EC2 instances:
1. Launch EC2 Instance:
# Create instance (using AWS CLI)
aws ec2 run-instances \
--image-id ami-0c55b159cbfafe1f0 \ # Ubuntu 22.04 LTS
--instance-type t3.medium \ # 4GB RAM, 2 vCPU
--key-name your-key-pair \
--security-group-ids sg-xxxxxxxxx \
--subnet-id subnet-xxxxxxxxx \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":30,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=control-core-kickstart}]'
2. Configure Security Group:
| Type | Protocol | Port Range | Source |
|---|---|---|---|
| SSH | TCP | 22 | Your IP/CIDR |
| HTTP | TCP | 3000 | Your IP/CIDR |
| HTTP | TCP | 8080 | Your IP/CIDR |
| HTTP | TCP | 8082 | Your IP/CIDR |
| HTTPS | TCP | 443 | 0.0.0.0/0 |
3. Connect and Install:
# SSH into instance
ssh -i your-key.pem ubuntu@<instance-public-ip>
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker ubuntu
# Download and setup Control Core
wget https://downloads.controlcore.io/packages/kickstart-{your-user-id}.zip
unzip kickstart-{your-user-id}.zip
cd kickstart-{your-user-id}
# Configure for cloud deployment
cp .env.example .env
# Edit .env to set PUBLIC_URL to your instance's public IP or domain
# Start Control Core
./start.sh
4. Set up Elastic IP (Optional):
# Allocate Elastic IP
aws ec2 allocate-address --domain vpc
# Associate with instance
aws ec2 associate-address \
--instance-id i-xxxxxxxxx \
--allocation-id eipalloc-xxxxxxxxx
5. Configure Route 53 DNS (Optional):
# Create DNS record
aws route53 change-resource-record-sets \
--hosted-zone-id Z1234567890ABC \
--change-batch '{
"Changes": [{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "controlcore.yourdomain.com",
"Type": "A",
"TTL": 300,
"ResourceRecords": [{"Value": "your-elastic-ip"}]
}
}]
}'
Google Cloud Platform (GCP) Deployment
Deploy Control Core on Google Compute Engine:
1. Create Compute Instance:
# Create instance (using gcloud CLI)
gcloud compute instances create control-core-kickstart \
--zone=us-central1-a \
--machine-type=e2-medium \ # 4GB RAM, 2 vCPU
--image-family=ubuntu-2204-lts \
--image-project=ubuntu-os-cloud \
--boot-disk-size=30GB \
--boot-disk-type=pd-ssd \
--tags=controlcore \
--metadata=startup-script='#!/bin/bash
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh'
2. Configure Firewall Rules:
# Create firewall rule
gcloud compute firewall-rules create allow-controlcore \
--direction=INGRESS \
--priority=1000 \
--network=default \
--action=ALLOW \
--rules=tcp:3000,tcp:8080,tcp:8082,tcp:443 \
--source-ranges=0.0.0.0/0 \
--target-tags=controlcore
3. Connect and Install:
# SSH into instance
gcloud compute ssh control-core-kickstart --zone=us-central1-a
# Download and setup Control Core
wget https://downloads.controlcore.io/packages/kickstart-{your-user-id}.zip
unzip kickstart-{your-user-id}.zip
cd kickstart-{your-user-id}
# Configure
cp .env.example .env
# Edit .env with instance's external IP
# Start
./start.sh
4. Reserve Static IP (Optional):
# Reserve static IP
gcloud compute addresses create control-core-ip --region=us-central1
# Assign to instance
gcloud compute instances delete-access-config control-core-kickstart \
--zone=us-central1-a
gcloud compute instances add-access-config control-core-kickstart \
--zone=us-central1-a \
--address=$(gcloud compute addresses describe control-core-ip --region=us-central1 --format='value(address)')
5. Configure Cloud DNS (Optional):
# Create DNS record
gcloud dns record-sets create controlcore.yourdomain.com. \
--zone=your-dns-zone \
--type=A \
--ttl=300 \
--rrdatas=your-static-ip
Microsoft Azure Deployment
Deploy Control Core on Azure Virtual Machines:
1. Create Resource Group and VM:
# Create resource group
az group create \
--name controlcore-rg \
--location eastus
# Create VM
az vm create \
--resource-group controlcore-rg \
--name control-core-kickstart \
--image Ubuntu2204 \
--size Standard_B2s \ # 4GB RAM, 2 vCPU
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard \
--os-disk-size-gb 30
2. Open Network Ports:
# Open ports
az vm open-port \
--resource-group controlcore-rg \
--name control-core-kickstart \
--port 3000 --priority 1001
az vm open-port \
--resource-group controlcore-rg \
--name control-core-kickstart \
--port 8080 --priority 1002
az vm open-port \
--resource-group controlcore-rg \
--name control-core-kickstart \
--port 8082 --priority 1003
az vm open-port \
--resource-group controlcore-rg \
--name control-core-kickstart \
--port 443 --priority 1004
3. Connect and Install:
# Get public IP
PUBLIC_IP=$(az vm show \
--resource-group controlcore-rg \
--name control-core-kickstart \
--show-details \
--query publicIps \
--output tsv)
# SSH into VM
ssh azureuser@$PUBLIC_IP
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker azureuser
# Download and setup Control Core
wget https://downloads.controlcore.io/packages/kickstart-{your-user-id}.zip
unzip kickstart-{your-user-id}.zip
cd kickstart-{your-user-id}
# Configure
cp .env.example .env
# Edit .env with VM's public IP
# Start
./start.sh
4. Create Static Public IP (Optional):
# Create static IP
az network public-ip create \
--resource-group controlcore-rg \
--name control-core-ip \
--sku Standard \
--allocation-method Static
# Associate with VM's NIC
NIC_ID=$(az vm show \
--resource-group controlcore-rg \
--name control-core-kickstart \
--query 'networkProfile.networkInterfaces[0].id' \
--output tsv)
az network nic ip-config update \
--resource-group controlcore-rg \
--nic-name $(basename $NIC_ID) \
--name ipconfig1 \
--public-ip-address control-core-ip
5. Configure Azure DNS (Optional):
# Create DNS record
az network dns record-set a add-record \
--resource-group your-dns-rg \
--zone-name yourdomain.com \
--record-set-name controlcore \
--ipv4-address your-static-ip
DigitalOcean Deployment
Deploy Control Core on a DigitalOcean Droplet:
1. Create Droplet:
# Using doctl (DigitalOcean CLI)
doctl compute droplet create control-core-kickstart \
--image ubuntu-22-04-x64 \
--size s-2vcpu-4gb \ # 4GB RAM, 2 vCPU
--region nyc1 \
--ssh-keys your-ssh-key-id \
--enable-monitoring \
--enable-ipv6
2. Configure Firewall:
# Create firewall
doctl compute firewall create \
--name controlcore-fw \
--inbound-rules "protocol:tcp,ports:22,sources:addresses:0.0.0.0/0 protocol:tcp,ports:3000,sources:addresses:0.0.0.0/0 protocol:tcp,ports:8080,sources:addresses:0.0.0.0/0 protocol:tcp,ports:8082,sources:addresses:0.0.0.0/0 protocol:tcp,ports:443,sources:addresses:0.0.0.0/0" \
--outbound-rules "protocol:tcp,ports:all,destinations:addresses:0.0.0.0/0 protocol:udp,ports:all,destinations:addresses:0.0.0.0/0" \
--droplet-ids $(doctl compute droplet list --format ID --no-header)
3. Connect and Install:
# SSH into droplet
ssh root@<droplet-ip>
# Install Docker
curl -fsSL https://get.docker.com | sh
# Download and setup Control Core
wget https://downloads.controlcore.io/packages/kickstart-{your-user-id}.zip
unzip kickstart-{your-user-id}.zip
cd kickstart-{your-user-id}
# Configure
cp .env.example .env
# Edit .env with droplet's public IP
# Start
./start.sh
4. Configure DNS (Optional):
# Create DNS record using DigitalOcean DNS
doctl compute domain records create yourdomain.com \
--record-type A \
--record-name controlcore \
--record-data <droplet-ip> \
--record-ttl 3600
Linode Deployment
Deploy Control Core on a Linode instance:
1. Create Linode:
# Using Linode CLI
linode-cli linodes create \
--label control-core-kickstart \
--image linode/ubuntu22.04 \
--region us-east \
--type g6-standard-2 \ # 4GB RAM, 2 vCPU
--root_pass 'your-strong-password' \
--authorized_keys "$(cat ~/.ssh/id_rsa.pub)"
2. Configure Firewall:
# Create firewall
linode-cli firewalls create \
--label controlcore-firewall \
--rules.inbound '[
{"protocol": "TCP", "ports": "22", "addresses": {"ipv4": ["0.0.0.0/0"]}},
{"protocol": "TCP", "ports": "3000", "addresses": {"ipv4": ["0.0.0.0/0"]}},
{"protocol": "TCP", "ports": "8080", "addresses": {"ipv4": ["0.0.0.0/0"]}},
{"protocol": "TCP", "ports": "8082", "addresses": {"ipv4": ["0.0.0.0/0"]}},
{"protocol": "TCP", "ports": "443", "addresses": {"ipv4": ["0.0.0.0/0"]}}
]' \
--rules.outbound '[
{"protocol": "TCP", "ports": "1-65535", "addresses": {"ipv4": ["0.0.0.0/0"]}},
{"protocol": "UDP", "ports": "1-65535", "addresses": {"ipv4": ["0.0.0.0/0"]}}
]'
# Attach firewall to Linode
linode-cli firewalls devices-create <firewall-id> --id <linode-id>
3. Connect and Install:
# SSH into Linode
ssh root@<linode-ip>
# Install Docker
curl -fsSL https://get.docker.com | sh
# Download and setup Control Core
wget https://downloads.controlcore.io/packages/kickstart-{your-user-id}.zip
unzip kickstart-{your-user-id}.zip
cd kickstart-{your-user-id}
# Configure
cp .env.example .env
# Edit .env with Linode's public IP
# Start
./start.sh
On-Premises Deployment
Deploy Control Core on your own hardware:
Requirements:
- Physical server or VM with Ubuntu 22.04 LTS
- 4GB RAM minimum, 8GB recommended
- 2 CPU cores minimum, 4 recommended
- 30GB disk space minimum
- Static IP address or internal DNS
- Network access to required ports
Installation Steps:
- Prepare Server:
# Update system
sudo apt update && sudo apt upgrade -y
# Install required packages
sudo apt install -y curl wget unzip
# Install Docker
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
- Configure Network:
- Ensure firewall allows ports 3000, 8080, 8082, 443
- Configure static IP or DHCP reservation
- Set up internal DNS if needed
- Deploy Control Core:
# Download package
wget https://downloads.controlcore.io/packages/kickstart-{your-user-id}.zip
unzip kickstart-{your-user-id}.zip
cd kickstart-{your-user-id}
# Configure
cp .env.example .env
# Edit .env with your server's IP or domain
# Start
./start.sh
- Configure Reverse Proxy (Optional):
If using NGINX as reverse proxy:
server {
listen 80;
server_name controlcore.yourdomain.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name controlcore.yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Console
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# API
location /api/ {
proxy_pass http://localhost:8082/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Bouncer (optional, if exposing directly)
location /bouncer/ {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Cloud Deployment Best Practices
1. Use Managed Databases (Optional):
- Replace PostgreSQL container with managed service
- Replace Redis container with managed cache
- Update connection strings in
.env
2. Set Up Backups:
- Configure automated backups to cloud storage (S3, GCS, Azure Blob)
- Test restoration procedures
- Maintain off-site backups
3. Enable Monitoring:
- Use cloud provider monitoring (CloudWatch, Cloud Monitoring, Azure Monitor)
- Set up alerts for resource utilization
- Monitor application logs
4. Configure Auto-Start:
- Set up systemd service for automatic restart
- Configure health checks
- Enable auto-recovery
5. Security Hardening:
- Use security groups/firewall rules to restrict access
- Enable SSL/TLS with valid certificates
- Configure VPN or private networking
- Regular security updates
6. Cost Optimization:
- Use reserved instances for long-term deployments
- Enable auto-shutdown for non-production environments
- Monitor and optimize resource usage
- Use appropriate instance sizes
π Initial Configuration
Create Your First Policy
-
Log in to Policy Administration Console:
- Navigate to http://localhost:3000
- Enter admin credentials
-
Create a Policy:
- Click Policies β Create Policy
- Enter policy details:
- Name:
api-basic-auth - Description: Basic API authentication
- Environment: Sandbox
- Name:
-
Add Policy Code:
package controlcore.policy
import rego.v1
default allow := false
# Allow requests with valid API key
allow if {
input.request.headers["X-API-Key"]
input.request.headers["X-API-Key"] == data.api_keys[input.user.id]
}
# Allow admin users
allow if {
input.user.roles[_] == "admin"
}
-
Test the Policy:
- Click Test tab
- Add test cases
- Run tests to verify
-
Deploy:
- Click Deploy β Deploy to Sandbox
- Test in sandbox environment
- Promote to production when ready
Configure GitHub Repository
-
Create GitHub Repository:
- Create a new repository (public or private) on GitHub
- Repository name:
control-core-policies(or your preferred name) - Initialize with a
README.md
-
Create GitHub Personal Access Token:
- Go to GitHub Settings β Developer settings β Personal access tokens β Tokens (classic)
- Click Generate new token (classic)
- Configure token:
- Note:
Control Core Policy Repository Access - Expiration: Choose appropriate expiration
- Scopes: β
repo, βread:org(for private org repos)
- Note:
- Click Generate token and copy it immediately
-
Configure in Control Plane:
- Navigate to Settings β Controls Repository
- Enter repository details:
- Repository URL:
https://github.com/your-org/control-core-policies - Branch:
main - Access Token: Paste your GitHub Personal Access Token
- Repository URL:
- Click Test Connection
- Click Save
Configure Protected Resources
Resources are automatically discovered when bouncers register. You can also manually register:
-
Add a Resource:
- Click Resources β Add Resource
- Enter resource details:
- Name: Your API name
- Type: API (or
webapp,service, etc.) - URL:
https://your-api.example.com - Environment:
SandboxorProduction - Security Posture:
deny-all(recommended)
-
Configure Bouncer for Auto-Registration:
Edit .env file:
# Bouncer Identity
BOUNCER_ID=my-api-bouncer-sandbox
BOUNCER_NAME=My API Bouncer (Sandbox)
# Resource Information (for auto-discovery)
RESOURCE_NAME=Your API name # Must match resource name
RESOURCE_TYPE=api
ORIGINAL_HOST_URL=https://your-api.example.com
TARGET_HOST=your-api.example.com:8000
ENVIRONMENT=sandbox # or "production"
# Control Plane Connection
PAP_API_URL=https://controlplane.yourcompany.com/api
API_KEY=sk_test_your_sandbox_api_key_here
TENANT_ID=your-organization-name
Restart Bouncer:
docker-compose restart control-core-bouncer
- Test Protected Endpoint:
# Request through Bouncer (should be protected)
curl -X GET http://localhost:8080/api/v1/data \
-H "X-API-Key: your-api-key"
# Should receive policy decision
# Check audit logs in Control Plane to verify
π€ Monitoring and Maintenance
Health Monitoring
Set Up Regular Health Checks:
#!/bin/bash
# health-check.sh
SERVICES=("console:3000" "api:8082" "bouncer:8080" "policy-bridge:7000")
for service in "${SERVICES[@]}"; do
name=$(echo $service | cut -d: -f1)
port=$(echo $service | cut -d: -f2)
if curl -sf http://localhost:$port/health > /dev/null; then
echo "[β] $name is healthy"
else
echo "[β] $name is down"
# Send alert
fi
done
Add to Cron:
# Run health check every 5 minutes
*/5 * * * * /path/to/health-check.sh
Log Management
View Logs:
# All services
docker-compose logs
# Specific service with timestamps
docker-compose logs -f --timestamps control-core-api
# Last 100 lines
docker-compose logs --tail=100 control-core-bouncer
# Filter by log level
docker-compose logs | grep ERROR
docker-compose logs | grep WARNING
Configure Log Rotation:
Create /etc/logrotate.d/controlcore:
/var/lib/docker/containers/*/*.log {
rotate 7
daily
compress
size=10M
missingok
delaycompress
copytruncate
}
Database Maintenance
Backup Database:
# Manual backup
docker-compose exec control-core-db pg_dump -U controlcore control_core_db > backup_$(date +%Y%m%d).sql
# Compressed backup
docker-compose exec control-core-db pg_dump -U controlcore control_core_db | gzip > backup_$(date +%Y%m%d).sql.gz
# Backup script
#!/bin/bash
# backup-database.sh
BACKUP_DIR="/var/backups/controlcore"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/controlcore_$DATE.sql.gz"
mkdir -p $BACKUP_DIR
docker-compose exec -T control-core-db pg_dump -U controlcore control_core_db | \
gzip > $BACKUP_FILE
# Keep only last 30 days
find $BACKUP_DIR -name "controlcore_*.sql.gz" -mtime +30 -delete
echo "Backup completed: $BACKUP_FILE"
Automated Backups with Cron:
# Add to crontab
0 2 * * * /path/to/backup-database.sh
Restore from Backup:
# Decompress and restore
gunzip < backup_20250122.sql.gz | \
docker-compose exec -T control-core-db psql -U controlcore control_core_db
# Or from uncompressed backup
docker-compose exec -T control-core-db psql -U controlcore control_core_db < backup_20250122.sql
Database Performance Monitoring:
# Connect to database
docker-compose exec control-core-db psql -U controlcore control_core_db
# Check database size
SELECT pg_size_pretty(pg_database_size('control_core_db'));
# Check table sizes
SELECT
schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables
WHERE schemaname = 'public'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
# Check for slow queries
SELECT
query,
calls,
mean_exec_time,
max_exec_time
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;
# Vacuum and analyze
VACUUM ANALYZE;
Redis Monitoring
Check Redis Status:
# Connect to Redis
docker-compose exec control-core-redis redis-cli -a $REDIS_PASSWORD
# Get info
INFO
# Check memory usage
INFO memory
# Check connected clients
CLIENT LIST
# Monitor commands in real-time
MONITOR
# Check key statistics
DBSIZE
# Inspect specific keys
KEYS policy:*
GET policy:api-basic-auth
Clear Cache:
# Clear all cache
docker-compose exec control-core-redis redis-cli -a $REDIS_PASSWORD FLUSHALL
# Clear specific pattern
docker-compose exec control-core-redis redis-cli -a $REDIS_PASSWORD \
--scan --pattern "policy:*" | \
xargs docker-compose exec control-core-redis redis-cli -a $REDIS_PASSWORD DEL
Performance Monitoring
Resource Usage:
# Monitor container resources
docker stats
# Continuous monitoring
watch -n 2 docker stats --no-stream
# Specific service
docker stats control-core-api
# System resource usage
top
htop
Set Resource Limits (edit docker-compose.yml):
services:
control-core-api:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
π Backup and Recovery
Full System Backup
Backup Script:
#!/bin/bash
# full-backup.sh
BACKUP_DIR="/var/backups/controlcore"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_PATH="$BACKUP_DIR/$DATE"
mkdir -p $BACKUP_PATH
# Backup database
docker-compose exec -T control-core-db pg_dump -U controlcore control_core_db | \
gzip > $BACKUP_PATH/database.sql.gz
# Backup configuration
cp .env $BACKUP_PATH/
cp docker-compose.yml $BACKUP_PATH/
# Backup volumes
docker run --rm \
-v control-core-data:/data \
-v $BACKUP_PATH:/backup \
alpine tar czf /backup/volumes.tar.gz /data
# Create manifest
cat > $BACKUP_PATH/manifest.txt <<EOF
Backup Date: $(date)
Database: β
Configuration: β
Volumes: β
EOF
echo "Full backup completed: $BACKUP_PATH"
Disaster Recovery
Recovery Procedure:
#!/bin/bash
# restore-backup.sh
BACKUP_PATH="/var/backups/controlcore/20250122_020000"
# Stop services
./stop.sh
# Restore configuration
cp $BACKUP_PATH/.env .
cp $BACKUP_PATH/docker-compose.yml .
# Restore volumes
docker run --rm \
-v control-core-data:/data \
-v $BACKUP_PATH:/backup \
alpine tar xzf /backup/volumes.tar.gz -C /
# Start database only
docker-compose up -d control-core-db control-core-redis
# Wait for database
sleep 10
# Restore database
gunzip < $BACKUP_PATH/database.sql.gz | \
docker-compose exec -T control-core-db psql -U controlcore control_core_db
# Start all services
./start.sh
echo "Recovery completed"
π Updating Control Core
Update Procedure
# 1. Backup current installation
./full-backup.sh
# 2. Download new version
wget https://downloads.controlcore.io/packages/kickstart-{your-user-id}-v2.0.0.zip
# 3. Stop services
./stop.sh
# 4. Extract update
unzip kickstart-{your-user-id}-v2.0.0.zip -d update
# 5. Review changes
diff docker-compose.yml update/docker-compose.yml
# 6. Backup current files
cp docker-compose.yml docker-compose.yml.backup
cp .env .env.backup
# 7. Apply update
cp update/docker-compose.yml .
# Merge any new .env variables
# 8. Pull new images
docker-compose pull
# 9. Run migrations (if needed)
docker-compose run --rm control-core-api alembic upgrade head
# 10. Start services
./start.sh
# 11. Verify update
docker-compose ps
curl http://localhost:8082/api/v1/version
π οΈ Troubleshooting
Services Won't Start
Check Port Conflicts:
# Check if ports are in use
netstat -tulpn | grep :3000
netstat -tulpn | grep :8080
netstat -tulpn | grep :8082
# Find process using port
lsof -i :3000
# Kill process if needed
kill -9 <PID>
Check Docker Status:
# Verify Docker is running
systemctl status docker
# Start Docker if needed
sudo systemctl start docker
# Check Docker resources
docker system df
docker system info
Check Logs for Errors:
docker-compose logs | grep -i error
docker-compose logs control-core-api
Database Connection Issues
Verify Database is Running:
docker-compose ps control-core-db
docker-compose logs control-core-db
Test Database Connection:
docker-compose exec control-core-db psql -U controlcore -d control_core_db -c "SELECT 1"
Reset Database:
# WARNING: This deletes all data
docker-compose down -v
docker-compose up -d control-core-db control-core-redis
sleep 10
./setup.sh
Performance Issues
Check Resource Usage:
docker stats
free -h
df -h
Optimize Database:
docker-compose exec control-core-db psql -U controlcore control_core_db -c "VACUUM ANALYZE"
Clear Cache:
docker-compose exec control-core-redis redis-cli -a $REDIS_PASSWORD FLUSHALL
docker-compose restart control-core-bouncer
π Security Hardening
SSL/TLS Configuration
Using Let's Encrypt with Nginx:
- Install Certbot:
sudo apt-get install certbot python3-certbot-nginx
- Create Nginx configuration (
/etc/nginx/sites-available/controlcore):
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Policy Administration Console
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Policy Administration API
location /api/ {
proxy_pass http://localhost:8082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
- Obtain certificate:
sudo certbot --nginx -d your-domain.com
Firewall Configuration
Using UFW (Ubuntu):
# Enable firewall
sudo ufw enable
# Allow SSH
sudo ufw allow ssh
# Allow HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
# Allow Control Core services (if needed externally)
sudo ufw allow 8080/tcp # Bouncer
sudo ufw allow 8082/tcp # API
# Check status
sudo ufw status
π Next Steps
- Administrator Guide: Learn how to manage users and policies
- User Guide: Master policy creation
- Pro Deployment: Consider upgrading to Pro
- Troubleshooting: Common issues and solutions
π Support
- Documentation: Documentation Home
- Community: GitHub Discussions
- Email: support@controlcore.io