Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Deployment

ScaiVault is a stateless container plus a PostgreSQL database, a Redis cache, and a KMS. Everything else — object storage, DNS providers, federated backends — is optional.

Prerequisites#

  • PostgreSQL 14+. Dedicated database with a dedicated user. Expect ~10 GB per 100k secrets including history.
  • Redis 7+. Single instance is fine for low-volume deployments; cluster for HA.
  • A KMS. AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault, or a PKCS#11 HSM. ScaiVault stores only a wrapped root key locally.
  • ScaiKey. An instance you control, or the managed scaikey.scailabs.ai.
  • Object storage (optional). S3-compatible. Used for large artifacts (certs, CRLs, audit exports). In-DB fallback works but limits how large those artifacts can be.

Configuration#

All configuration is via environment variables.

Core#

Variable Required Description
DATABASE_URL Yes postgresql://user:pass@host:5432/scaivault?sslmode=require
REDIS_URL Yes redis://host:6379/0 or rediss:// for TLS
SCAIKEY_URL Yes https://scaikey.scailabs.ai
SCAIKEY_JWKS_URL No Override auto-discovery
BIND_ADDRESS No Default 0.0.0.0:8443
BASE_URL Yes Your public ScaiVault URL
LOG_LEVEL No info (default), debug, warn, error
LOG_FORMAT No json (default) or text

KMS#

Pick one. Provider auth is via the cloud provider's standard mechanisms (IAM role, workload identity, etc.) unless you specify static credentials.

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# AWS KMS
KMS_PROVIDER=aws
KMS_KEY_ID=arn:aws:kms:us-east-1:123456789012:key/abcd

# GCP KMS
KMS_PROVIDER=gcp
KMS_KEY_NAME=projects/acme/locations/global/keyRings/scaivault/cryptoKeys/root

# Azure Key Vault
KMS_PROVIDER=azure
KMS_KEY_URL=https://acme.vault.azure.net/keys/scaivault-root/abc

# HashiCorp Vault Transit
KMS_PROVIDER=hashicorp
KMS_ENDPOINT=https://vault.internal:8200
KMS_KEY_NAME=scaivault-root
KMS_AUTH_TOKEN_FILE=/var/run/secrets/vault-token

# PKCS#11 HSM
KMS_PROVIDER=pkcs11
KMS_LIBRARY=/usr/lib/softhsm/libsofthsm2.so
KMS_SLOT=0
KMS_LABEL=scaivault-root
KMS_PIN_FILE=/etc/scaivault/hsm-pin

Object storage (optional)#

bash
1
2
3
4
5
6
STORAGE_PROVIDER=s3
STORAGE_BUCKET=scaivault-prod
STORAGE_REGION=us-east-1
# Static creds (optional; prefer IAM roles):
STORAGE_ACCESS_KEY_ID=...
STORAGE_SECRET_ACCESS_KEY=...

Providers: s3, gcs, azure_blob, minio.

Identity cache sync#

bash
1
2
IDENTITY_SYNC_WEBHOOK_SECRET=<shared with ScaiKey>
IDENTITY_SYNC_INTERVAL=15m  # background full-sync interval

Rate limits (optional override)#

yaml
1
2
3
4
5
6
7
RATE_LIMITS: |
  secrets:read:
    rate: 2000
    window: 1m
  secrets:write:
    rate: 200
    window: 1m

See Rate Limiting for the full list of categories.

Single-node Docker#

For development or small deployments:

bash
1
2
3
4
5
6
7
8
9
docker run -d \
  -p 8443:8443 \
  -e DATABASE_URL=postgresql://... \
  -e REDIS_URL=redis://... \
  -e SCAIKEY_URL=https://scaikey.scailabs.ai \
  -e KMS_PROVIDER=aws \
  -e KMS_KEY_ID=arn:aws:kms:... \
  -e BASE_URL=https://scaivault.example.com \
  scailabs/scaivault:1.0.0

The container runs the API on port 8443 with TLS terminated upstream. For TLS at the container, mount certs and set TLS_CERT_FILE / TLS_KEY_FILE.

