Skip to content

Tenant Management

KSail can generate multi-tenancy manifests for platform teams that need to onboard workload teams onto a shared cluster. Each tenant gets namespace isolation, RBAC, and optional GitOps sync resources.

TypeRBACGitOps sync resourcesRequires GitOps engine
fluxOCIRepository / GitRepository + KustomizationFlux
argocdAppProject + ApplicationArgoCD
kubectlNoneNo

The --type flag defaults to auto-detect from ksail.yaml gitOpsEngine.

Terminal window
# Auto-detect type (reads gitOpsEngine from ksail.yaml)
ksail tenant create my-team
# Explicit type
ksail tenant create my-team --type flux
# Custom namespace(s) — default is the tenant name
ksail tenant create my-team --namespace my-team --namespace my-team-staging
# Custom ClusterRole — default is 'edit'
ksail tenant create my-team --cluster-role view
# Output to a specific directory
ksail tenant create my-team --output platform/tenants/

The command writes manifests to <output>/<tenant-name>/:

platform/tenants/my-team/
├── kustomization.yaml
├── namespace.yaml
├── serviceaccount.yaml
├── rolebinding.yaml
└── (flux or argocd sync resources if applicable)

Add --register to automatically append the tenant to the nearest kustomization.yaml:

Terminal window
ksail tenant create my-team --register

For Flux tenants, specify the sync source type and registry or Git repo:

Terminal window
# OCI source (default)
ksail tenant create my-team --type flux \
--sync-source oci \
--registry oci://ghcr.io/my-org
# Git source
ksail tenant create my-team --type flux \
--sync-source git \
--git-provider github \
--git-repo my-org/my-team-infra

To scaffold a new Git repository for the tenant (requires --git-provider github):

Terminal window
ksail tenant create my-team --type flux \
--sync-source git \
--git-provider github \
--git-repo my-org/my-team-infra

KSail resolves the GitHub token automatically using the following fallback chain:

  1. --git-token flag (highest priority)
  2. GH_TOKEN or GITHUB_TOKEN environment variable
  3. GitHub CLI config (e.g., from gh auth login)

If no token can be resolved through any of these sources, repo scaffolding is skipped with a warning and the command succeeds. In CI, ensure a non-empty token is available via --git-token, GH_TOKEN, or GITHUB_TOKEN if you want scaffolding to run. Only ksail tenant delete --delete-repo fails when no token can be resolved.

Pass --git-token explicitly only when you need to override the auto-detected token:

Terminal window
ksail tenant create my-team --type flux \
--git-provider github \
--git-repo my-org/my-team-infra \
--git-token "${MY_BOT_TOKEN}"

ArgoCD tenants generate an AppProject, Application, and argocd-rbac-cm ConfigMap entry:

Terminal window
ksail tenant create my-team --type argocd \
--git-provider github \
--git-repo my-org/my-team-infra

kubectl tenants generate RBAC only (no sync resources):

Terminal window
ksail tenant create my-team --type kubectl
Terminal window
# Remove manifests and unregister from kustomization.yaml (default)
ksail tenant delete my-team
# Also delete the tenant Git repository (token resolved automatically;
# requires a valid token from the fallback chain above)
ksail tenant delete my-team --delete-repo \
--git-provider github \
--git-repo my-org/my-team-infra
# Keep kustomization.yaml entry
ksail tenant delete my-team --unregister=false

After generating manifests, apply them to the cluster using the workflow that matches how the tenant was created:

Terminal window
# If you created the tenant without --register,
# apply the generated tenant directory directly
ksail workload apply -k platform/tenants/my-team/
# If you created the tenant with --register, or platform/tenants/kustomization.yaml
# already includes the tenant directory, apply the parent directory
ksail workload apply -k platform/tenants/

Or if using GitOps, push and reconcile:

Terminal window
ksail workload push
ksail workload reconcile