# Metadata

> Inherit additional metadata on Tenant resources.

> For the complete documentation index, see [llms.txt](https://projectcapsule.dev/llms.txt).
> The HTML version of this page is at https://projectcapsule.dev/docs/tenants/metadata/.

## Managed

By default all namespaced resources within a `Namespace` which are part of a `Tenant` labeled at admission with the following labels:

  * `capsule.clastix.io/managed-by`: `<tenant-name>` (Legacy label)
  * `projectcapsule.dev/tenant`: `<tenant-name>`

The labels are used by Capsule to identify resources belonging to a specific tenant. This is currently important for the [Capsule Proxy](/docs/proxy/) to filter resources accordingly.

## Namespaces


### ManagedMetadataOnly

Disallows any further metadata to be added to the `Namespaces` created by the tenant owners.

```yaml
---
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  namespaceOptions:
    managedMetadataOnly: true
```

### RequiredMetadata


> **Deprecated**
>
> This feature will be deprecated in a future release of Capsule. Instead use <a href="/docs/rules/enforcement/metadata">Metadata Rules</a>. <strong><a href="/docs/rules/enforcement/metadata/#migrate-namespace-metadata">Migration Guide Here</a></strong>


The cluster admin can enforce tenant owners to add specific metadata as `Labels` and `Annotations` to the `Namespaces` they create. This is a useful feature to enforce a set of [Rules](/docs/tenants/rules/) based on `Labels`.

```yaml
---
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  namespaceOptions:
    requiredMetadata:
      labels:
        env: "^(prod|test|dev)$"
      annotations:
        example.corp/cost-center: "^INV-[0-9]{4}$"
```

If you add these properties to a `Tenant`, and there's already a `Namespace` in that `Tenant` that does not comply with the required metadata, the `Namespace` will have admission errors until the required metadata is added to it.

Example with [Rules](/docs/tenants/rules/):

```yaml
---
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  namespaceOptions:
    requiredMetadata:
      labels:
        env: "^(prod|test|dev)$"
      annotations:
        example.corp/cost-center: "^INV-[0-9]{4}$"

  rules:
    # Select a subset of namespaces (enviornment=prod) to allow further registries
    - namespaceSelector:
        matchExpressions:
          - key: env
            operator: In
            values: ["prod"]
      enforce:
        action: allow
        workloads:
          registries:
            - exp: "harbor/v2/prod-registry/.*"
              policy: ["IfNotPresent"]
```

### AdditionalMetadataList


> **Deprecated**
>
> This feature will be deprecated in a future release of Capsule. Instead use <a href="/docs/rules/enforcement/metadata">Metadata Rules</a>. <strong><a href="/docs/rules/enforcement/metadata/#migrate-namespace-metadata">Migration Guide Here</a></strong>



```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  owners:
    - name: alice
      kind: User
  namespaceOptions:
    additionalMetadataList:
      - annotations:
          templated-annotation: "{{ tenant.name }}"
        labels:
          templated-label: "{{ namespace }}"
```

The cluster admin can "taint" the namespaces created by tenant owners with additional metadata as labels and annotations. There is no specific semantic assigned to these labels and annotations: they will be assigned to the namespaces in the tenant as they are created. However you have the option to be more specific by selecting to which namespaces you want to assign what kind of metadata:

```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  owners:
  - name: alice
    kind: User
  namespaceOptions:
    additionalMetadataList:
    # An item without any further selectors is applied to all namspaces
    - annotations:
        storagelocationtype: s3
      labels:
        projectcapsule.dev/backup: "true"

    # Select a subset of namespaces to apply metadata on
    - namespaceSelector:
        matchExpressions:
          - key: projectcapsule.dev/low_security_profile
            operator: NotIn
            values: ["true"]
      labels:
        pod-security.kubernetes.io/enforce: baseline

    - namespaceSelector:
        matchExpressions:
          - key: projectcapsule.dev/low_security_profile
            operator: In
            values: ["true"]
      labels:
        pod-security.kubernetes.io/enforce: privileged
```

### AdditionalMetadata


> **Deprecated**
>
> This feature will be deprecated in a future release of Capsule. Instead use <a href="/docs/rules/enforcement/metadata">Metadata Rules</a>. <strong><a href="/docs/rules/enforcement/metadata/#migrate-namespace-metadata">Migration Guide Here</a></strong>



The cluster admin can "taint" the namespaces created by tenant owners with additional metadata as labels and annotations. There is no specific semantic assigned to these labels and annotations: they will be assigned to the namespaces in the tenant as they are created. This can help the cluster admin to implement specific use cases as, for example, leave only a given tenant to be backed up by a backup service.

Assigns additional labels and annotations to all namespaces created in the `solar` tenant:

```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  owners:
  - name: alice
    kind: User
  namespaceOptions:
    additionalMetadata:
      annotations:
        storagelocationtype: s3
      labels:
        projectcapsule.dev/backup: "true"
```

When the tenant owner creates a namespace, it inherits the given label and/or annotation:

```yaml
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    storagelocationtype: s3
  labels:
    capsule.clastix.io/tenant: solar
    kubernetes.io/metadata.name: solar-production
    name: solar-production
    projectcapsule.dev/backup: "true"
  name: solar-production
  ownerReferences:
  - apiVersion: capsule.clastix.io/v1beta2
    blockOwnerDeletion: true
    controller: true
    kind: Tenant
    name: solar
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
```

### Deny labels and annotations on Namespaces


> **Deprecated**
>
> This feature will be deprecated in a future release of Capsule. Instead use <a href="/docs/rules/enforcement/metadata">Metadata Rules</a>. <strong><a href="/docs/rules/enforcement/metadata/#migrate-namespace-metadata">Migration Guide Here</a></strong>



By default, capsule allows tenant owners to add and modify any label or annotation on their namespaces.

But there are some scenarios, when tenant owners should not have an ability to add or modify specific labels or annotations (for example, this can be labels used in [Kubernetes network policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/) which are added by cluster administrator).

Bill, the cluster admin, can deny Alice to add specific labels and annotations on namespaces:

```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  namespaceOptions:
    forbiddenAnnotations:
      denied:
          - foo.acme.net
          - bar.acme.net
      deniedRegex: .*.acme.net
    forbiddenLabels:
      denied:
          - foo.acme.net
          - bar.acme.net
      deniedRegex: .*.acme.net
  owners:
  - name: alice
    kind: User
```

## Nodes


> **Warning**
>
> Due to <a href="https://github.com/kubernetes/kubernetes/issues/100096">CVE-2021-25735</a> this feature is only supported for Kubernetes version older than: v1.18.18, v1.19.10, v1.20.6, v1.21.0


When using capsule together with [capsule-proxy](/docs/proxy/_index), Bill can allow Tenant Owners to modify Nodes.

By default, it will allow tenant owners to add and modify any label or annotation on their nodes.

But there are some scenarios, when tenant owners should not have an ability to add or modify specific labels or annotations (there are some types of labels or annotations, which must be protected from modifications - for example, which are set by cloud-providers or autoscalers).

Bill, the cluster admin, can deny Tenant Owners to add or modify specific labels and annotations on Nodes:

```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: CapsuleConfiguration
metadata:
  name: default
spec:
  nodeMetadata:
    forbiddenAnnotations:
      denied:
        - foo.acme.net
        - bar.acme.net
      deniedRegex: .*.acme.net
    forbiddenLabels:
      denied:
        - foo.acme.net
        - bar.acme.net
      deniedRegex: .*.acme.net
  userGroups:
    - projectcapsule.dev
    - system:serviceaccounts:default
```

## Services


> **Deprecated**
>
> This feature will be deprecated in a future release of Capsule. Instead use <a href="/docs/rules/enforcement/metadata">Metadata Rules</a>. <strong><a href="/docs/rules/enforcement/metadata/#migrate-service-metadata">Migration Guide Here</a></strong>


The cluster admin can "taint" the services created by the tenant owners with additional metadata as labels and annotations.

Assigns additional labels and annotations to all services created in the `solar` tenant:

```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  owners:
  - name: alice
    kind: User
  serviceOptions:
    additionalMetadata:
      annotations:
        storagelocationtype: s3
      labels:
        projectcapsule.dev/backup: "true"
```

When the tenant owner creates a service in a tenant namespace, it inherits the given label and/or annotation:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: solar-production
  labels:
    projectcapsule.dev/backup: "true"
  annotations:
    storagelocationtype: s3
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  selector:
    run: nginx
  type: ClusterIP
```

## Pods


> **Deprecated**
>
> This feature will be deprecated in a future release of Capsule. Instead use <a href="/docs/rules/enforcement/metadata">Metadata Rules</a>. <strong><a href="/docs/rules/enforcement/metadata/#migrate-pod-metadata">Migration Guide Here</a></strong>


The cluster admin can "taint" the pods created by the tenant owners with additional metadata as labels and annotations.

Assigns additional labels and annotations to all services created in the `solar` tenant:

```yaml
apiVersion: capsule.clastix.io/v1beta2
kind: Tenant
metadata:
  name: solar
spec:
  owners:
  - name: alice
    kind: User
  podOptions:
    additionalMetadata:
      annotations:
        storagelocationtype: s3
      labels:
        projectcapsule.dev/backup: "true"
```

When the tenant owner creates a service in a tenant namespace, it inherits the given label and/or annotation:

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: solar-production
  labels:
    projectcapsule.dev/backup: "true"
  annotations:
    storagelocationtype: s3
...
```

---

Last modified October 16, 2026: Fix: minor mistakes in CR specs in examples (#162) (6358fb2)
