docs(phase-02): research IAM & Security lab domain
This commit is contained in:
453
.planning/phases/02-lab-01-iam-sicurezza/02-RESEARCH.md
Normal file
453
.planning/phases/02-lab-01-iam-sicurezza/02-RESEARCH.md
Normal file
@@ -0,0 +1,453 @@
|
|||||||
|
# Phase 2: Lab 01 - IAM & Sicurezza - Research
|
||||||
|
|
||||||
|
**Researched:** 2026-03-24
|
||||||
|
**Domain:** Docker Security, Linux User Management, IAM Parallels
|
||||||
|
**Confidence:** HIGH
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Phase 2 focuses on teaching IAM (Identity and Access Management) concepts through local Linux user management and Docker socket permissions. Students will learn to configure Linux users, groups, and Docker socket access control, drawing direct parallels to AWS IAM Users, Roles, and Policies.
|
||||||
|
|
||||||
|
**Primary recommendation:** Use standard Docker group-based permissions model for socket access, complemented by rootless Docker demonstrations for advanced security concepts. Avoid custom authentication layers - use Docker's native security model.
|
||||||
|
|
||||||
|
## Standard Stack
|
||||||
|
|
||||||
|
### Core
|
||||||
|
| Library/Tool | Version | Purpose | Why Standard |
|
||||||
|
|--------------|---------|---------|--------------|
|
||||||
|
| Docker Engine | >= 24.0 | Container runtime, socket permissions | Project-wide standard, native permission model |
|
||||||
|
| Docker Compose | V2 | Multi-container orchestration | Project-wide standard |
|
||||||
|
| Linux utilities | (system) | useradd, groupadd, chmod, chown | Standard POSIX user management |
|
||||||
|
| BASH | >= 4.0 | Test scripting, validation | Project-wide TDD approach |
|
||||||
|
|
||||||
|
### Supporting
|
||||||
|
| Library/Tool | Version | Purpose | When to Use |
|
||||||
|
|--------------|---------|---------|-------------|
|
||||||
|
| BATS Core | latest | Advanced test framework | Optional: for complex test suites beyond basic bash |
|
||||||
|
| newuidmap/newgidmap | (system) | User namespace mapping | For rootless Docker demonstrations |
|
||||||
|
|
||||||
|
### Alternatives Considered
|
||||||
|
| Instead of | Could Use | Tradeoff |
|
||||||
|
|------------|-----------|----------|
|
||||||
|
| Docker group permissions | Rootless Docker only | Rootless is more secure but harder to teach beginners; start with group model, mention rootless as advanced topic |
|
||||||
|
| BASH scripts | BATS framework | BATS provides better testing primitives but adds dependency; use BASH for simplicity, BATS optional for advanced validation |
|
||||||
|
|
||||||
|
**Installation:**
|
||||||
|
```bash
|
||||||
|
# Core utilities (typically pre-installed)
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||||
|
|
||||||
|
# For rootless Docker (optional/advanced)
|
||||||
|
sudo apt-get install -y uidmap slirp4netns fuse-overlayfs
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture Patterns
|
||||||
|
|
||||||
|
### Recommended Project Structure
|
||||||
|
```
|
||||||
|
labs/lab-01-iam/
|
||||||
|
├── tutorial/
|
||||||
|
│ ├── 01-create-users.md
|
||||||
|
│ ├── 02-docker-groups.md
|
||||||
|
│ ├── 03-socket-permissions.md
|
||||||
|
│ └── 04-verification.md
|
||||||
|
├── how-to-guides/
|
||||||
|
│ ├── add-user-to-docker-group.md
|
||||||
|
│ ├── verify-non-root-container.md
|
||||||
|
│ └── reset-docker-permissions.md
|
||||||
|
├── reference/
|
||||||
|
│ ├── docker-socket-permissions.md
|
||||||
|
│ ├── linux-users-groups.md
|
||||||
|
│ └── iam-parallels.md
|
||||||
|
├── explanation/
|
||||||
|
│ └── docker-iam-parallels.md
|
||||||
|
├── tests/
|
||||||
|
│ ├── 01-user-creation-test.sh
|
||||||
|
│ ├── 02-docker-access-test.sh
|
||||||
|
│ └── 03-non-root-test.sh
|
||||||
|
└── docker-compose.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 1: Docker Group-Based Socket Access
|
||||||
|
**What:** Standard Docker security model where adding users to `docker` group grants socket access
|
||||||
|
**When to use:** Default teaching approach for Lab 1
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
# Source: Docker official documentation
|
||||||
|
# Create user without Docker access
|
||||||
|
sudo useradd -m -s /bin/bash student1
|
||||||
|
|
||||||
|
# Add to docker group for socket access
|
||||||
|
sudo usermod -aG docker student1
|
||||||
|
|
||||||
|
# Verify group membership
|
||||||
|
groups student1
|
||||||
|
# Output: student1 : student1 docker
|
||||||
|
|
||||||
|
# Test access (requires re-login for group changes to take effect)
|
||||||
|
su - student1
|
||||||
|
docker ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 2: Non-Root Container Execution
|
||||||
|
**What:** Running containers as unprivileged users instead of root (default)
|
||||||
|
**When to use:** ALL containers in Lab 1 (INF-01 requirement)
|
||||||
|
**Example:**
|
||||||
|
```dockerfile
|
||||||
|
# Source: Docker security best practices
|
||||||
|
FROM alpine:3.19
|
||||||
|
# Create non-root user
|
||||||
|
RUN addgroup -g 1000 appuser && \
|
||||||
|
adduser -D -u 1000 -G appuser appuser
|
||||||
|
# Switch to non-root user
|
||||||
|
USER appuser
|
||||||
|
# Verify non-root execution
|
||||||
|
CMD ["sh", "-c", "whoami && sleep 3600"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# docker-compose.yml
|
||||||
|
services:
|
||||||
|
test-container:
|
||||||
|
image: alpine:3.19
|
||||||
|
user: "1000:1000" # UID:GID for non-root
|
||||||
|
command: ["sh", "-c", "whoami && sleep 3600"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 3: IAM Parallels Documentation
|
||||||
|
**What:** Explicit mapping between Linux concepts and AWS IAM concepts
|
||||||
|
**When to use:** In Explanation documents
|
||||||
|
**Example:**
|
||||||
|
```markdown
|
||||||
|
# Parallel: Linux User Management → AWS IAM
|
||||||
|
|
||||||
|
| Concepto Linux | AWS IAM Equivalente | Spiegazione |
|
||||||
|
|----------------|---------------------|-------------|
|
||||||
|
| Utente Linux (`student1`) | IAM User | Identità che può autenticarsi |
|
||||||
|
| Gruppo Linux (`docker`) | IAM Group | Collezione di utenti con stessi permessi |
|
||||||
|
| Permessi file/socket | IAM Policy | Regole che definiscono cosa è permesso |
|
||||||
|
| `/var/run/docker.sock` | Service Endpoint | Risorsa protetta da controlli accesso |
|
||||||
|
| `sudo` elevation | IAM Role Assumption | Temporanea elevazione privilegi |
|
||||||
|
```
|
||||||
|
|
||||||
|
### Anti-Patterns to Avoid
|
||||||
|
- **Running containers as root:** Violates INF-01, creates security risk
|
||||||
|
- **Using `--privileged` flag:** Defeats container isolation, never use in teaching
|
||||||
|
- **chmod 777 on docker.sock:** Breaks all security models
|
||||||
|
- **Teaching rootless Docker first:** Too advanced for beginners, teach group model first
|
||||||
|
- **Skipping verification tests:** TDD approach requires RED→GREEN→REFACTOR cycle
|
||||||
|
|
||||||
|
## Don't Hand-Roll
|
||||||
|
|
||||||
|
| Problem | Don't Build | Use Instead | Why |
|
||||||
|
|---------|-------------|-------------|-----|
|
||||||
|
| Docker permission system | Custom ACL scripts | Native docker group membership | Docker's built-in security model is battle-tested |
|
||||||
|
| User authentication | PAM modules | Standard Linux useradd/usermod | Simpler, widely understood, POSIX compliant |
|
||||||
|
| Test framework | Custom assertion library | BASH builtins + BATS (optional) | No dependency hell, students already know bash |
|
||||||
|
| Container user management | Custom uid/gid mapping | Docker `USER` directive, user namespaces | Native Docker features handle edge cases |
|
||||||
|
|
||||||
|
**Key insight:** Docker's permission model, while simple, is production-grade. Building custom authentication layers teaches wrong lessons about using established security patterns.
|
||||||
|
|
||||||
|
## Common Pitfalls
|
||||||
|
|
||||||
|
### Pitfall 1: Group Membership Requires Re-Login
|
||||||
|
**What goes wrong:** User added to docker group but `docker ps` still fails with "permission denied"
|
||||||
|
**Why it happens:** Group membership is evaluated at login; current session doesn't see new groups
|
||||||
|
**How to avoid:** Teach students to use `newgrp docker` OR `su - user` OR logout/login
|
||||||
|
**Warning signs:** "Got permission denied while trying to connect to the Docker daemon socket"
|
||||||
|
|
||||||
|
### Pitfall 2: Testing as Wrong User
|
||||||
|
**What goes wrong:** Test passes when run as root but fails as regular user
|
||||||
|
**Why it happens:** Root can bypass Docker socket permissions
|
||||||
|
**How to avoid:** All tests MUST run as non-privileged user, use `sudo -u student1` for testing
|
||||||
|
**Warning signs:** Test passes with `sudo` but fails without it
|
||||||
|
|
||||||
|
### Pitfall 3: Insufficient Verification of Non-Root Execution
|
||||||
|
**What goes wrong:** Container configured with `USER` directive but still running as root
|
||||||
|
**Why it happens:** Dockerfile USER directive not applied, or docker-compose `user` override missing, or container switches back to root
|
||||||
|
**How to avoid:** Always verify with `docker exec <container> whoami` AND `docker inspect <container> | grep User`
|
||||||
|
**Warning signs:** Container process shows as root in `docker top` or `docker inspect`
|
||||||
|
|
||||||
|
### Pitfall 4: Socket Permissions After Docker Restart
|
||||||
|
**What goes wrong:** Docker daemon restart changes socket permissions
|
||||||
|
**Why it happens:** Docker daemon may reset socket ownership on restart
|
||||||
|
**How to avoid:** Document that docker group membership persists but socket may need verification
|
||||||
|
**Warning signs:** Previously working docker commands fail after `sudo systemctl restart docker`
|
||||||
|
|
||||||
|
## Code Examples
|
||||||
|
|
||||||
|
Verified patterns from official sources:
|
||||||
|
|
||||||
|
### Creating Non-Root Dockerfile
|
||||||
|
```dockerfile
|
||||||
|
# Source: Docker security best practices
|
||||||
|
FROM alpine:3.19
|
||||||
|
|
||||||
|
# Create non-root user with specific UID/GID for consistency
|
||||||
|
RUN addgroup -g 1000 appgroup && \
|
||||||
|
adduser -D -u 1000 -G appgroup appuser
|
||||||
|
|
||||||
|
# Switch to non-root user BEFORE any operations that don't require root
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Verify non-root execution
|
||||||
|
CMD ["sh", "-c", "echo 'Running as:' && whoami"]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verifying Container User Runtime
|
||||||
|
```bash
|
||||||
|
# Source: Docker CLI documentation
|
||||||
|
# Method 1: Execute whoami inside container
|
||||||
|
docker exec <container_name> whoami
|
||||||
|
# Expected output: appuser (NOT root)
|
||||||
|
|
||||||
|
# Method 2: Inspect container configuration
|
||||||
|
docker inspect <container_name> --format='{{.State.User}}'
|
||||||
|
# Note: May show empty if using docker-compose user directive
|
||||||
|
|
||||||
|
# Method 3: Check process on host
|
||||||
|
docker top <container_name>
|
||||||
|
# Look at USER column - should show UID (e.g., 1000), NOT 0 (root)
|
||||||
|
|
||||||
|
# Method 4: Comprehensive check script
|
||||||
|
#!/bin/bash
|
||||||
|
container_name=$1
|
||||||
|
actual_user=$(docker exec $container_name whoami)
|
||||||
|
echo "Container running as: $actual_user"
|
||||||
|
if [ "$actual_user" = "root" ]; then
|
||||||
|
echo "FAIL: Container running as root!"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "PASS: Container running as non-root user"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing Docker Access Control
|
||||||
|
```bash
|
||||||
|
# Source: TDD approach for infrastructure
|
||||||
|
#!/bin/bash
|
||||||
|
# RED phase: Test should fail initially
|
||||||
|
|
||||||
|
# Test 1: Non-group member cannot access docker socket
|
||||||
|
test_unauthorized_access() {
|
||||||
|
sudo useradd -m -s /bin/bash test_user 2>/dev/null || true
|
||||||
|
if sudo -u test_user docker ps &>/dev/null; then
|
||||||
|
echo "FAIL: test_user can access docker without being in docker group"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
echo "PASS: test_user correctly denied access"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test 2: Group member can access docker socket
|
||||||
|
test_authorized_access() {
|
||||||
|
sudo usermod -aG docker test_user
|
||||||
|
# newgrp doesn't work in sudo, so we need to test differently
|
||||||
|
# Check group membership instead
|
||||||
|
if groups test_user | grep -q docker; then
|
||||||
|
echo "PASS: test_user is in docker group"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "FAIL: test_user not in docker group"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test 3: Container runs as non-root
|
||||||
|
test_non_root_container() {
|
||||||
|
# Create test container
|
||||||
|
echo 'FROM alpine:3.19
|
||||||
|
RUN adduser -D -u 1000 testuser
|
||||||
|
USER testuser
|
||||||
|
CMD ["sh", "-c", "whoami"]' > /tmp/test.Dockerfile
|
||||||
|
|
||||||
|
docker build -f /tmp/test.Dockerfile -t test-non-root . >/dev/null 2>&1
|
||||||
|
result=$(docker run --rm test-non-root)
|
||||||
|
|
||||||
|
if [ "$result" = "testuser" ]; then
|
||||||
|
echo "PASS: Container runs as non-root user"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo "FAIL: Container running as $result (expected testuser)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run all tests
|
||||||
|
test_unauthorized_access && \
|
||||||
|
test_authorized_access && \
|
||||||
|
test_non_root_container && \
|
||||||
|
echo "All tests passed!" || echo "Some tests failed"
|
||||||
|
```
|
||||||
|
|
||||||
|
## State of the Art
|
||||||
|
|
||||||
|
| Old Approach | Current Approach | When Changed | Impact |
|
||||||
|
|--------------|------------------|--------------|--------|
|
||||||
|
| Rootful Docker only | Rootless Docker available | Docker 19.03+ | Labs can now demonstrate true non-root Docker daemon |
|
||||||
|
| `--user` flag only | User namespaces + userns-remap | Docker 1.10+ | Multiple isolation layers for defense-in-depth |
|
||||||
|
| Manual test scripts | BATS framework adoption | 2020+ | Professional-grade test infrastructure for bash |
|
||||||
|
|
||||||
|
**Deprecated/outdated:**
|
||||||
|
- **Docker socket as `chmod 777`:** NEVER use, completely bypasses security
|
||||||
|
- **Running daemons as root inside container:** Violates security best practices
|
||||||
|
- **Using `--privileged` flag:** Defeats container isolation, only for edge cases in advanced labs
|
||||||
|
|
||||||
|
## Validation Architecture
|
||||||
|
|
||||||
|
> This section defines validation/testing approach for Phase 2 based on TDD methodology and project requirements.
|
||||||
|
|
||||||
|
### Test Framework
|
||||||
|
| Property | Value |
|
||||||
|
|----------|-------|
|
||||||
|
| Framework | BASH (Bourne Again Shell) >= 4.0 |
|
||||||
|
| Config file | None — inline test functions |
|
||||||
|
| Quick run command | `bash labs/lab-01-iam/tests/quick-test.sh` |
|
||||||
|
| Full suite command | `bash labs/lab-01-iam/tests/run-all-tests.sh` |
|
||||||
|
|
||||||
|
### Phase Requirements → Test Map
|
||||||
|
|
||||||
|
| Req ID | Behavior | Test Type | Automated Command | File Exists? |
|
||||||
|
|--------|----------|-----------|-------------------|-------------|
|
||||||
|
| LAB-01 | Studente può configurare utenti Linux, gruppi e permessi per accesso Docker socket | integration | `bash tests/test-01-user-creation.sh` | ❌ Wave 0 |
|
||||||
|
| DOCT-01 | Lab include Tutorial (guida passo-passo) | manual | Verify file exists: `tutorial/01-create-users.md` | ❌ Wave 0 |
|
||||||
|
| DOCT-02 | Lab include How-to Guides | manual | Verify files exist: `how-to-guides/*.md` | ❌ Wave 0 |
|
||||||
|
| DOCT-03 | Lab include Reference | manual | Verify file exists: `reference/docker-socket-permissions.md` | ❌ Wave 0 |
|
||||||
|
| DOCT-04 | Lab include Explanation (parallelismo Docker ↔ cloud) | manual | Verify file exists: `explanation/docker-iam-parallels.md` | ❌ Wave 0 |
|
||||||
|
| DOCT-05 | Tutorial segue principio "little often" | manual | Review tutorial for incremental steps | ❌ Wave 0 |
|
||||||
|
| TEST-01 | Script di test bash pre-implementazione (TDI) | unit | `bash tests/02-docker-access-test.sh` | ❌ Wave 0 |
|
||||||
|
| TEST-05 | Comando di verifica finale ("double check") | integration | `bash tests/99-final-verification.sh` | ❌ Wave 0 |
|
||||||
|
| INF-01 | Nessun container gira come utente root | unit | `bash tests/03-non-root-test.sh` | ❌ Wave 0 |
|
||||||
|
| PARA-01 | Componente Docker mappato a servizio cloud (IAM Users) | manual | Verify Explanation document includes mapping table | ❌ Wave 0 |
|
||||||
|
| PARA-03 | Differenze tra locale e cloud documentate | manual | Verify Explanation includes differences section | ❌ Wave 0 |
|
||||||
|
| PARA-04 | Comandi Docker equivalenti a comandi cloud mostrati | manual | Verify Reference includes command comparison | ❌ Wave 0 |
|
||||||
|
|
||||||
|
### Sampling Rate
|
||||||
|
- **Per task commit:** `bash labs/lab-01-iam/tests/quick-test.sh` (runs in < 30 seconds)
|
||||||
|
- **Per wave merge:** `bash labs/lab-01-iam/tests/run-all-tests.sh` (full validation)
|
||||||
|
- **Phase gate:** Full suite green + manual verification of all 4 Diátaxis documents + INF-01 verified
|
||||||
|
|
||||||
|
### Wave 0 Gaps
|
||||||
|
- [ ] `labs/lab-01-iam/tests/01-user-creation-test.sh` — tests user/group creation and Docker socket access
|
||||||
|
- [ ] `labs/lab-01-iam/tests/02-non-root-test.sh` — verifies INF-01: no container runs as root
|
||||||
|
- [ ] `labs/lab-01-iam/tests/99-final-verification.sh` — double check command for students
|
||||||
|
- [ ] `labs/lab-01-iam/tutorial/01-create-users.md` — first Diátaxis tutorial
|
||||||
|
- [ ] `labs/lab-01-iam/how-to-guides/` — directory for goal-oriented guides
|
||||||
|
- [ ] `labs/lab-01-iam/reference/` — directory for technical specifications
|
||||||
|
- [ ] `labs/lab-01-iam/explanation/docker-iam-parallels.md` — IAM parallelism explanation
|
||||||
|
- [ ] Test harness setup: None needed — using pure BASH
|
||||||
|
|
||||||
|
### Success Criteria Validation
|
||||||
|
|
||||||
|
**Success Criteria 1:** Studente può creare utenti Linux con permessi limitati per accesso Docker socket
|
||||||
|
- **How to verify:** Test script creates user, verifies NOT in docker group, confirms `docker ps` fails, adds to docker group, confirms `docker ps` succeeds
|
||||||
|
- **Test command:** `bash tests/01-user-creation-test.sh`
|
||||||
|
- **Manual check:** Student follows Tutorial and demonstrates working Docker access
|
||||||
|
|
||||||
|
**Success Criteria 2:** Studente comprende il parallelismo tra utenti Linux/permessi Docker e IAM Users/Roles in cloud
|
||||||
|
- **How to verify:** Explanation document includes mapping table comparing Linux concepts to AWS IAM
|
||||||
|
- **Manual check:** Review `explanation/docker-iam-parallels.md` for explicit parallels
|
||||||
|
- **Test command:** None — conceptual understanding verified through documentation quality
|
||||||
|
|
||||||
|
**Success Criteria 3:** Nessun container gira come root (principio minimo privilegio verificato)
|
||||||
|
- **How to verify:** Automated test checks `docker exec <container> whoami` returns non-root
|
||||||
|
- **Test command:** `bash tests/02-non-root-test.sh`
|
||||||
|
- **Manual check:** `docker inspect` shows User field set, docker-compose.yml has `user:` directive
|
||||||
|
|
||||||
|
**Success Criteria 4:** Lab include Tutorial, How-to Guides, Reference, Explanation (Diátaxis completo)
|
||||||
|
- **How to verify:** File structure check confirms all 4 document types exist
|
||||||
|
- **Manual check:** Review each document for Diátaxis compliance
|
||||||
|
- **Test command:** `find labs/lab-01-iam -name "*.md" | grep -E "(tutorial|how-to|reference|explanation)"`
|
||||||
|
|
||||||
|
**Success Criteria 5:** Studente può eseguire comando di verifica finale ("double check")
|
||||||
|
- **How to verify:** Final verification script runs all checks and produces PASS/FAIL report
|
||||||
|
- **Test command:** `bash tests/99-final-verification.sh`
|
||||||
|
- **Manual check:** Student runs script and sees all tests passing
|
||||||
|
|
||||||
|
### TDI Methodology Verification
|
||||||
|
|
||||||
|
**RED Phase (Pre-Implementation):**
|
||||||
|
- Test scripts are written BEFORE docker-compose.yml or Dockerfiles
|
||||||
|
- Tests explicitly fail when run against non-existent infrastructure
|
||||||
|
- Example: `test_01-user-creation-test.sh` checks for users that don't exist yet
|
||||||
|
|
||||||
|
**GREEN Phase (Implementation):**
|
||||||
|
- Minimum infrastructure created to make tests pass
|
||||||
|
- docker-compose.yml includes `user:` directive for all services
|
||||||
|
- Test execution produces all PASS results
|
||||||
|
|
||||||
|
**REFACTOR Phase (Optimization):**
|
||||||
|
- Test coverage remains 100% after optimizations
|
||||||
|
- Documentation improvements don't break existing tests
|
||||||
|
- Security enhancements (e.g., user namespaces) are tested before deployment
|
||||||
|
|
||||||
|
### INF-01 Verification (No Root Containers)
|
||||||
|
|
||||||
|
**Automated Verification:**
|
||||||
|
```bash
|
||||||
|
# Test runs for every container defined in docker-compose.yml
|
||||||
|
for service in $(docker-compose ps --services); do
|
||||||
|
container_name=$(docker-compose ps -q $service)
|
||||||
|
actual_user=$(docker exec $container_name whoami 2>/dev/null)
|
||||||
|
if [ "$actual_user" = "root" ]; then
|
||||||
|
echo "FAIL: $service running as root"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "PASS: All containers running as non-root"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Manual Verification:**
|
||||||
|
1. Check docker-compose.yml for `user:` directive on all services
|
||||||
|
2. Run `docker-compose ps` to get container names
|
||||||
|
3. Run `docker top <container>` and verify USER column != root
|
||||||
|
4. Run `docker inspect <container>` and verify Config.User is set
|
||||||
|
|
||||||
|
**Continuous Verification:**
|
||||||
|
- Quick test runs on every commit during development
|
||||||
|
- Full test suite runs before merging lab branch to main
|
||||||
|
- Phase gate requires 100% PASS rate for all tests
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
|
||||||
|
1. **Should we teach rootless Docker in Lab 1?**
|
||||||
|
- What we know: Rootless Docker is more secure but adds complexity (uidmap, slirp4netns, etc.)
|
||||||
|
- What's unclear: Is it too advanced for first lab?
|
||||||
|
- Recommendation: Teach standard docker group model in Lab 1, mention rootless as "advanced topic" in Explanation
|
||||||
|
|
||||||
|
2. **How to handle the "newgrp" limitation in automated tests?**
|
||||||
|
- What we know: Group membership requires re-login to take effect
|
||||||
|
- What's unclear: Best practice for automated testing without interactive login
|
||||||
|
- Recommendation: Test group membership with `groups` command, not actual Docker access, or use `sg docker -c "docker ps"`
|
||||||
|
|
||||||
|
3. **What UID/GID should we use for non-root containers?**
|
||||||
|
- What we know: Common practice is 1000:1000, but may conflict with host users
|
||||||
|
- What's unclear: Should we use specific UIDs to avoid conflicts?
|
||||||
|
- Recommendation: Use 1000:1000 for simplicity, document potential conflicts in troubleshooting guide
|
||||||
|
|
||||||
|
## Sources
|
||||||
|
|
||||||
|
### Primary (HIGH confidence)
|
||||||
|
- Docker Engine Security Documentation - https://docs.docker.com/engine/security/ - Namespaces, control groups, daemon attack surface, capabilities
|
||||||
|
- Rootless Docker Documentation - https://docs.docker.com/engine/security/rootless/ - Installation, user namespaces, limitations
|
||||||
|
- AWS IAM Introduction - https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html - Identities, policies, authentication vs authorization
|
||||||
|
|
||||||
|
### Secondary (MEDIUM confidence)
|
||||||
|
- Docker Compose Documentation - https://docs.docker.com/compose/ - `user` directive, service configuration
|
||||||
|
- Linux user management (useradd, usermod) - Standard POSIX utilities
|
||||||
|
|
||||||
|
### Tertiary (LOW confidence)
|
||||||
|
- None - all findings verified with official documentation
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
**Confidence breakdown:**
|
||||||
|
- Standard stack: HIGH - Docker and Linux utilities are project-wide standards
|
||||||
|
- Architecture: HIGH - Based on official Docker security documentation
|
||||||
|
- Pitfalls: HIGH - Common issues verified through Docker documentation and best practices
|
||||||
|
|
||||||
|
**Research date:** 2026-03-24
|
||||||
|
**Valid until:** 2026-04-23 (30 days - Docker security model is stable)
|
||||||
Reference in New Issue
Block a user