Multi-tenant OpenClaw platform on Kubernetes. Each tenant (team member) gets an isolated OpenClaw instance with per-tenant cloud storage and IAM-scoped access, behind a subdomain (jente.opencrane.ai).
ββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
β Control Plane βββββββββββΊβ Cloud SQL (Postgres) β
β admin.opencrane.ai β β org / users / state β
β Express + Prisma β ββββββββββββββββββββββββββββ€
βββββββββββββββ¬βββββββββββββ β Skills Repo β
β β versioned AI skills β
βΌ ββββββββββββββββββββββββββββ
ββββββββββββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββββββββββββ
β Cross-Repo Operator Plane β β jente.oc β β bob.oc β β Egress Control Plane β
β β β OpenClaw β β OpenClaw β β β
β - repo reconcile β β (isolated) β β (isolated) β β - outbound policy β
β - skill deployment β ββββββββββ¬ββββββββββ€ ββββββββββ¬ββββββββββ€ β - proxy / allowlists β
β - config push β β GCS β IAM | β GCS β IAM β | - secrets brokerage β
β - bootstrap sync β β bucket β+ Secret β β bucket β+ Secret β β - AI token access β
β - rollout coordination β β β Vault β β IAM β Vault β β - audit / rate limiting β
β β ββββββββββββββββββββ ββββββββββββββββββββ β - external access control β
β β ββββββββββββββββββββ β β
β β β sara.oc β β β
β β β OpenClaw β β β
β β β (isolated) β β β
β β ββββββββββ¬ββββββββββ€ β β
β β β GCS β IAM β β β
β β β bucket β+ Secret β β β
β β β β Vault β β β
ββββββββββββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββββββββββββ
- Tenant isolation: Each user runs in their own pod with a dedicated GCS bucket mounted via GCS Fuse CSI. IAM-enforced: each pod's Workload Identity service account can only access its own bucket.
- GCS-resident OpenClaw: The Docker image is a slim Node 22 runtime. OpenClaw is npm-installed into the per-tenant GCS bucket on first boot and persists across pod restarts. Tenants update independently via
openclaw update. - Credentials: Encrypted emptyDir (memory-backed) for pod-local secrets + K8s Secret for encryption key. Org-wide secrets via External Secrets Operator + GCP Secret Manager.
- Skills: Developed individually in tenant pods, promoted to team/org via a shared ReadWriteMany PVC (GCP Filestore).
- Access control: Network-level domain allowlisting via CiliumNetworkPolicy, managed by AccessPolicy CRDs.
- Observability: Structured JSON logs (pino) shipped to Cloud Logging by GKE natively. No in-cluster logging stack required.
- Dual-write: Control plane writes tenant state to both K8s CRDs (source of truth for operator) and PostgreSQL (query store for dashboard/API).
- IaC: Terraform for static infra (GKE, Cloud SQL, VPC). Crossplane for dynamic per-tenant resources (GCS buckets, IAM bindings).
Pod filesystem (ephemeral):
/data/secrets/ -- Encrypted emptyDir (pod-local secrets)
/etc/openclaw/encryption-key/ -- K8s Secret projected as file
GCS Fuse CSI mount (per-tenant bucket, IAM-scoped):
/data/openclaw/
βββ runtime/ -- OpenClaw npm install (persists across restarts)
βββ config/
βββ agents/
βββ sessions/
βββ uploads/
βββ knowledge/
Shared skills (ReadOnly PVC, GCP Filestore):
/shared-skills/ -- Org/team skills library
| Component | Path | Description |
|---|---|---|
| Helm chart | helm/opencrane/ |
K8s manifests, CRDs, operator + control plane deployments |
| Operator | operator/ |
Watches Tenant/AccessPolicy CRDs, reconciles per-tenant resources |
| Control Plane | control-plane/ |
Express REST API with Prisma ORM for tenant/skill/policy management |
| Docker | docker/ |
Container images for tenant pods, operator, and control plane |
| Skills | skills/shared/ |
Org/team shared skill library |
| Terraform | terraform/ |
GCP infrastructure: GKE, Cloud SQL, VPC, Crossplane |
- Node 22+, pnpm 10+
- Kubernetes 1.28+ (GKE recommended)
- Helm 3
- Terraform 1.5+ (for GCP deployment)
- PostgreSQL 15+ (Cloud SQL or local)
pnpm install
pnpm build
pnpm test# 1. Provision infrastructure
cd terraform/environments/dev
cp terraform.tfvars.example terraform.tfvars # edit with your GCP project
terraform init && terraform apply
# 2. Install the platform
helm install opencrane helm/opencrane \
-f helm/opencrane/values-gcp.yaml \
--set tenant.storage.gcpProject=my-project \
--set ingress.domain=opencrane.ai \
--set controlPlane.database.existingSecret=opencrane-cloudsql
# 3. Create a tenant
kubectl apply -f - <<EOF
apiVersion: opencrane.io/v1alpha1
kind: Tenant
metadata:
name: jente
spec:
displayName: Jente
email: jente@example.com
EOFThe operator creates a GCS bucket, Workload Identity service account, encryption key, deployment, service, and ingress. Access at https://jente.opencrane.ai.
Pin a tenant to a specific OpenClaw version:
apiVersion: opencrane.io/v1alpha1
kind: Tenant
metadata:
name: jente
spec:
displayName: Jente
email: jente@example.com
openclawVersion: "2026.3.15"Without openclawVersion, tenants install latest on first boot and can self-update via openclaw update.
AGPL-3.0-or-later