> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Tenant Namespaces Should Have A ResourceQuota

### More Info:

Advisory: create a ResourceQuota per tenant namespace to bound aggregate CPU, memory and object counts, preventing one tenant from starving others.

### Risk Level

Low

### Address

Security

### Compliance Standards

* Cloudanix Best Practice

### Triage and Remediation

<Tabs>
  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Manual Steps" defaultOpen="true">
        1. **Identify tenant namespaces (decision step)**\
           On any machine with kubectl access, list namespaces and decide which are “tenant” namespaces (per your org’s multi-tenancy model; usually app or team namespaces, not `kube-*`, `default`, or system namespaces):
           ```bash theme={null}
           kubectl get ns --show-labels
           ```
           Optionally, if you label tenant namespaces (recommended), e.g. `tenant=true`, list them:
           ```bash theme={null}
           kubectl get ns -l tenant=true
           ```

        2. **Check which tenant namespaces lack a ResourceQuota**\
           For each tenant namespace you identified, check for existing ResourceQuota objects:
           ```bash theme={null}
           kubectl get resourcequota -n <TENANT_NAMESPACE>
           ```
           Note which tenant namespaces return `No resources found` or have quotas that clearly do not bound CPU, memory, and object counts.

        3. **Review existing ResourceQuota coverage and sufficiency (decision step)**\
           For tenant namespaces that do have a ResourceQuota, inspect them to ensure they bound at least aggregate CPU, memory, and key object counts (e.g. pods, services, PVCs, configmaps, secrets):
           ```bash theme={null}
           kubectl describe resourcequota -n <TENANT_NAMESPACE>
           ```
           Decide whether limits are appropriate for the tenant (not too low to break workloads, not so high that tenants can starve others).

        4. **Design quota policies per tenant type (decision step)**\
           Outside the cluster (on any admin workstation), define standard quota “profiles” for different tenant types (e.g. small/medium/large) that include:
           * `requests.cpu`, `requests.memory`, `limits.cpu`, `limits.memory`
           * `pods`, `services`, `persistentvolumeclaims`, `configmaps`, `secrets`, etc.\
             Document which profile each tenant namespace should receive based on current and projected usage.

        5. **Create or update ResourceQuota manifests for tenant namespaces**\
           On any machine with kubectl access, create or adjust ResourceQuota objects according to your profiles. Example manifest (adjust values per your decisions):
           ```yaml theme={null}
           cat << 'EOF' > tenant-resourcequota.yaml
           apiVersion: v1
           kind: ResourceQuota
           metadata:
             name: tenant-quota
             namespace: <TENANT_NAMESPACE>
           spec:
             hard:
               requests.cpu: "4"
               requests.memory: "8Gi"
               limits.cpu: "8"
               limits.memory: "16Gi"
               pods: "50"
               services: "10"
               persistentvolumeclaims: "20"
               configmaps: "50"
               secrets: "50"
           EOF
           ```
           Apply for each tenant namespace (edit the manifest namespace or generate one per namespace):
           ```bash theme={null}
           kubectl apply -f tenant-resourcequota.yaml
           ```

        6. **Verify quotas are in place and effective**\
           On any machine with kubectl access, confirm that every tenant namespace now has an appropriate ResourceQuota and that usage is tracked:
           ```bash theme={null}
           # List quotas per tenant namespace
           kubectl get resourcequota -n <TENANT_NAMESPACE>

           # Confirm hard limits and current usage
           kubectl describe resourcequota -n <TENANT_NAMESPACE>
           ```
           Re-run this check for all tenant namespaces; any tenant namespace without a ResourceQuota, or with quotas that don’t bound CPU, memory, and object counts, should be revisited using steps 3–5.
      </Accordion>

      <Accordion title="Using kubectl">
        ```bash theme={null}
        # 1) List all namespaces to identify tenant namespaces
        # Run on: any machine with kubectl access
        kubectl get namespaces -o custom-columns=NAME:.metadata.name \
          --no-headers | sort
        ```

        Review this list and decide which are tenant namespaces (for example, team or project namespaces) versus system/internal namespaces (e.g. `kube-system`, `kube-public`, `kube-node-lease`, `istio-system`, `ingress-nginx`, etc.).

        ```bash theme={null}
        # 2) For a given tenant namespace, check for ResourceQuota objects
        # Replace TENANT_NS with an actual tenant namespace name
        kubectl get resourcequota -n TENANT_NS
        ```

        **Problem indication:**

        * If this command returns `No resources found in TENANT_NS namespace`, the tenant namespace has **no** `ResourceQuota` and is in violation of this control.
        * If it returns one or more `ResourceQuota` objects, you must still review them (next step) to decide whether the quotas are adequate.

        ```bash theme={null}
        # 3) Inspect details of each ResourceQuota in the tenant namespace
        # First, list the names:
        kubectl get resourcequota -n TENANT_NS -o name

        # Then, for each quota (example name: rq-team-a), describe it:
        kubectl describe resourcequota rq-team-a -n TENANT_NS
        ```

        **Problem indication (requires human judgment):**

        * `Hard` limits missing for CPU or memory (e.g. no entries for `limits.cpu`, `limits.memory`, `requests.cpu`, `requests.memory`) mean aggregate resource usage is not bounded.
        * Missing object count limits (e.g. `pods`, `configmaps`, `secrets`, `services`, `persistentvolumeclaims`) mean the namespace could still starve others via object count exhaustion.
        * Very high or effectively unlimited values (e.g. `0` where that means “no limit”, or values that exceed node/cluster capacity) indicate quotas are not meaningfully constraining the tenant.

        ```bash theme={null}
        # 4) Optional: summarize quotas for all namespaces to spot gaps at a glance
        kubectl get resourcequota --all-namespaces
        ```

        **Problem indication:**

        * Any tenant namespace that does **not** appear in this list lacks a `ResourceQuota` and should be reviewed and corrected.
        * Namespaces that appear with quotas but you know are **not** tenants (e.g. system namespaces) are not relevant to this control and can be ignored.
      </Accordion>

      <Accordion title="Automation">
        ```bash theme={null}
        #!/usr/bin/env bash
        #
        # Report tenant namespaces that do NOT have a ResourceQuota
        # and summarize quotas for those that do.
        #
        # Run from: any machine with kubectl access and the correct context.
        # Requires: kubectl, jq

        set -euo pipefail

        # 1) Define how to identify "tenant" namespaces.
        # Adjust this selector to match YOUR environment.
        # Examples:
        #   - All non-system namespaces:
        #       NS_SELECTOR='!name in (kube-system,kube-public,kube-node-lease,default)'
        #   - Label-based (preferred):
        #       NS_SELECTOR='tenant=true'
        #
        # Below uses label-based selection. Update to match your labels.
        NS_SELECTOR='tenant=true'

        echo "==> Discovering tenant namespaces (selector: ${NS_SELECTOR})"
        TENANT_NAMESPACES=$(kubectl get ns -l "${NS_SELECTOR}" -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}')

        if [[ -z "${TENANT_NAMESPACES}" ]]; then
          echo "No tenant namespaces found with selector '${NS_SELECTOR}'."
          exit 0
        fi

        echo ""
        echo "==> Per-namespace ResourceQuota summary"
        echo "Namespace,HasResourceQuota,QuotaName,Hard.cpu,Hard.memory,Hard.pods,Hard.configmaps,Hard.secrets,Hard.services,Hard.persistentvolumeclaims"

        MISSING_COUNT=0

        for ns in ${TENANT_NAMESPACES}; do
          RQ_JSON=$(kubectl get resourcequota -n "${ns}" -o json 2>/dev/null || echo '{}')
          RQ_COUNT=$(echo "${RQ_JSON}" | jq '.items | length')

          if [[ "${RQ_COUNT}" -eq 0 ]]; then
            # No ResourceQuota in this tenant namespace
            echo "${ns},NO,,,,,,,"
            ((MISSING_COUNT++))
            continue
          fi

          # Print one line per ResourceQuota in the namespace
          echo "${RQ_JSON}" | jq -r --arg ns "${ns}" '
            .items[] as $rq |
            [
              $ns,
              "YES",
              $rq.metadata.name,
              ($rq.spec.hard.cpu // ""),
              ($rq.spec.hard.memory // ""),
              ($rq.spec.hard.pods // ""),
              ($rq.spec.hard.configmaps // ""),
              ($rq.spec.hard.secrets // ""),
              ($rq.spec.hard.services // ""),
              ($rq.spec.hard.persistentvolumeclaims // "")
            ] | @csv
          '
        done

        echo ""
        echo "==> Summary"
        TOTAL_NS=$(echo "${TENANT_NAMESPACES}" | wc -l | tr -d ' ')
        echo "Total tenant namespaces: ${TOTAL_NS}"
        echo "Namespaces without any ResourceQuota: ${MISSING_COUNT}"

        if [[ "${MISSING_COUNT}" -gt 0 ]]; then
          echo ""
          echo "Problem indication:"
          echo "- Any line with 'HasResourceQuota' == 'NO' in the CSV output"
          echo "  (e.g. 'tenant-a,NO,....') marks a tenant namespace that lacks a ResourceQuota."
          echo "- These namespaces should be reviewed and given an appropriate ResourceQuota"
          echo "  to bound aggregate CPU, memory, and object counts."
        fi
        ```

        **What output indicates a problem**

        * In the CSV section, any row where the second column (`HasResourceQuota`) is `NO` indicates a tenant namespace that does not have any `ResourceQuota` objects defined.
        * The final summary line `Namespaces without any ResourceQuota: N`:
          * If `N > 0`, those namespaces are not constrained and should be reviewed and given an appropriate `ResourceQuota` per the benchmark guidance.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>
