Capsule: multi-tenancy for one Kubernetes cluster without new layers
Multi-tenancy and policy-based framework for Kubernetes.
At a glance
- What is it?
- An operator that groups namespaces into tenant objects and pushes quotas, RBAC and policies down into them, so platform teams can share a cluster instead of provisioning one per department. Useful, with a support matrix narrower than the README suggests.
- Who is it for?
- Capsule earns its place when you are past the point where one cluster per team is affordable to operate and you want tenancy expressed in objects rather than in a wrapper platform. Because it enforces through ordinary Kubernetes admission machinery and adds no custom binaries or management layer, adopting it is a decision about your cluster's organisation rather than a migration to a different stack.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Cluster sprawl as the problem, a namespace group as the answer
The README frames Capsule around an operational failure it calls cluster sprawl. Kubernetes gives you the Namespace object, which partitions a cluster into isolated slices, and that is enough until you want tenants that share resources. Because namespaces are flat, two teams who should see a shared quota or a shared config cannot be given one, so administrators end up provisioning a separate cluster per group of users. As an organisation grows, the number of clusters to keep aligned becomes the thing nobody wants to own.
Capsule's answer is one more level above namespace, and it is called a Tenant. A Tenant is a grouping of Kubernetes namespaces, and the Capsule Controller aggregates them inside a single cluster. The README describes the design as a microservice-based ecosystem that relies only on upstream Kubernetes, which is a meaningful constraint: no custom scheduler, no modified API server, no separate control plane for tenants.
The self-service angle is what makes it more than a grouping mechanism. Within a tenant, users create their own namespaces rather than filing a request, which is the administrative bottleneck that usually pushes teams toward one cluster each. The tenant is the unit an administrator configures once, and everything inside it follows.
The claim worth testing is the native one. Because tenancy is expressed as custom resources reconciled by an operator, a tenant is visible through ordinary kubectl tooling and can live in Git alongside everything else, which is why the README describes the project as declarative and GitOps ready.
Policies inherited downward through the policy engine
The second half of the design is a policy engine that keeps tenants isolated from each other. Policies defined at the tenant level are inherited automatically by every namespace in that tenant. The list the README names is specific: network and security policies, resource quota, limit ranges, and RBAC, with the word automatically doing the real work.
This is where the project differs from a namespace labelling scheme. Label-based approaches require every quota and rolebinding to be written per namespace, which is exactly the repetition tenants generate. Here the tenant object is the single declaration and the controller propagates it, so a change to a tenant's quota reaches its namespaces without anyone editing them.
Resource control gets its own feature heading in the README, framed as taking control of the resources users consume while preventing them from overtaking. Limit ranges and quotas are what make a shared cluster survivable, since without them a single tenant can starve the node. The BYOD feature goes further: assigning a tenant dedicated compute, storage and network resources so it is insulated from noisy neighbours.
The dependency list in go.mod shows how policy decisions are evaluated. The project pulls in cel-go for Common Expression Language evaluation, the jsonschema library for validation, and go-sprout, a sprig-style function library, for templating inside resources. That last one turns out to matter for security, as a later section covers.
Two different support matrices, and one of them is stale
The README and the release notes disagree about which Kubernetes versions Capsule supports, and the disagreement is large enough to matter before you install anything.
The README FAQ says Capsule was tested with vanilla Kubernetes 1.16 and later on private environments and public clouds, and expects it to work on other distributions. The v0.14.5 release note says the opposite in stronger terms: the project offers support only for the latest minor version of Kubernetes, and backwards compatibility with older versions and OpenShift is offered by vendors rather than by the project. That note includes a table giving Kubernetes v1.36 as requiring 1.36.0 or newer.
Both statements are in the repository at the same time. Rather than pick one, check the thing that cannot be stale: the module dependencies. go.mod requires k8s.io/api, apimachinery, client-go, apiextensions-apiserver and apiserver all at v0.36.3, which lines up with the 1.36 line rather than with 1.16. The Makefile states the same thing in the place a release engineer would look:
KUBERNETES_SUPPORTED_VERSION ?= "v1.36.1"
OS_SUPPORTED_VERSION ?= "4.22.0-okd-scos.ec.10"So the practical reading is that the FAQ text has not kept up with the policy, and the version your cluster must meet is the one in the release note table and the go.mod pins. A related note appears in every recent release, telling you to review the major changes section before upgrading.
Helm chart, OCI artifacts and where the badges point
Distribution is ordinary: an OCI image published to a GitHub container registry, and a Helm chart that is both listed on Artifact Hub and available as an OCI artifact itself. The Makefile holds the two coordinates:
REGISTRY ?= ghcr.io
REPOSITORY ?= projectcapsule/capsuleThat is worth pausing on, because the README's badges still point at an older organisation. The license badge, the Go module badge and the release badge are all built for clastix/capsule, and the CLOMonitor report links to a cncf/capsule project path. The repository itself is projectcapsule/capsule, and the README names Clastix as the company behind the project offering commercial support. Those are consistent with an organisation move rather than a mistake, but they mean a badge on the README will not resolve to the repository you are reading.
The tree shows the shape of the codebase. cmd/ and internal/ hold the operator, api/ the custom resource definitions, pkg/ shared libraries, charts/ the Helm chart, playground/ a local environment, e2e/ the end-to-end suite driven by ginkgo and gomega, and hack/ the build scripts. There is a separate Dockerfile.tracing, and the module pulls in the full OpenTelemetry stack including an OTLP trace exporter, so the tracing build is a first-class path rather than an afterthought.
Every OCI release artifact is said to include a Software Bill of Materials in CycloneDX JSON format, which matters for the compliance questionnaires that cluster operators get asked to fill in.
The expandenv advisory shows what TenantResource templating is for
Release v0.14.4, published on 2026-09-03, is the one to read if you use TenantResource. It carries a moderate severity advisory, GHSA-2vqc-26cg-wpxg, describing a TenantResource template sanitizer that missed the sprig expandenv function because the deny-list was matched on the wrong case. The consequence is named precisely: a namespaced tenant could read the Capsule controller process environment and secrets.
Two things make this worth more than a routine patch note. First, the mechanism is understandable from the dependency list. Templating in resources is powered by go-sprout, a sprig-compatible function set, and expandenv is a standard sprig function that reads environment variables. A sanitizer that blocks a function list by exact string match will miss a case variant, and that is a class of bug any template allowlist is exposed to. Second, the fix is a removal rather than a correction: the release notes describe removing expandenv from the function map entirely, not fixing the match.
The same release also validates only changed metadata on updates. v0.14.5, four days later, denies empty metadata. v0.14.6 improves admission messages for rules, fixes metadata audience inheritance for managed metadata, allows updates to the namespace node-selector annotation, and reduces tenant rule reconciliation overhead. That last item is the kind of fix that tells you the controller was doing repeated work per reconciliation cycle, which matters on a cluster with many tenants.
If you enable templating, pin to a release carrying the fix rather than tracking latest, and treat the function allowlist as a security boundary rather than a convenience.
Stable by Kubernetes definition, still versioned zero
The Project Status section says the project is stable and explicitly adopts the Kubernetes definition of stable, linking to the feature gate stages page. The FAQ, in the same README, describes it as under frequent development and improvement and says it is ready for production, with people running it in public and private deployments. The version numbers tell a third story: v0.14.4, v0.14.5 and v0.14.6, all published in September 2026.
None of those statements cancel the others, and readers should hold all three. A zero major version means the project has not committed to API stability, the Kubernetes notion of stable is about feature gate maturity rather than semantic versioning, and the FAQ's production readiness claim is about deployability. When you are evaluating, the concrete question is whether the custom resource schemas in api/ are expected to change between minor releases, and the repository does not promise that they will not.
The README itself is a pointer rather than a manual. Configuration, the tenant spec, the policy engine behaviour and the upgrade guidance all live at the documentation site. Governance is documented separately, maintainers are listed in a YAML file under .github/, community discussion happens in a dedicated community repository and a Kubernetes Slack channel, and an ADOPTERS.md file lists companies using it. There is also a SELF_ASSESSMENT.md, a DEPENDENCY.md, a ROADMAP.md and a SECURITY-INSIGHTS.yml in the tree, which is the paperwork you would expect from a project that has to pass a CNCF-style review.
The last push was on 2026-09-28, most of the recent commits come from a single maintainer, and the release cadence is weekly or better. Activity is not the open question here.
Editorial conclusion
Capsule earns its place when you are past the point where one cluster per team is affordable to operate and you want tenancy expressed in objects rather than in a wrapper platform. Because it enforces through ordinary Kubernetes admission machinery and adds no custom binaries or management layer, adopting it is a decision about your cluster's organisation rather than a migration to a different stack. The costs are visible in the release notes. Support tracks only the current Kubernetes minor version, which means an upgrade cycle for your cluster is also an upgrade cycle for Capsule, and the TenantResource template path had a real escape in the recent past because its sanitizer denied functions by exact name. Read the admission control section on the documentation site, check the supported version table in the release notes against your cluster version rather than the README FAQ, and if you enable TenantResource templating, pin to a release that carries the expandenv fix.
Frequently asked questions
What is a Tenant in Capsule?
A Tenant is a grouping of one or more Kubernetes namespaces inside a single cluster, which the Capsule Controller aggregates. Administrators configure a tenant once and the policy engine pushes network and security policies, resource quota, limit ranges and RBAC down into every namespace it contains. Users can then create namespaces inside that tenant themselves instead of requesting one from an administrator.
Which Kubernetes versions does Capsule support?
The current release notes are explicit that support covers only the latest Kubernetes minor version, with a table giving v1.36 as requiring 1.36.0 or newer, and older-version compatibility offered by vendors rather than the project. The README FAQ still mentions vanilla Kubernetes 1.16 and later, and go.mod pins the Kubernetes libraries at v0.36.3, which matches the newer policy rather than the FAQ. Check the release note table and the module pins against your cluster version.
Does Capsule require changes to my Kubernetes distribution?
No. The README describes the design as relying only on upstream Kubernetes, and lists providing multi-tenancy without additional management layers, plugins or customized binaries as a feature. Enforcement happens through Kubernetes admission controllers, which is why the governance section frames it as meeting industry security practices with mechanisms already present in the cluster.
Is commercial support available for Capsule?
Yes. The README states that Clastix is the company behind Capsule and that commercial support is available on request. The project itself is Apache 2 licensed and hosted at projectcapsule/capsule, and governance documentation is published on the project documentation site.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/projectcapsule-capsule)