Skip to content

🎓 LEVEL 38 DEBRIEF: Volume Permissions & fsGroup

Congratulations! You've mastered volume permissions - critical for secure container file access!


📊 What You Fixed

The Problem:

spec:
  containers:
  - securityContext:
      runAsUser: 1000  # Runs as user 1000
  # ❌ No fsGroup! Volume owned by root
Result: Permission denied when writing to volume

The Solution:

spec:
  securityContext:  # ✅ Pod-level
    fsGroup: 1000
  containers:
  - securityContext:
      runAsUser: 1000
      runAsGroup: 1000
Result: Volume group ownership changed to 1000, write access granted


🔍 Understanding Volume Permissions

The Permission Problem

Default Behavior: - Volume created with root ownership (0:0) - Container runs as non-root user (e.g., 1000) - User 1000 cannot write to root-owned directory

Without fsGroup:

drwxr-xr-x  2 root root  /data  # Only root can write
# User 1000 gets: Permission denied

With fsGroup: 1000:

drwxrwsr-x  2 root 1000  /data  # Group 1000 can write!
# User 1000 (in group 1000) can write

Security Context Levels

Container-level (per-container):

containers:
- securityContext:
    runAsUser: 1000      # Run as this user
    runAsGroup: 1000     # Run as this group
    readOnlyRootFilesystem: true

Pod-level (affects all containers + volumes):

spec:
  securityContext:
    fsGroup: 1000        # Change volume group ownership
    runAsNonRoot: true   # Enforce non-root
    fsGroupChangePolicy: "OnRootMismatch"


💥 Common Mistakes

Mistake 1: fsGroup in Wrong Place

containers:
- securityContext:
    fsGroup: 1000  # ❌ Wrong! Goes at pod level

Fix:

spec:
  securityContext:  # ✅ Pod level
    fsGroup: 1000

Mistake 2: Mismatched User and Group

spec:
  securityContext:
    fsGroup: 2000
  containers:
  - securityContext:
      runAsUser: 1000
      runAsGroup: 1000  # ❌ Doesn't match fsGroup!

Mistake 3: Root User with fsGroup

spec:
  securityContext:
    fsGroup: 1000  # Ignored! Root has full access anyway
  containers:
  - securityContext:
      runAsUser: 0  # Running as root

🛡️ Best Practices

  1. Always set fsGroup for non-root containers:

    securityContext:
      fsGroup: 1000
      runAsNonRoot: true
    

  2. Match fsGroup with runAsGroup:

    spec:
      securityContext:
        fsGroup: 1000
      containers:
      - securityContext:
          runAsUser: 1000
          runAsGroup: 1000
    

  3. Use fsGroupChangePolicy:

    securityContext:
      fsGroup: 1000
      fsGroupChangePolicy: "OnRootMismatch"
      # Only changes ownership if needed (faster)
    

  4. Document required permissions:

    metadata:
      annotations:
        securityContext: "runAsUser=1000, fsGroup=1000"
    


🎯 Key Takeaways

  1. fsGroup changes volume group ownership - Enables write access
  2. Set at pod level - Not container level
  3. Match with runAsGroup - For consistency
  4. Required for non-root containers - That need to write to volumes
  5. Check with ls -la - Verify permissions in pod

Well done! You understand volume permissions! 🎉