Multitenancy
Cosmonic Control supports multi-tenant deployments where multiple teams share the same Kubernetes cluster and Cosmonic Control installation. Isolation is enforced at two levels: the Kubernetes namespace boundary (for resource management) and the WebAssembly sandbox (for runtime execution).
Tenancy model
Each tenant is mapped to a Kubernetes namespace. Teams create and manage their workloads within their own namespace, primarily as WorkloadDeployment resources with an HTTPTrigger routing HTTP traffic to each, and cannot see or modify resources in other namespaces.
The Cosmonic Control operator and infrastructure components run in cosmonic-system and are managed by platform operators, not tenants.
cosmonic-system/
operator, nexus, envoy, observability stack ← platform team only
team-a/
WorkloadDeployment + HTTPTrigger: checkout-service ← team-a manages
WorkloadDeployment + HTTPTrigger: product-api
team-b/
WorkloadDeployment + HTTPTrigger: analytics-pipeline ← team-b manages
Access to each namespace is controlled with standard Kubernetes Role and RoleBinding objects. See Tenant RBAC for a step-by-step setup guide.
Workload isolation
Cosmonic Control applies the Principle of Least Authority through the WebAssembly sandbox, which enforces strict capability boundaries regardless of which namespace a component is deployed to:
- A component has no access to the host filesystem, network, or environment by default.
- Outbound HTTP calls and raw socket connections require explicit opt-in via
allowedHosts. Since v0.14.0 hosts enforce this for raw sockets by default, along with a guest memory budget and an allowlist forhostPathvolumes. - Configuration and secrets are injected by the operator at deploy time, scoped to the component's own manifest (component configuration).
- Components cannot communicate with other components or services unless explicitly linked via
hostInterfaces.
This means a misbehaving or compromised component cannot read another tenant's secrets, call arbitrary external services, or access cluster infrastructure — the sandbox enforces the boundary at the CPU instruction level, not just at the network level.
The manifest is where those grants are made, so whoever can create a workload in a namespace decides them. To cap what a tenant can grant its own workloads, such as which registries, egress domains and host interfaces it may use, add Pod Security and the Cosmonic admission policies described in Securing a Cluster.
HostGroups and scheduling
A HostGroup is a set of wasmCloud runtime pods. Each pod in a HostGroup can run Wasm components from multiple namespaces simultaneously — the sandbox ensures they remain isolated from each other on the same host.
By default, all workloads share a single default HostGroup. A WorkloadDeployment with no spec.template.spec.environment set is left unpinned, and the scheduler treats every host in the cluster as fair game, including any shared hostgroup. To confine a tenant's workloads to a specific hostgroup, set spec.template.spec.environment (or hostSelector) on the WorkloadDeployment to match the hostgroup's label.
For stronger isolation between teams (e.g., compliance requirements, different resource profiles, GPU workloads), deploy separate HostGroups with distinct names and use hostSelector in WorkloadDeployment manifests to pin workloads to specific HostGroups:
# A dedicated HostGroup for a high-compliance team
helm install hostgroup-secure oci://ghcr.io/cosmonic/cosmonic-control-hostgroup \
--version 0.14.0 \
--namespace cosmonic-system \
--set hostgroup=secure \
--set replicaCount=2# WorkloadDeployment that targets the secure HostGroup
spec:
template:
spec:
hostSelector:
hostgroup: secureSelecting on the hostgroup name is the common case, but a hostSelector matches any label a host advertises. Advertise arbitrary hostLabels on a group to schedule by other dimensions, such as a zone or a hardware tier. See Scheduling by label.
See Installing HostGroups for full configuration options.
Architecture
At runtime, Envoy routes inbound HTTP requests to the correct Wasm component based on the Host header. Each HTTPTrigger registers its hostnames and path rules, and the WorkloadDeployments they route to, with the XDS cache service, which pushes updated routing configuration to Envoy. Components from different namespaces can be reachable on distinct hostnames via the same Envoy instance.
Components on the same HostGroup pod remain sandbox-isolated despite sharing the runtime process — there is no shared memory or direct call path between components in different namespaces unless an explicit link is declared.