# Containers run with read-only root filesystem where permitted

- **Pattern:** `ab-001640` (`infrastructure-hardening.access-control-rbac.read-only-filesystem`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001640
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001640)

## Why it matters

A writable root filesystem allows malware dropped into a container to persist — modified binaries, installed backdoors, and written cron jobs survive across request handling even if the attacker's initial vector closes. NIST 800-53 CM-7 requires containers to provide only essential functionality. CIS Kubernetes 5.2.3 mandates read-only root filesystems for stateless workloads. Most stateless API servers and web frontends have zero legitimate need to write to the root filesystem at runtime — only log paths and temp directories require writability, and both can be served by emptyDir volumes.

## Severity rationale

Medium because a writable root filesystem allows an attacker with code execution to persist modifications across requests, but direct exploitation still requires a separate initial compromise.

## Remediation

Enable `readOnlyRootFilesystem: true` and mount emptyDir volumes for any paths the application writes to. In your Deployment manifest:

```yaml
containers:
  - name: app
    securityContext:
      readOnlyRootFilesystem: true
    volumeMounts:
      - name: tmp-dir
        mountPath: /tmp
      - name: log-dir
        mountPath: /var/log/app
volumes:
  - name: tmp-dir
    emptyDir: {}
  - name: log-dir
    emptyDir: {}
```

Verify the application starts cleanly with this setting before rolling to production — some frameworks write PID files or session caches to paths that need explicit emptyDir mounts.

## Detection

- **ID:** `read-only-filesystem`
- **Severity:** `medium`
- **What to look for:** Count all container definitions in Kubernetes manifests and for each, check whether `securityContext.readOnlyRootFilesystem: true` is set. For containers with read-only filesystems, verify that writable mount points (emptyDir volumes for `/tmp` or `/var/log`) are configured for paths that need write access.
- **Pass criteria:** At least 80% of containers have `readOnlyRootFilesystem: true` configured in their securityContext, with writable emptyDir volumes mounted for any paths that require write access (at minimum `/tmp`). Report: "X of Y containers use read-only root filesystem."
- **Fail criteria:** Any stateless container allows write access to the root filesystem when the application does not require it — most stateless web services and API servers can run read-only.
- **Skip (N/A) when:** The application legitimately requires write access to the root filesystem (e.g., database, legacy application).
- **Detail on fail:** Quote the Deployment name. Example: `"Deployment 'web-app' lacks readOnlyRootFilesystem: true. Stateless web application could run with read-only root."`
- **Remediation:** Enable read-only root filesystem for applications that do not require write access:

  ```yaml
  securityContext:
    readOnlyRootFilesystem: true
  volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: logs
      mountPath: /var/log
  volumes:
    - name: tmp
      emptyDir: {}
    - name: logs
      emptyDir: {}
  ```

## External references

- nist CM-7
- external CIS-Kubernetes-5.2.3 — https://www.cisecurity.org/benchmark/kubernetes

Taxons: operational-readiness

HTML version: https://auditbuffet.com/patterns/ab-001640
