Skip to main content

Documentation Index

Fetch the complete documentation index at: https://enterprise-docs.crewai.com/llms.txt

Use this file to discover all available pages before exploring further.

Overview

By default, all organizations share the same Kubernetes namespace (defined by K8S_NAMESPACE). Multi-org namespace isolation allows each organization to use a dedicated namespace, providing stronger isolation between organizations. This feature is optional. Organizations that do not require isolation will continue using the shared namespace as before.
Fresh-install-only. Enable k8s_namespace_isolation before provisioning your first crew. Flipping the flag on after crews already exist in the shared K8S_NAMESPACE orphans those workloads — the platform will route subsequent provision/update/delete operations (and the /health/debug Studio probe) to <K8S_NAMESPACE>-org-<id>, while the original pods sit untouched in the shared namespace. There is no automatic migration path. If you must enable isolation on an existing install, plan to re-provision every crew (Studio internal Assistant + Runner included) into its per-org namespace and clean up the orphaned Deployments by hand.

Prerequisites

  • K8S_NAMESPACE environment variable is set in your Helm values (e.g., crewai)
  • The k8s_namespace_isolation Flipper feature flag is enabled globally
  • Recommended: Enable rbac.namespaceIsolation: true in Helm values to automatically grant cluster-wide permissions for managing per-organization namespaces

Enable the Feature Flag

kubectl exec -it deploy/crewai-web -- \
  bin/rails runner "Flipper.enable(:k8s_namespace_isolation)"
The chart can automatically create the required ClusterRole and ClusterRoleBinding to grant the CrewAI Platform ServiceAccount permissions across all organization namespaces. This simplifies setup by eliminating manual RoleBinding creation for each organization. Add to your Helm values:
rbac:
  create: true
  namespaceIsolation: true  # Creates ClusterRole and ClusterRoleBinding
Then upgrade the release:
helm upgrade crewai-platform ./helm --values values.yaml
When rbac.namespaceIsolation: true, the chart creates a ClusterRole with scoped permissions (namespaces, secrets, configmaps, pods, deployments, etc.) and binds it to the CrewAI ServiceAccount. This grants cluster-wide access to manage resources in dynamically created per-organization namespaces (e.g., crewai-org-1, crewai-org-2).
Enabling rbac.namespaceIsolation grants cluster-wide permissions to the CrewAI Platform ServiceAccount. Ensure your organization’s security policies allow ClusterRole creation before enabling this feature. If ClusterRole creation is not permitted, use the manual setup approach described below.

Namespace Naming Convention

When isolation is enabled, each organization gets a dedicated namespace using the format:
{K8S_NAMESPACE}-org-{organization_id}
For example, if K8S_NAMESPACE=crewai and the organization ID is 4, the namespace will be crewai-org-4. You can find the organization ID and the expected namespace name on the organization’s admin page in the warning banner.

Setting Up a New Organization Namespace

If you enabled rbac.namespaceIsolation: true in your Helm values, the platform will automatically create organization namespaces and manage permissions when you deploy crews to a new organization. You only need to ensure the registry secret is copied to new namespaces. For each new organization namespace:
# Copy the registry secret to the new namespace
kubectl get secret docker-registry -n {K8S_NAMESPACE} -o yaml \
  | sed 's/namespace: .*/namespace: {K8S_NAMESPACE}-org-{id}/' \
  | kubectl apply -f -
The platform automatically creates the namespace ({K8S_NAMESPACE}-org-{id}) when a crew is deployed to the organization. No manual namespace creation or RoleBinding setup is required when using rbac.namespaceIsolation: true.

Manual Setup (Alternative)

If you cannot enable rbac.namespaceIsolation due to security policies that prohibit ClusterRole creation, manually set up each organization namespace:

1. Create the Namespace

kubectl create namespace {K8S_NAMESPACE}-org-{id}

2. Grant the Service Account Access

