Deployment Patterns
Step-by-step deployment guides for every supported target: AKS, EKS, GKE, on-premises Kubernetes, multi-region active-passive, and Docker Compose for local development.
Choosing a Deployment Pattern
Aegis Sovereign runs on any CNCF-conformant Kubernetes distribution. All patterns use the same Helm chart — only the values override file and the secret key provider differ. Choose the pattern that matches your cloud provider and data residency requirements.
| Pattern | Secret provider | Ingress | Best for |
|---|---|---|---|
| AKS (Azure) | Azure Key Vault via CSI driver | AGIC / nginx | Enterprises on Azure, Azure AD SSO |
| EKS (AWS) | AWS Secrets Manager via IRSA | AWS ALB / nginx | Enterprises on AWS, Cognito / Okta |
| GKE (Google Cloud) | GCP Secret Manager via Workload Identity | Cloud Load Balancing / nginx | Enterprises on GCP, Google Workspace |
| On-Premises / Air-Gapped | HashiCorp Vault | MetalLB + nginx | Banks, defence, no internet egress |
| Multi-Region Active-Passive | Primary KMS + standby replica | Global DNS failover | 99.9%+ SLA, regulatory data residency |
| Docker Compose (Dev) | `.env` file | localhost | Local development, sandbox testing |
Pattern 1 — Azure Kubernetes Service (AKS)
This pattern uses AKS with Azure Active Directory for SSO, Azure Key Vault for the encryption key, and cert-manager with Let's Encrypt for TLS. The Helm chart pre-upgrade hook runs database migrations before any pod restarts.
1# Create resource group + AKS cluster (system node pool)
2az group create --name rg-aegissovereign --location eastus
3az aks create \
4 --resource-group rg-aegissovereign \
5 --name aks-aegissovereign \
6 --node-count 3 --node-vm-size Standard_D4s_v5 \
7 --enable-workload-identity --enable-oidc-issuer \
8 --enable-addons azure-keyvault-secrets-provider \
9 --attach-acr sovereignregistry
10
11# Create Key Vault + encryption key secret
12az keyvault create --name kv-aegissovereign --resource-group rg-aegissovereign --location eastus
13az keyvault secret set --vault-name kv-aegissovereign --name sovereign-encryption-key \
14 --value "$(openssl rand -hex 32)"
15
16# Grant AKS managed identity access to Key Vault
17AKS_IDENTITY=$(az aks show -g rg-aegissovereign -n aks-aegissovereign --query identityProfile.kubeletidentity.clientId -o tsv)
18az keyvault set-policy --name kv-aegissovereign --spn $AKS_IDENTITY --secret-permissions get1global:
2 domain: sovereign.yourcompany.com
3 provider: azure
4
5secretKeyProvider: azure_keyvault
6azureKeyVaultUrl: "https://kv-aegissovereign.vault.azure.net/"
7azureSecretName: sovereign-encryption-key
8
9ingress:
10 enabled: true
11 className: nginx
12 annotations:
13 cert-manager.io/cluster-issuer: letsencrypt-prod
14 tls:
15 - hosts: [sovereign.yourcompany.com]
16 secretName: sovereign-tls
17
18# Azure AD SSO — register an App Registration first
19oidc:
20 issuer: "https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0"
21 clientId: "YOUR_APP_CLIENT_ID"
22
23# PostgreSQL — use Azure Database for PostgreSQL Flexible Server
24postgresql:
25 external: true
26 host: sovereign-pg.postgres.database.azure.com
27 database: aegissovereign
28 existingSecret: sovereign-pg-secret
29 existingSecretPasswordKey: password
30
31# Redis — use Azure Cache for Redis
32redis:
33 external: true
34 host: sovereign-redis.redis.cache.windows.net
35 port: 6380
36 tls: true
37 existingSecret: sovereign-redis-secret1# From the Aegis Sovereign release bundle
2cd aegis-sovereign/helm
3
4helm upgrade --install aegissovereign ./sovereign-gateway \
5 --namespace aegissovereign --create-namespace \
6 --values values-aks.yaml \
7 --wait --timeout 15m
8
9# Verify all pods are running
10kubectl get pods -n aegissovereign
11kubectl logs -n aegissovereign -l app.kubernetes.io/component=api | grep "Application startup complete"Pattern 2 — AWS EKS
This pattern uses EKS with IRSA (IAM Roles for Service Accounts) to grant the platform pod access to Secrets Manager — no long-lived AWS credentials in the cluster. The ALB Ingress Controller handles TLS termination via ACM.
1# Create cluster with eksctl
2eksctl create cluster --name aegissovereign --region us-east-1 \
3 --nodegroup-name standard-workers --node-type m6i.xlarge \
4 --nodes 3 --with-oidc
5
6# Store encryption key in Secrets Manager
7aws secretsmanager create-secret --name aegissovereign/encryption-key \
8 --secret-string "$(openssl rand -hex 32)" --region us-east-1
9
10# Create IRSA role granting GetSecretValue
11eksctl create iamserviceaccount \
12 --name aegissovereign-backend \
13 --namespace aegissovereign \
14 --cluster aegissovereign \
15 --attach-policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite \
16 --approve --region us-east-11global:
2 domain: sovereign.yourcompany.com
3 provider: aws
4
5secretKeyProvider: aws_kms
6awsSecretsManagerSecretId: aegissovereign/encryption-key
7awsRegion: us-east-1
8
9serviceAccount:
10 annotations:
11 eks.amazonaws.com/role-arn: "arn:aws:iam::ACCOUNT_ID:role/aegissovereign-irsa"
12
13ingress:
14 enabled: true
15 className: alb
16 annotations:
17 kubernetes.io/ingress.class: alb
18 alb.ingress.kubernetes.io/scheme: internet-facing
19 alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:ACCOUNT_ID:certificate/CERT_ID"
20 alb.ingress.kubernetes.io/target-type: ip
21
22# RDS PostgreSQL
23postgresql:
24 external: true
25 host: sovereign.cluster-xyz.us-east-1.rds.amazonaws.com
26 database: aegissovereign
27 existingSecret: sovereign-rds-secret
28
29# ElastiCache Redis
30redis:
31 external: true
32 host: sovereign.abc123.0001.use1.cache.amazonaws.com
33 port: 6379Pattern 3 — Google Kubernetes Engine (GKE)
This pattern uses GKE Autopilot with Workload Identity Federation so the platform pod can access GCP Secret Manager without a service account key file. Cloud Load Balancing handles TLS via Google-managed certificates.
1# Create GKE Autopilot cluster
2gcloud container clusters create-auto aegissovereign \
3 --region us-central1 --release-channel regular
4
5# Create encryption key secret
6gcloud secrets create sovereign-encryption-key \
7 --replication-policy automatic
8echo -n "$(openssl rand -hex 32)" | gcloud secrets versions add sovereign-encryption-key --data-file=-
9
10# Bind GKE K8s service account to GCP service account
11gcloud iam service-accounts create aegissovereign-backend
12gcloud secrets add-iam-policy-binding sovereign-encryption-key \
13 --member "serviceAccount:aegissovereign-backend@PROJECT_ID.iam.gserviceaccount.com" \
14 --role roles/secretmanager.secretAccessor
15gcloud iam service-accounts add-iam-policy-binding \
16 aegissovereign-backend@PROJECT_ID.iam.gserviceaccount.com \
17 --member "serviceAccount:PROJECT_ID.svc.id.goog[aegissovereign/aegissovereign-backend]" \
18 --role roles/iam.workloadIdentityUser1global:
2 domain: sovereign.yourcompany.com
3 provider: gcp
4
5secretKeyProvider: gcp_secret_manager
6gcpProjectId: YOUR_PROJECT_ID
7gcpSecretName: sovereign-encryption-key
8
9serviceAccount:
10 annotations:
11 iam.gke.io/gcp-service-account: "aegissovereign-backend@YOUR_PROJECT_ID.iam.gserviceaccount.com"
12
13ingress:
14 enabled: true
15 className: gce
16 annotations:
17 networking.gke.io/managed-certificates: sovereign-cert
18 kubernetes.io/ingress.global-static-ip-name: sovereign-ip
19
20# Cloud SQL for PostgreSQL
21postgresql:
22 external: true
23 host: "127.0.0.1" # via Cloud SQL Auth Proxy sidecar
24 database: aegissovereign
25 existingSecret: sovereign-cloudsql-secret
26
27# Memorystore Redis
28redis:
29 external: true
30 host: 10.0.0.5 # private IP
31 port: 6379Pattern 4 — On-Premises / Air-Gapped
For regulated environments with no internet egress (banking, defence, healthcare). This pattern uses a private container registry, HashiCorp Vault for the encryption key, MetalLB for LoadBalancer services, and an internal CA for TLS. All images must be mirrored into your private registry before deployment.
1# Pull all required images (run on internet-connected machine)
2IMAGES=(
3 "ghcr.io/aegissovereign/sovereign-gateway:latest"
4 "postgres:16-alpine"
5 "redis:7-alpine"
6 "bitnami/cert-manager:latest"
7)
8
9for img in "${IMAGES[@]}"; do
10 docker pull "$img"
11 docker tag "$img" "registry.internal/$img"
12 docker push "registry.internal/$img"
13done
14
15# Update Helm values to use private registry
16# global.imageRegistry: "registry.internal"1global:
2 domain: sovereign.corp.internal
3 provider: onprem
4 imageRegistry: registry.internal # all images pulled from here
5
6secretKeyProvider: vault
7vaultAddr: https://vault.corp.internal:8200
8vaultToken: "" # or use K8s auth method
9vaultSecretPath: secret/data/sovereign/encryption-key
10
11ingress:
12 enabled: true
13 className: nginx
14 annotations:
15 nginx.ingress.kubernetes.io/ssl-redirect: "true"
16 tls:
17 - hosts: [sovereign.corp.internal]
18 secretName: sovereign-internal-tls # cert from internal CA
19
20# Internal CA for TLS (cert-manager with internal ClusterIssuer)
21certManager:
22 clusterIssuer: internal-ca-issuer
23
24# Internal PostgreSQL (bare-metal or VM)
25postgresql:
26 external: true
27 host: pg01.corp.internal
28 database: aegissovereign
29 existingSecret: sovereign-pg-secret
30
31# Internal Redis Sentinel
32redis:
33 external: true
34 host: redis-sentinel.corp.internal
35 port: 26379
36 sentinelMode: true
37 masterName: sovereign-master
38
39# Disable outbound telemetry
40telemetry:
41 enabled: false1# On your Vault server
2vault kv put secret/sovereign/encryption-key \
3 value="$(openssl rand -hex 32)"
4
5# Enable Kubernetes auth method (recommended over token auth)
6vault auth enable kubernetes
7vault write auth/kubernetes/config \
8 kubernetes_host="https://k8s-api.corp.internal:6443" \
9 kubernetes_ca_cert=@/etc/kubernetes/pki/ca.crt
10
11vault policy write sovereign-policy - <<EOF
12path "secret/data/sovereign/*" { capabilities = ["read"] }
13EOF
14
15vault write auth/kubernetes/role/aegissovereign-backend \
16 bound_service_account_names=aegissovereign-backend \
17 bound_service_account_namespaces=aegissovereign \
18 policies=sovereign-policy ttl=1hPattern 5 — Multi-Region Active-Passive
For organisations that require RTO < 4 hours and RPO < 1 hour across a full region loss. The primary region runs active workloads. The standby region has a scaled-down Helm release watching a PostgreSQL read replica via WAL streaming. DNS failover (Route 53 / Azure Traffic Manager / Cloud DNS) promotes the standby on a health check failure.
1global:
2 domain: sovereign.yourcompany.com
3 region: us-east-1
4 role: primary
5
6# PostgreSQL — enable WAL streaming to standby
7postgresql:
8 walArchiving:
9 enabled: true
10 walg:
11 enabled: true
12 s3Bucket: sovereign-wal-archive
13 s3Region: us-east-1
14
15replicaCount: 3 # full capacity1global:
2 domain: sovereign-standby.yourcompany.com
3 region: eu-west-1
4 role: standby
5
6postgresql:
7 standby: true
8 primaryHost: sovereign-primary.us-east-1.rds.amazonaws.com
9
10replicaCount: 1 # scaled down — scales to 3 on failover
11
12# Health check for DNS failover controller
13healthCheck:
14 path: /api/v1/health/ready
15 interval: 30s
16 failureThreshold: 31# 1. Promote standby PostgreSQL
2kubectl exec -n aegissovereign deploy/postgresql-standby -- \
3 pg_ctl promote -D /var/lib/postgresql/data
4
5# 2. Scale up standby Helm release
6helm upgrade aegissovereign aegissovereign/sovereign-gateway \
7 --namespace aegissovereign \
8 --values values-standby.yaml \
9 --set replicaCount=3 \
10 --set global.role=primary
11
12# 3. Update DNS (Route 53 example)
13aws route53 change-resource-record-sets \
14 --hosted-zone-id YOUR_ZONE_ID \
15 --change-batch '{"Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"sovereign.yourcompany.com","Type":"CNAME","TTL":60,"ResourceRecords":[{"Value":"sovereign-standby-lb.eu-west-1.elb.amazonaws.com"}]}}]}'
16
17# 4. Verify
18curl https://sovereign.yourcompany.com/api/v1/health/readyPattern 6 — Docker Compose (Local Development)
The fastest way to run the platform locally for development or sandbox testing. All services (API, Celery worker, Celery Beat, PostgreSQL, Redis) start with a single command. No Kubernetes or cloud credentials required. Not suitable for production.
1git clone https://github.com/aegissovereign/sovereign-gateway.git
2cd sovereign-gateway
3
4# Copy the development environment template
5cp .env.example .env
6
7# The defaults are safe for local use — change these for your setup:
8# PLATFORM_HOST=localhost
9# SECRET_ENCRYPTION_KEY=dev-only-key-change-in-prod
10# OPENAI_API_KEY=sk-... (or leave blank to use mock LLM responses)1docker compose up -d
2
3# Services started:
4# - sovereign-api → http://localhost:8000
5# - sovereign-worker → Celery worker (AI agents)
6# - sovereign-beat → Celery Beat (drift scans, weekly report)
7# - postgres → localhost:5432
8# - redis → localhost:6379
9
10# Watch startup logs
11docker compose logs -f sovereign-api
12
13# Access the platform
14open http://localhost:8000
15# Default admin login: admin@example.com / changeme1231# Load demo models, compliance evals, and audit events
2docker compose exec sovereign-api python manage.py seed_demo_data
3
4# This creates:
5# 5 demo models with compliance evaluations already run
6# 200+ audit chain entries
7# 3 demo workspaces: Finance, Healthcare, General
8# Pre-configured LLM gateway routing policies1# Run migrations manually
2docker compose exec sovereign-api alembic upgrade head
3
4# Open a Django/FastAPI shell
5docker compose exec sovereign-api python -c "from app.main import app; print('OK')"
6
7# Tail worker logs to see AI agent activity
8docker compose logs -f sovereign-worker
9
10# Run the test suite
11docker compose exec sovereign-api pytest tests/ -v
12
13# Stop and remove volumes (full reset)
14docker compose down -vPost-Deployment Checklist (All Patterns)
After any deployment, run through this checklist before onboarding users.
| Check | Command / Action | Expected Result |
|---|---|---|
| API liveness | `curl /api/v1/health/live` | `{ "status": "ok" }` |
| API readiness (DB + Redis) | `curl /api/v1/health/ready` | `{ "status": "ready" }` |
| Migrations complete | `kubectl logs ... | grep alembic` | `INFO [alembic] Running upgrade` |
| Celery worker online | `kubectl logs -l component=celery-worker` | `celery@pod-xyz ready.` |
| Celery Beat online | `kubectl logs -l component=celery-beat` | `beat: Starting...` |
| Encryption key resolved | `curl /api/v1/admin/key-status` | `{ "provider": "...", "resolved": true }` |
| OIDC login works | Open platform URL, click SSO button | Redirects to IdP and back |
| Audit chain genesis | `curl /api/v1/audit/verify/latest` | `{ "chain_valid": true }` |