Workspaces¶
Workspaces provide multi-tenant isolation in DRLS. Each workspace gets dedicated Kubernetes namespaces, IAM roles, and network policies to ensure data and compute separation between teams.
Overview¶
A workspace represents an isolated environment with:
- 3 dedicated K8s namespaces —
{id}-notebooks,{id}-drls-clusters,{id}-drls-pipelines - S3 prefix scoping — each workspace's IAM role only grants access to
s3://{bucket}/{workspace_id}/* - Per-user ServiceAccounts — JIT-created on OIDC login with IRSA annotations for AWS credential injection
- Network policies — namespace-level isolation preventing cross-workspace network traffic
- Data-level scoping — all API queries (pipelines, runs, clusters, notebooks) are filtered by workspace
A default workspace is always present and uses the pre-existing namespaces (notebooks, drls-clusters, drls-pipelines).
Creating a Workspace¶
Navigate to System Settings > Workspaces in the management console.
- Click Create Workspace
- Enter a Workspace ID — lowercase alphanumeric with hyphens, 2-38 characters, no leading/trailing hyphen (e.g.,
data-science,team-alpha) - Enter a Display Name — human-readable label shown in the UI
- Click Create
The workspace enters pending status while Kubernetes resources are provisioned asynchronously. Once complete, it transitions to active.
Note
Workspace IDs must be at most 38 characters because they become K8s namespace prefixes. The longest suffix (-drls-pipelines, 25 chars) plus the ID must fit within the 63-character namespace limit.
IAM Role Configuration¶
Each workspace can have an associated IAM role for S3 and Glue access via IRSA (IAM Roles for Service Accounts).
Setting the IAM Role¶
- Provision the IAM role using the Terraform module (see Terraform Provisioning below)
- Copy the role ARN from the Terraform output
- In System Settings > Workspaces, click the workspace row to edit
- Paste the ARN into the IAM Role ARN field and save
- Click Sync IAM to propagate the annotation to all existing ServiceAccounts
How IRSA Works¶
When an IAM role ARN is set on a workspace:
- All per-user ServiceAccounts in the workspace's namespaces receive the
eks.amazonaws.com/role-arnannotation - Pods running under those ServiceAccounts automatically receive AWS credentials via the EKS pod identity webhook
- The IAM role's trust policy allows assumption from any SA in the workspace's namespaces
- The IAM role's permission policy restricts S3 access to the workspace's prefix
Per-User ServiceAccounts¶
When a user logs in via OIDC SSO, the system JIT-creates a Kubernetes ServiceAccount named user-{sub} in all three of the user's workspace namespaces. This happens as a fire-and-forget background task, so it does not add latency to login.
- Notebook pods in non-default workspaces run under the user's ServiceAccount
- IRSA annotations are applied if the workspace has an IAM role configured
- ServiceAccount records are tracked in the database for lifecycle management
- On workspace deletion, all associated ServiceAccounts are cleaned up automatically
Network Isolation¶
Each workspace namespace has a NetworkPolicy that restricts traffic:
Notebook Namespace¶
| Direction | Allowed | Ports |
|---|---|---|
| Ingress | core-services (backend pod only) | TCP/2718 (marimo) |
| Egress | DNS | UDP+TCP/53 |
| Egress | HTTPS (external, non-RFC1918) | TCP/443 |
Ray Cluster Namespace¶
| Direction | Allowed | Ports |
|---|---|---|
| Ingress | core-services (dashboard proxy, log streaming) | All |
| Ingress | Intra-namespace (head ↔ workers, GCS) | All |
| Egress | DNS | UDP+TCP/53 |
| Egress | HTTPS (S3, external APIs) | TCP/443 |
| Egress | Intra-namespace (head ↔ workers) | All |
Pipeline Namespace¶
| Direction | Allowed | Ports |
|---|---|---|
| Ingress | core-services (ui-server log streaming) | All |
| Ingress | Intra-namespace (Spark driver ↔ executor) | All |
| Egress | DNS | UDP+TCP/53 |
| Egress | HTTPS (S3, Polaris, external APIs) | TCP/443 |
| Egress | Kafka | TCP/9092, TCP/9093 |
| Egress | Intra-namespace (driver ↔ executor) | All |
Info
Network policies are namespace-scoped. When a workspace is deleted, its namespaces (and all policies within) are automatically removed.
Terraform Provisioning¶
The terraform/04-workspace-iam/ module creates per-workspace IAM roles with S3 prefix-scoped access.
Usage¶
cd terraform/04-workspace-iam
terraform init
# Create IAM role for a workspace
terraform apply \
-var="workspace_id=data-science" \
-var="bucket_arn=arn:aws:s3:::drls-datalake"
Inputs¶
| Variable | Required | Default | Description |
|---|---|---|---|
workspace_id |
Yes | — | Workspace identifier |
cluster_name |
No | drls |
EKS cluster name |
region |
No | us-west-2 |
AWS region |
bucket_arn |
Yes | — | Data lake S3 bucket ARN |
kms_key_arn |
No | "" |
KMS key ARN (if bucket uses custom key) |
Outputs¶
| Output | Description |
|---|---|
role_arn |
IAM role ARN — paste into workspace settings |
role_name |
IAM role name |
What It Creates¶
- IAM Role (
rls-workspace-{id}) with IRSA trust policy allowing any ServiceAccount in the workspace's namespaces - S3 Policy —
ListBucket(prefix-scoped),GetObject/PutObject/DeleteObject(prefix-scoped) - Glue Policy — read-only access to the shared Glue Data Catalog
- KMS Policy (optional) —
Decrypt/GenerateDataKeyif a custom KMS key is provided
Troubleshooting¶
Workspace stuck in "pending" or "error"¶
The workspace provisioning creates K8s namespaces, RBAC roles, and network policies asynchronously. If it fails:
- Check the workspace error message in System Settings > Workspaces
- Common causes: K8s API unreachable, RBAC insufficient, namespace already exists with conflicting labels
- Click Retry Provisioning to re-run the provisioning task
ServiceAccounts not receiving IRSA annotation¶
- Verify the IAM role ARN is set on the workspace
- Click Sync IAM to force-propagate the annotation
- Check that the user has logged in at least once (SAs are JIT-created on login)
Pods cannot access S3¶
- Verify the pod is running under a user ServiceAccount (not
default) - Check the SA has the
eks.amazonaws.com/role-arnannotation:kubectl get sa user-{sub} -n {ws}-drls-pipelines -o yaml - Verify the IAM role trust policy includes the correct OIDC provider and namespace
- Check CloudTrail for
AssumeRoleWithWebIdentityerrors