Kubernetes#

A minimal Deployment:

yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
apiVersion: apps/v1
kind: Deployment
metadata:
  name: scaivault
spec:
  replicas: 3
  selector:
    matchLabels:
      app: scaivault
  template:
    metadata:
      labels:
        app: scaivault
    spec:
      serviceAccountName: scaivault  # with KMS IAM binding
      containers:
      - name: scaivault
        image: scailabs/scaivault:1.0.0
        ports:
        - containerPort: 8443
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef: {name: scaivault-db, key: url}
        - name: REDIS_URL
          valueFrom:
            secretKeyRef: {name: scaivault-redis, key: url}
        - name: SCAIKEY_URL
          value: https://scaikey.scailabs.ai
        - name: KMS_PROVIDER
          value: aws
        - name: KMS_KEY_ID
          value: arn:aws:kms:us-east-1:123:key/abc
        - name: BASE_URL
          value: https://scaivault.acme.example
        livenessProbe:
          httpGet:
            path: /v1/health
            port: 8443
            scheme: HTTPS
          initialDelaySeconds: 10
        readinessProbe:
          httpGet:
            path: /v1/health/ready
            port: 8443
            scheme: HTTPS
          periodSeconds: 5
        resources:
          requests:
            cpu: 500m
            memory: 512Mi
          limits:
            cpu: 2000m
            memory: 2Gi

3 replicas is a good starting point. Scale horizontally — ScaiVault instances are stateless.

First-boot setup#

On first boot, ScaiVault:

  1. Runs database migrations.
  2. Generates an initial encryption root (wrapped by your KMS).
  3. Creates a bootstrap super_admin user as configured by BOOTSTRAP_SUPER_ADMIN.

For production, configure:

bash
1
BOOTSTRAP_SUPER_ADMIN=user:admin@acme.example

First person signs in via ScaiKey with that email, gets promoted to super_admin automatically. After first login, set BOOTSTRAP_SUPER_ADMIN= (empty) to disable.

Database migrations#

On startup, ScaiVault checks migration state. If ahead of the schema it expects, it refuses to start. If behind, by default it migrates automatically. To run migrations as a separate step:

bash
1
2
3
docker run --rm \
  -e DATABASE_URL=... \
  scailabs/scaivault:1.0.0 migrate

Then start the API with --no-migrate (or set MIGRATE_ON_START=false).

TLS#

ScaiVault expects TLS termination. Typical setups:

  • Load balancer terminates (ALB, GLB, Traefik, nginx-ingress). ScaiVault listens HTTP internally.
  • ScaiVault terminates. Set TLS_CERT_FILE and TLS_KEY_FILE. Certs from your PKI.
  • mTLS internal. Additional TLS_CLIENT_CA_FILE forces client cert authentication on top of bearer tokens.

Scaling#

  • API pods: stateless. Scale to taste; 3 is a sensible minimum.
  • Postgres: single-writer, one or more replicas. ScaiVault can route reads to replicas with DATABASE_URL_READ=postgresql://....
  • Redis: single-instance works up to tens of thousands of concurrent identities; cluster mode beyond that.

High availability#

  • Run at least 3 API pods across failure domains.
  • Postgres streaming replication + automated failover (Patroni, Cloud SQL, RDS Multi-AZ).
  • Redis Sentinel or cluster mode.
  • KMS: use a regional key with cross-region replication; ScaiVault supports failover to a secondary key if the primary is unreachable (KMS_KEY_ID_SECONDARY).

Backup and recovery#

What to back up:

  • PostgreSQL: full + WAL.
  • Object store bucket (if used).
  • KMS key policy (so you can restore access).

What NOT to back up separately:

  • The plaintext root key — it never leaves the KMS.
  • Application container state — everything interesting is in Postgres.

Recovery test: restore DB to a staging cluster, point at a test KMS key wrapped by the same rehydrated material, verify a secret reads correctly. Do this at least annually.

What's next#

Updated 2026-05-17 13:26:51 View source (.md) rev 2