The platform’s service account needs permissions to manage resources in the new namespace:
kubectl create rolebinding crewai-sa-edit \
  --clusterrole=edit \
  --serviceaccount={K8S_NAMESPACE}:crewai-sa \
  --namespace={K8S_NAMESPACE}-org-{id}
Replace {K8S_NAMESPACE} with your configured namespace (e.g., crewai) and {id} with the organization ID shown on the organization’s admin page.

3. Copy the Registry Secret

The new namespace needs access to the container image registry to pull automation images:
kubectl get secret docker-registry -n {K8S_NAMESPACE} -o yaml \
  | sed 's/namespace: .*/namespace: {K8S_NAMESPACE}-org-{id}/' \
  | kubectl apply -f -

Example

Automatic Setup Example

Setting up namespace isolation for organization 4 with K8S_NAMESPACE=crewai and rbac.namespaceIsolation: true:
# 1. Enable ClusterRole in Helm values (one-time setup)
# values.yaml:
#   rbac:
#     create: true
#     namespaceIsolation: true

# 2. Upgrade Helm release (one-time setup)
helm upgrade crewai-platform ./helm --values values.yaml

# 3. Enable the feature flag (one-time setup)
kubectl exec -it deploy/crewai-web -- \
  bin/rails runner "Flipper.enable(:k8s_namespace_isolation)"

# 4. Copy registry secret when organization namespace is created
# (The platform creates crewai-org-4 automatically on first crew deployment)
kubectl get secret docker-registry -n crewai -o yaml \
  | sed 's/namespace: .*/namespace: crewai-org-4/' \
  | kubectl apply -f -

Manual Setup Example

Setting up namespace isolation for organization 4 with K8S_NAMESPACE=crewai without rbac.namespaceIsolation:
# Create the namespace
kubectl create namespace crewai-org-4

# Grant service account access
kubectl create rolebinding crewai-sa-edit \
  --clusterrole=edit \
  --serviceaccount=crewai:crewai-sa \
  --namespace=crewai-org-4

# Copy the registry secret
kubectl get secret docker-registry -n crewai -o yaml \
  | sed 's/namespace: .*/namespace: crewai-org-4/' \
  | kubectl apply -f -

Verification

After setting up the namespace, deploy an automation to the organization. The deployment should target the new namespace. You can verify with:
# Check pods in the org namespace
kubectl get pods -n {K8S_NAMESPACE}-org-{id}

# Check pods by org label
kubectl get pods -l org-id=org-{id} --all-namespaces
The warning banner on the organization’s admin page will disappear after the first successful deployment.

Support Bundle Configuration

When using multi-organization namespace isolation, configure support bundles to collect logs from all organization namespaces for comprehensive troubleshooting. Add to your Helm values:
supportBundle:
  crewLogNamespaces:
    - "crewai-org-1"
    - "crewai-org-2"
    - "crewai-org-3"
This ensures support bundles capture crew workload logs (web, worker, redis pods) and events from each organization namespace. See Support Bundle Configuration for details.

Troubleshooting

Deployment Fails with Forbidden Error

The service account does not have permissions in the org namespace. If using rbac.namespaceIsolation: true: Verify the ClusterRoleBinding exists:
kubectl get clusterrolebinding crewai-namespace-isolation
If using manual setup: Verify the namespace-specific RoleBinding exists:
kubectl get rolebinding -n {K8S_NAMESPACE}-org-{id}

Secrets Forbidden Error

If you see an error like:
secrets "docker-registry" is forbidden: User "system:serviceaccount:..." cannot get resource "secrets" in the namespace "...-org-{id}"
This means the namespace and rolebinding were not set up for this organization. Follow the setup steps to create the namespace, grant the service account access, and copy the registry secret.

Image Pull Errors

The registry secret is missing from the org namespace. Re-run the secret copy step:
kubectl get secret docker-registry -n {K8S_NAMESPACE} -o yaml \
  | sed 's/namespace: .*/namespace: {K8S_NAMESPACE}-org-{id}/' \
  | kubectl apply -f -