diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md
index 8621354..689b152 100644
--- a/.planning/ROADMAP.md
+++ b/.planning/ROADMAP.md
@@ -12,7 +12,7 @@
| Phase | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------|
| 1. Setup & Git Foundation | 0/2 | Planning complete | - |
-| 2. Lab 01 - IAM & Sicurezza | 0/3 | Not started | - |
+| 2. Lab 01 - IAM & Sicurezza | 0/3 | Planning complete | - |
| 3. Lab 02 - Network & VPC | 0/3 | Not started | - |
| 4. Lab 03 - Compute & EC2 | 0/3 | Not started | - |
| 5. Lab 04 - Storage & S3 | 0/3 | Not started | - |
@@ -80,7 +80,11 @@
4. Lab include Tutorial passo-passo, How-to Guides, Reference, e Explanation (Framework Diátaxis completo)
5. Studente può eseguire comando di verifica finale ("double check") per validare il lavoro svolto
-**Plans:** TBD
+**Plans:** 3
+
+- [ ] [02-01-PLAN.md](.planning/phases/02-lab-01-iam-sicurezza/02-01-PLAN.md) — Create test infrastructure (Wave 0: test-01-user-creation.sh, test-02-docker-access.sh, 03-non-root-test.sh, 99-final-verification.sh, run-all-tests.sh)
+- [ ] [02-02-PLAN.md](.planning/phases/02-lab-01-iam-sicurezza/02-02-PLAN.md) — Create Diátaxis documentation (Tutorial: 3 parts, How-to Guides: 3 guides, Reference: 3 documents, Explanation: IAM parallels)
+- [ ] [02-03-PLAN.md](.planning/phases/02-lab-01-iam-sicurezza/02-03-PLAN.md) — Create infrastructure (Dockerfile with non-root user, docker-compose.yml with user directive, infrastructure verification)
---
diff --git a/.planning/phases/02-lab-01-iam-sicurezza/02-01-PLAN.md b/.planning/phases/02-lab-01-iam-sicurezza/02-01-PLAN.md
new file mode 100644
index 0000000..b9323f1
--- /dev/null
+++ b/.planning/phases/02-lab-01-iam-sicurezza/02-01-PLAN.md
@@ -0,0 +1,808 @@
+---
+phase: 02-lab-01-iam-sicurezza
+plan: 01
+type: execute
+wave: 0
+depends_on: []
+files_modified:
+ - labs/lab-01-iam/tests/test-01-user-creation.sh
+ - labs/lab-01-iam/tests/test-02-docker-access.sh
+ - labs/lab-01-iam/tests/03-non-root-test.sh
+ - labs/lab-01-iam/tests/99-final-verification.sh
+ - labs/lab-01-iam/tests/run-all-tests.sh
+autonomous: true
+requirements: [TEST-01, TEST-05, INF-01]
+user_setup: []
+must_haves:
+ truths:
+ - "Test scripts exist and can validate user creation and Docker access"
+ - "Test scripts verify non-root container execution (INF-01)"
+ - "Final verification script runs all checks for student self-validation"
+ - "Test harness can be executed with single command"
+ artifacts:
+ - path: "labs/lab-01-iam/tests/test-01-user-creation.sh"
+ provides: "User and group creation validation"
+ min_lines: 40
+ - path: "labs/lab-01-iam/tests/test-02-docker-access.sh"
+ provides: "Docker socket access control validation"
+ min_lines: 30
+ - path: "labs/lab-01-iam/tests/03-non-root-test.sh"
+ provides: "Non-root container verification (INF-01)"
+ min_lines: 35
+ - path: "labs/lab-01-iam/tests/99-final-verification.sh"
+ provides: "Final double-check command for students"
+ min_lines: 25
+ - path: "labs/lab-01-iam/tests/run-all-tests.sh"
+ provides: "Test suite orchestration"
+ min_lines: 15
+ key_links:
+ - from: "run-all-tests.sh"
+ to: "test-01-user-creation.sh, test-02-docker-access.sh, 03-non-root-test.sh, 99-final-verification.sh"
+ via: "Sequential execution with exit code handling"
+ pattern: "bash.*tests/.*\\.sh"
+---
+
+
+Create test infrastructure following TDD methodology (RED phase first). Test scripts validate user creation, Docker socket access control, and non-root container execution before any implementation exists.
+
+Purpose: Enable Test-Driven Infrastructure (TDI) by writing failing tests first, then implementing infrastructure to make them pass.
+Output: Four test scripts (user creation, Docker access, non-root verification, final check) plus test orchestration script.
+
+
+
+@/home/luca/.claude/get-shit-done/workflows/execute-plan.md
+@/home/luca/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/02-lab-01-iam-sicurezza/02-RESEARCH.md
+@.planning/phases/02-lab-01-iam-sicurezza/02-VALIDATION.md
+@CLAUDE.md
+
+# Key patterns from RESEARCH.md
+
+## TDD Methodology for Infrastructure
+```bash
+# RED Phase: Test should fail initially (no infrastructure exists)
+# GREEN Phase: Implement minimum infrastructure to pass tests
+# REFACTOR Phase: Optimize without breaking tests
+
+# Example test structure from RESEARCH.md:
+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
+}
+```
+
+## INF-01 Verification Pattern
+```bash
+# From RESEARCH.md - Non-root container verification
+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"
+```
+
+## Common Pitfalls to Handle
+- Group membership requires re-login (use `groups` command for testing)
+- Test as non-privileged user (root bypasses Docker socket permissions)
+- Verify with multiple methods: `docker exec whoami`, `docker inspect`, `docker top`
+
+## Test Framework from RESEARCH.md
+- Framework: BASH (Bourne Again Shell) >= 4.0
+- No config file needed - inline test functions
+- Quick run: `bash labs/lab-01-iam/tests/quick-test.sh`
+- Full suite: `bash labs/lab-01-iam/tests/run-all-tests.sh`
+
+
+
+
+
+ Task 1: Create user creation test script
+ labs/lab-01-iam/tests/test-01-user-creation.sh
+
+ - Test 1: Non-existent user returns appropriate failure
+ - Test 2: User not in docker group cannot access Docker socket
+ - Test 3: User can be added to docker group
+ - Test 4: Group membership verified with `groups` command
+
+
+Create test script for Linux user and group management:
+
+```bash
+#!/bin/bash
+# Test: Linux user creation and Docker group membership
+# Phase: RED - This test will fail initially (no users configured)
+
+set -euo pipefail
+
+# Color output
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m' # No Color
+
+pass_count=0
+fail_count=0
+
+test_user_not_exists() {
+ local user="lab01_student"
+ if id "$user" &>/dev/null; then
+ echo -e "${YELLOW}SKIP${NC}: User $user already exists"
+ return 0
+ fi
+ echo -e "${GREEN}PASS${NC}: User $user does not exist (test environment clean)"
+ ((pass_count++))
+ return 0
+}
+
+test_user_without_docker_group() {
+ local user="lab01_student"
+ # Create test user if doesn't exist
+ if ! id "$user" &>/dev/null; then
+ sudo useradd -m -s /bin/bash "$user" 2>/dev/null || true
+ fi
+
+ # Check if user is in docker group
+ if groups "$user" 2>/dev/null | grep -q docker; then
+ echo -e "${RED}FAIL${NC}: User $user is in docker group (should not be yet)"
+ ((fail_count++))
+ return 1
+ fi
+
+ echo -e "${GREEN}PASS${NC}: User $user is not in docker group"
+ ((pass_count++))
+ return 0
+}
+
+test_docker_access_denied() {
+ local user="lab01_student"
+
+ # Test that user cannot access docker socket
+ if sudo -u "$user" docker ps &>/dev/null; then
+ echo -e "${RED}FAIL${NC}: User $user can access docker without docker group membership"
+ ((fail_count++))
+ return 1
+ fi
+
+ echo -e "${GREEN}PASS${NC}: Docker access correctly denied for $user"
+ ((pass_count++))
+ return 0
+}
+
+# Run all tests
+echo "Running user creation tests..."
+echo "================================"
+test_user_not_exists
+test_user_without_docker_group
+test_docker_access_denied
+echo "================================"
+echo "Tests passed: $pass_count"
+echo "Tests failed: $fail_count"
+
+if [ $fail_count -gt 0 ]; then
+ exit 1
+fi
+exit 0
+```
+
+Key implementation points:
+- Use `groups` command to verify group membership (handles re-login issue)
+- Run Docker commands as test user with `sudo -u`
+- Test the negative case first (user without access)
+- Return proper exit codes (0=pass, 1=fail)
+
+
+ chmod +x labs/lab-01-iam/tests/test-01-user-creation.sh && bash labs/lab-01-iam/tests/test-01-user-creation.sh
+
+ Script exists, is executable, and tests user/group creation behavior
+
+
+
+ Task 2: Create Docker access control test script
+ labs/lab-01-iam/tests/test-02-docker-access.sh
+
+ - Test 1: User in docker group can execute docker ps
+ - Test 2: User in docker group can run basic containers
+ - Test 3: Socket permissions are correctly set (660 or stricter)
+ - Test 4: Group membership propagation is verified
+
+
+Create test script for Docker socket access control:
+
+```bash
+#!/bin/bash
+# Test: Docker socket access control via group membership
+# Phase: RED - This test will fail initially (no users configured)
+
+set -euo pipefail
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m'
+
+pass_count=0
+fail_count=0
+
+test_socket_permissions() {
+ local socket="/var/run/docker.sock"
+ local perms=$(stat -c "%a" "$socket" 2>/dev/null || echo "000")
+
+ # Socket should be 660 or stricter (no world-readable/writable)
+ if [ "$perms" = "660" ] || [ "$perms" = "600" ]; then
+ echo -e "${GREEN}PASS${NC}: Docker socket permissions are $perms"
+ ((pass_count++))
+ return 0
+ else
+ echo -e "${YELLOW}WARN${NC}: Docker socket permissions are $perms (expected 660)"
+ ((pass_count++))
+ return 0
+ fi
+}
+
+test_docker_group_exists() {
+ if getent group docker >/dev/null 2>&1; then
+ echo -e "${GREEN}PASS${NC}: Docker group exists"
+ ((pass_count++))
+ return 0
+ else
+ echo -e "${RED}FAIL${NC}: Docker group does not exist"
+ ((fail_count++))
+ return 1
+ fi
+}
+
+test_user_can_add_to_docker_group() {
+ local user="lab01_student"
+
+ # This test verifies the MECHANISM, not that it's done yet
+ if command -v usermod >/dev/null 2>&1; then
+ echo -e "${GREEN}PASS${NC}: usermod command available for group management"
+ ((pass_count++))
+ return 0
+ else
+ echo -e "${RED}FAIL${NC}: usermod command not available"
+ ((fail_count++))
+ return 1
+ fi
+}
+
+test_docker_accessible_by_group() {
+ # Check that docker group members can access the socket
+ local socket_group=$(stat -c "%G" /var/run/docker.sock 2>/dev/null || echo "unknown")
+
+ if [ "$socket_group" = "docker" ]; then
+ echo -e "${GREEN}PASS${NC}: Docker socket owned by docker group"
+ ((pass_count++))
+ return 0
+ else
+ echo -e "${YELLOW}WARN${NC}: Docker socket owned by $socket_group (expected docker)"
+ ((pass_count++))
+ return 0
+ fi
+}
+
+# Run all tests
+echo "Running Docker access control tests..."
+echo "======================================"
+test_socket_permissions
+test_docker_group_exists
+test_user_can_add_to_docker_group
+test_docker_accessible_by_group
+echo "======================================"
+echo "Tests passed: $pass_count"
+echo "Tests failed: $fail_count"
+
+if [ $fail_count -gt 0 ]; then
+ exit 1
+fi
+exit 0
+```
+
+Key implementation points:
+- Verify socket ownership and permissions
+- Check docker group exists
+- Validate group management commands available
+- Test mechanism for adding users to docker group
+
+
+ chmod +x labs/lab-01-iam/tests/test-02-docker-access.sh && bash labs/lab-01-iam/tests/test-02-docker-access.sh
+
+ Script validates Docker socket access control mechanisms
+
+
+
+ Task 3: Create non-root container verification script (INF-01)
+ labs/lab-01-iam/tests/03-non-root-test.sh
+
+ - Test 1: Container configured with USER directive runs as non-root
+ - Test 2: docker exec whoami returns non-root user
+ - Test 3: docker inspect shows User field set
+ - Test 4: docker top shows non-root UID (not 0)
+
+
+Create test script for non-root container verification (INF-01 requirement):
+
+```bash
+#!/bin/bash
+# Test: Non-root container execution (INF-01 requirement)
+# Phase: RED - This test will fail initially (no containers exist)
+
+set -euo pipefail
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+NC='\033[0m'
+
+pass_count=0
+fail_count=0
+
+# Container name to test
+CONTAINER_NAME="lab01-test-container"
+
+test_non_root_dockerfile_exists() {
+ local dockerfile="labs/lab-01-iam/Dockerfile.test"
+
+ if [ -f "$dockerfile" ]; then
+ echo -e "${GREEN}PASS${NC}: Test Dockerfile exists"
+ ((pass_count++))
+ return 0
+ else
+ echo -e "${YELLOW}SKIP${NC}: Test Dockerfile not created yet (expected in RED phase)"
+ ((pass_count++))
+ return 0
+ fi
+}
+
+test_container_runs_as_non_root() {
+ # Check if container exists
+ if ! docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
+ echo -e "${YELLOW}SKIP${NC}: Container ${CONTAINER_NAME} does not exist yet (expected in RED phase)"
+ ((pass_count++))
+ return 0
+ fi
+
+ # Check if container is running
+ if ! docker ps --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
+ echo -e "${YELLOW}SKIP${NC}: Container ${CONTAINER_NAME} not running"
+ ((pass_count++))
+ return 0
+ fi
+
+ # Method 1: docker exec whoami
+ local actual_user=$(docker exec "${CONTAINER_NAME}" whoami 2>/dev/null || echo "unknown")
+
+ if [ "$actual_user" = "root" ]; then
+ echo -e "${RED}FAIL${NC}: Container running as root (whoami)"
+ ((fail_count++))
+ return 1
+ elif [ "$actual_user" = "unknown" ]; then
+ echo -e "${YELLOW}SKIP${NC}: Cannot determine user (container not running or no exec)"
+ ((pass_count++))
+ return 0
+ else
+ echo -e "${GREEN}PASS${NC}: Container running as non-root user: $actual_user"
+ ((pass_count++))
+ return 0
+ fi
+}
+
+test_container_user_configured() {
+ if ! docker ps -a --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$"; then
+ echo -e "${YELLOW}SKIP${NC}: Container not created yet"
+ ((pass_count++))
+ return 0
+ fi
+
+ # Method 2: docker inspect for User field
+ local user_config=$(docker inspect --format='{{.Config.User}}' "${CONTAINER_NAME}" 2>/dev/null || echo "")
+
+ if [ -z "$user_config" ]; then
+ # Check compose file for user directive (may override Dockerfile)
+ if [ -f "labs/lab-01-iam/docker-compose.yml" ]; then
+ if grep -q "user:" labs/lab-01-iam/docker-compose.yml; then
+ echo -e "${GREEN}PASS${NC}: User directive found in docker-compose.yml"
+ ((pass_count++))
+ return 0
+ fi
+ fi
+
+ echo -e "${YELLOW}WARN${NC}: No User directive found in Dockerfile or compose"
+ ((pass_count++))
+ return 0
+ else
+ echo -e "${GREEN}PASS${NC}: User configured in container: $user_config"
+ ((pass_count++))
+ return 0
+ fi
+}
+
+test_no_container_runs_as_root() {
+ # INF-01 requirement: NO container should run as root
+ local compose_file="labs/lab-01-iam/docker-compose.yml"
+
+ if [ ! -f "$compose_file" ]; then
+ echo -e "${YELLOW}SKIP${NC}: docker-compose.yml not created yet"
+ ((pass_count++))
+ return 0
+ fi
+
+ # Get all services from compose file
+ local services=$(docker-compose -f "$compose_file" ps --services 2>/dev/null || echo "")
+
+ if [ -z "$services" ]; then
+ echo -e "${YELLOW}SKIP${NC}: No services defined yet"
+ ((pass_count++))
+ return 0
+ fi
+
+ local root_containers=0
+ while IFS= read -r service; do
+ if [ -n "$service" ]; then
+ local container_name=$(docker-compose -f "$compose_file" ps -q "$service" 2>/dev/null || echo "")
+ if [ -n "$container_name" ]; then
+ local user=$(docker exec "$container_name" whoami 2>/dev/null || echo "unknown")
+ if [ "$user" = "root" ]; then
+ echo -e "${RED}FAIL${NC}: Service $service running as root"
+ ((root_containers++))
+ fi
+ fi
+ fi
+ done <<< "$services"
+
+ if [ $root_containers -gt 0 ]; then
+ echo -e "${RED}FAIL${NC}: $root_containers container(s) running as root (INF-01 violation)"
+ ((fail_count++))
+ return 1
+ else
+ echo -e "${GREEN}PASS${NC}: No containers running as root (INF-01 satisfied)"
+ ((pass_count++))
+ return 0
+ fi
+}
+
+# Run all tests
+echo "Running non-root container tests (INF-01)..."
+echo "============================================"
+test_non_root_dockerfile_exists
+test_container_runs_as_non_root
+test_container_user_configured
+test_no_container_runs_as_root
+echo "============================================"
+echo "Tests passed: $pass_count"
+echo "Tests failed: $fail_count"
+
+if [ $fail_count -gt 0 ]; then
+ exit 1
+fi
+exit 0
+```
+
+Key implementation points:
+- INF-01 requirement: NO container runs as root
+- Multiple verification methods (whoami, inspect, compose check)
+- Handle not-yet-created infrastructure gracefully (skip with warning)
+- Check all services in docker-compose.yml for compliance
+
+
+ chmod +x labs/lab-01-iam/tests/03-non-root-test.sh && bash labs/lab-01-iam/tests/03-non-root-test.sh
+
+ Script verifies INF-01: no container runs as root
+
+
+
+ Task 4: Create final verification script (double-check for students)
+ labs/lab-01-iam/tests/99-final-verification.sh
+
+ - Test 1: All previous tests can be run
+ - Test 2: Student can verify their work end-to-end
+ - Test 3: Clear PASS/FAIL report for all requirements
+ - Test 4: Exit code indicates overall success/failure
+
+
+Create final verification script for student self-check:
+
+```bash
+#!/bin/bash
+# Final Verification: Lab 01 - IAM & Sicurezza
+# This is the "double check" command students run to verify their work
+# Usage: bash tests/99-final-verification.sh
+
+set -euo pipefail
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m'
+
+echo -e "${BLUE}========================================${NC}"
+echo -e "${BLUE}Lab 01 - IAM & Sicurezza${NC}"
+echo -e "${BLUE}Final Verification (Double Check)${NC}"
+echo -e "${BLUE}========================================${NC}"
+echo ""
+
+# Track overall results
+all_passed=true
+
+# Test 1: User and group configuration
+echo -e "${BLUE}[1/5] Checking user and group configuration...${NC}"
+if id lab01_student &>/dev/null; then
+ echo -e " ${GREEN}✓${NC} User lab01_student exists"
+ if groups lab01_student 2>/dev/null | grep -q docker; then
+ echo -e " ${GREEN}✓${NC} User lab01_student is in docker group"
+ else
+ echo -e " ${RED}✗${NC} User lab01_student is NOT in docker group"
+ all_passed=false
+ fi
+else
+ echo -e " ${YELLOW}○${NC} User lab01_student does not exist (not created yet)"
+ all_passed=false
+fi
+echo ""
+
+# Test 2: Docker access control
+echo -e "${BLUE}[2/5] Checking Docker access control...${NC}"
+if sudo -u lab01_student docker ps &>/dev/null; then
+ echo -e " ${GREEN}✓${NC} lab01_student can access Docker socket"
+else
+ echo -e " ${RED}✗${NC} lab01_student cannot access Docker socket"
+ echo -e " ${YELLOW} Hint: User may need to re-login for group membership to take effect${NC}"
+ all_passed=false
+fi
+echo ""
+
+# Test 3: Non-root container execution (INF-01)
+echo -e "${BLUE}[3/5] Checking non-root container execution (INF-01)...${NC}"
+compose_file="labs/lab-01-iam/docker-compose.yml"
+if [ ! -f "$compose_file" ]; then
+ echo -e " ${YELLOW}○${NC} docker-compose.yml not found"
+ all_passed=false
+else
+ echo -e " ${GREEN}✓${NC} docker-compose.yml exists"
+
+ # Check for user directive in services
+ if grep -A 10 "services:" "$compose_file" | grep -q "user:"; then
+ echo -e " ${GREEN}✓${NC} Services configured with non-root user directive"
+ else
+ echo -e " ${RED}✗${NC} No user directive found in docker-compose.yml"
+ all_passed=false
+ fi
+
+ # If containers are running, verify they're not root
+ if docker-compose -f "$compose_file" ps --services 2>/dev/null | grep -q .; then
+ local root_count=0
+ while IFS= read -r service; do
+ [ -z "$service" ] && continue
+ local container=$(docker-compose -f "$compose_file" ps -q "$service" 2>/dev/null || echo "")
+ if [ -n "$container" ]; then
+ local user=$(docker exec "$container" whoami 2>/dev/null || echo "unknown")
+ if [ "$user" = "root" ]; then
+ echo -e " ${RED}✗${NC} Service $service running as ROOT (INF-01 violation)"
+ ((root_count++))
+ fi
+ fi
+ done <<< "$(docker-compose -f "$compose_file" ps --services 2>/dev/null)"
+
+ if [ $root_count -eq 0 ]; then
+ echo -e " ${GREEN}✓${NC} All running containers are non-root"
+ else
+ all_passed=false
+ fi
+ else
+ echo -e " ${YELLOW}○${NC} No containers running (start with docker-compose up)"
+ fi
+fi
+echo ""
+
+# Test 4: Documentation completeness (Diátaxis)
+echo -e "${BLUE}[4/5] Checking documentation (Diátaxis framework)...${NC}"
+doc_count=0
+for doc_type in "tutorial" "how-to-guides" "reference" "explanation"; do
+ if [ -d "labs/lab-01-iam/$doc_type" ]; then
+ local md_files=$(find "labs/lab-01-iam/$doc_type" -name "*.md" 2>/dev/null | wc -l)
+ if [ "$md_files" -gt 0 ]; then
+ echo -e " ${GREEN}✓${NC} $doc_type: $md_files document(s)"
+ ((doc_count++))
+ else
+ echo -e " ${YELLOW}○${NC} $doc_type: directory exists but empty"
+ fi
+ else
+ echo -e " ${RED}✗${NC} $doc_type: missing"
+ fi
+done
+
+if [ $doc_count -eq 4 ]; then
+ echo -e " ${GREEN}✓${NC} All 4 Diátaxis document types present"
+else
+ echo -e " ${YELLOW}○${NC} $doc_count/4 Diátaxis document types present"
+ all_passed=false
+fi
+echo ""
+
+# Test 5: IAM parallels documentation
+echo -e "${BLUE}[5/5] Checking IAM parallels explanation...${NC}"
+explanation_file="labs/lab-01-iam/explanation/docker-iam-parallels.md"
+if [ -f "$explanation_file" ]; then
+ if grep -qi "IAM.*Linux\|Linux.*IAM" "$explanation_file"; then
+ echo -e " ${GREEN}✓${NC} IAM parallels documented"
+ else
+ echo -e " ${YELLOW}○${NC} Explanation exists but IAM parallels unclear"
+ fi
+
+ if grep -qi "differenza\|difference" "$explanation_file"; then
+ echo -e " ${GREEN}✓${NC} Local vs cloud differences documented"
+ else
+ echo -e " ${YELLOW}○${NC} Local vs cloud differences not clearly documented"
+ fi
+else
+ echo -e " ${RED}✗${NC} IAM parallels explanation not found"
+ all_passed=false
+fi
+echo ""
+
+# Final summary
+echo -e "${BLUE}========================================${NC}"
+if [ "$all_passed" = true ]; then
+ echo -e "${GREEN}ALL CHECKS PASSED${NC}"
+ echo -e "${GREEN}Lab 01 is complete!${NC}"
+ echo -e "${BLUE}========================================${NC}"
+ exit 0
+else
+ echo -e "${RED}SOME CHECKS FAILED${NC}"
+ echo -e "${YELLOW}Review the output above and complete the missing items${NC}"
+ echo -e "${BLUE}========================================${NC}"
+ exit 1
+fi
+```
+
+Key implementation points:
+- Student-friendly double-check command
+- Clear visual indicators (✓ pass, ✗ fail, ○ skip)
+- Tests all phase requirements: LAB-01, INF-01, DOCT-01/02/03/04, PARA-01/03
+- Exit code 0 for all-pass, 1 for any failure
+- Helpful hints for common issues (re-login for group membership)
+
+
+ chmod +x labs/lab-01-iam/tests/99-final-verification.sh && bash labs/lab-01-iam/tests/99-final-verification.sh
+
+ Student can run single command to verify all lab requirements are met
+
+
+
+ Task 5: Create test orchestration script
+ labs/lab-01-iam/tests/run-all-tests.sh
+
+ - Test 1: Script executes all test files in sequence
+ - Test 2: Script stops on first failure (fail-fast)
+ - Test 3: Script aggregates results and provides summary
+ - Test 4: Script can be run from project root
+
+
+Create test orchestration script:
+
+```bash
+#!/bin/bash
+# Test Suite Runner: Lab 01 - IAM & Sicurezza
+# Runs all tests in sequence and provides summary
+# Usage: bash labs/lab-01-iam/tests/run-all-tests.sh
+
+set -euo pipefail
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+BLUE='\033[0;34m'
+NC='\033[0m'
+
+TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(cd "$TEST_DIR/../.." && pwd)"
+
+cd "$PROJECT_ROOT"
+
+echo -e "${BLUE}========================================${NC}"
+echo -e "${BLUE}Lab 01 Test Suite${NC}"
+echo -e "${BLUE}========================================${NC}"
+echo ""
+
+# Array of test files in order
+declare -a tests=(
+ "$TEST_DIR/test-01-user-creation.sh"
+ "$TEST_DIR/test-02-docker-access.sh"
+ "$TEST_DIR/03-non-root-test.sh"
+)
+
+total_tests=${#tests[@]}
+passed_tests=0
+failed_tests=0
+
+for i in "${!tests[@]}"; do
+ test_num=$((i + 1))
+ test_file="${tests[$i]}"
+ test_name=$(basename "$test_file")
+
+ echo -e "${BLUE}[$test_num/$total_tests] Running $test_name...${NC}"
+
+ if bash "$test_file"; then
+ echo -e "${GREEN}✓ PASSED${NC}"
+ echo ""
+ ((passed_tests++))
+ else
+ echo -e "${RED}✗ FAILED${NC}"
+ echo ""
+ ((failed_tests++))
+ # Fail-fast: stop on first failure
+ break
+ fi
+done
+
+# Summary
+echo -e "${BLUE}========================================${NC}"
+echo -e "${BLUE}Test Suite Summary${NC}"
+echo -e "${BLUE}========================================${NC}"
+echo "Passed: $passed_tests/$total_tests"
+echo "Failed: $failed_tests/$total_tests"
+echo ""
+
+if [ $failed_tests -eq 0 ]; then
+ echo -e "${GREEN}All tests passed!${NC}"
+ echo ""
+ echo "Run final verification:"
+ echo " bash labs/lab-01-iam/tests/99-final-verification.sh"
+ echo -e "${BLUE}========================================${NC}"
+ exit 0
+else
+ echo -e "${RED}Some tests failed${NC}"
+ echo -e "${BLUE}========================================${NC}"
+ exit 1
+fi
+```
+
+Key implementation points:
+- Fail-fast approach (stops on first failure for TDD RED phase)
+- Executes tests in dependency order
+- Provides summary and next steps
+- Can be run from any directory (uses absolute paths)
+
+
+ chmod +x labs/lab-01-iam/tests/run-all-tests.sh && bash labs/lab-01-iam/tests/run-all-tests.sh
+
+ Orchestration script runs all tests and provides summary
+
+
+
+
+
+1. All test scripts are executable (chmod +x)
+2. Test scripts can run individually and return proper exit codes
+3. Test orchestration script executes all tests in sequence
+4. Test scripts follow TDD RED phase (will fail before implementation exists)
+5. All tests handle missing infrastructure gracefully (skip with warning)
+
+
+
+1. Test infrastructure is in place before any implementation (Wave 0 complete)
+2. All requirement IDs (TEST-01, TEST-05, INF-01) have test coverage
+3. Tests follow bash scripting best practices (set -euo pipefail, proper exit codes)
+4. Student can run individual tests or full suite
+5. Final verification script provides clear pass/fail report for all lab requirements
+
+
+
diff --git a/.planning/phases/02-lab-01-iam-sicurezza/02-02-PLAN.md b/.planning/phases/02-lab-01-iam-sicurezza/02-02-PLAN.md
new file mode 100644
index 0000000..369b11f
--- /dev/null
+++ b/.planning/phases/02-lab-01-iam-sicurezza/02-02-PLAN.md
@@ -0,0 +1,1843 @@
+---
+phase: 02-lab-01-iam-sicurezza
+plan: 02
+type: execute
+wave: 1
+depends_on: [02-01]
+files_modified:
+ - labs/lab-01-iam/tutorial/01-create-linux-users.md
+ - labs/lab-01-iam/tutorial/02-docker-group-permissions.md
+ - labs/lab-01-iam/tutorial/03-verify-iam-setup.md
+ - labs/lab-01-iam/how-to-guides/add-user-to-docker-group.md
+ - labs/lab-01-iam/how-to-guides/verify-non-root-container.md
+ - labs/lab-01-iam/how-to-guides/reset-docker-permissions.md
+ - labs/lab-01-iam/reference/docker-socket-permissions.md
+ - labs/lab-01-iam/reference/linux-users-groups.md
+ - labs/lab-01-iam/reference/iam-parallels.md
+ - labs/lab-01-iam/explanation/docker-iam-parallels.md
+autonomous: true
+requirements: [LAB-01, DOCT-01, DOCT-02, DOCT-03, DOCT-04, DOCT-05, PARA-01, PARA-03, PARA-04]
+user_setup: []
+must_haves:
+ truths:
+ - "Student can follow step-by-step tutorial to create Linux users with Docker permissions"
+ - "Tutorial follows 'little often' principle with small incremental steps"
+ - "How-to guides exist for common procedures independent of tutorial flow"
+ - "Reference documents provide technical specifications without explanation"
+ - "Explanation document draws clear parallels between Docker permissions and AWS IAM"
+ artifacts:
+ - path: "labs/lab-01-iam/tutorial/01-create-linux-users.md"
+ provides: "Step-by-step user creation guide"
+ min_lines: 60
+ - path: "labs/lab-01-iam/tutorial/02-docker-group-permissions.md"
+ provides: "Docker group permissions tutorial"
+ min_lines: 60
+ - path: "labs/lab-01-iam/tutorial/03-verify-iam-setup.md"
+ provides: "Verification and testing tutorial"
+ min_lines: 40
+ - path: "labs/lab-01-iam/how-to-guides/add-user-to-docker-group.md"
+ provides: "Procedure for adding user to docker group"
+ min_lines: 30
+ - path: "labs/lab-01-iam/how-to-guides/verify-non-root-container.md"
+ provides: "Non-root container verification procedure"
+ min_lines: 25
+ - path: "labs/lab-01-iam/how-to-guides/reset-docker-permissions.md"
+ provides: "Permission reset procedure"
+ min_lines: 30
+ - path: "labs/lab-01-iam/reference/docker-socket-permissions.md"
+ provides: "Docker socket technical specifications"
+ min_lines: 40
+ - path: "labs/lab-01-iam/reference/linux-users-groups.md"
+ provides: "Linux user management reference"
+ min_lines: 40
+ - path: "labs/lab-01-iam/reference/iam-parallels.md"
+ provides: "IAM parallelism quick reference"
+ min_lines: 30
+ - path: "labs/lab-01-iam/explanation/docker-iam-parallels.md"
+ provides: "Conceptual mapping between Docker and IAM"
+ min_lines: 80
+ key_links:
+ - from: "tutorial/*.md"
+ to: "how-to-guides/*.md, reference/*.md"
+ via: "Cross-references for deeper dives"
+ pattern: "\\[.*\\]\\(\\../how-to-guides/.*\\)"
+ - from: "explanation/docker-iam-parallels.md"
+ to: "reference/iam-parallels.md"
+ via: "Quick reference table for concepts"
+ pattern: "See \\[.*\\]\\(\\../reference/iam-parallels.md\\)"
+---
+
+
+Create complete Diátaxis documentation (Tutorial, How-to Guides, Reference, Explanation) for Lab 01 - IAM & Sicurezza. Students learn Linux user management and Docker permissions through step-by-step tutorials, with supporting documentation for procedures and technical specs.
+
+Purpose: Teach IAM concepts through local Linux user management and Docker socket permissions, drawing direct parallels to AWS IAM.
+Output: 10 documentation files covering all 4 Diátaxis quadrants.
+
+
+
+@/home/luca/.claude/get-shit-done/workflows/execute-plan.md
+@/home/luca/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/02-lab-01-iam-sicurezza/02-RESEARCH.md
+@.planning/phases/02-lab-01-iam-sicurezza/02-VALIDATION.md
+@CLAUDE.md
+
+# Diátaxis Framework from CLAUDE.md
+
+## 2.1 Output Didattico a 4 Quadranti
+1. **Tutorials:** Guida passo-passo incrementale (*little often*) per guidare l'allievo.
+2. **How-to Guides:** Procedure specifiche (es. "Come generare chiavi SSH", "Come ripulire i volumi Docker").
+3. **Reference:** Specifiche tecniche nude e crude (mappe IP, tabelle porte esposte, spiegazione direttive `docker-compose`).
+4. **Explanation:** Il raccordo concettuale (parallelismo tra l'ambiente locale simulato e i veri servizi Cloud managed).
+
+## IAM Parallels from RESEARCH.md
+
+| 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 |
+
+## Common Pitfalls from RESEARCH.md
+- Group membership requires re-login (use `newgrp docker` OR `su - user`)
+- Testing as wrong user (root bypasses permissions)
+- Socket permissions may change after Docker daemon restart
+
+## Tone Guidelines
+- Direct, simple language (Italian)
+- No emojis
+- Technically accurate
+- Step-by-step with verification at each step
+
+
+
+
+
+ Task 1: Create Tutorial - Part 1: Linux Users
+ labs/lab-01-iam/tutorial/01-create-linux-users.md
+
+Create tutorial following Diátaxis framework - step-by-step, incremental, with verification:
+
+```markdown
+# Tutorial: Creare Utenti Linux per il Lab IAM
+
+In questo tutorial creerai utenti Linux con permessi limitati per simulare utenti IAM in un ambiente cloud. Imparerai a creare utenti, verificare i permessi e gestire l'appartenenza ai gruppi.
+
+## Obiettivo
+Creare un utente Linux `lab01_student` che non ha accesso iniziale a Docker, simulando un utente cloud senza permessi.
+
+## Prerequisiti
+- Accesso a un terminale Linux con privilegi sudo
+- Docker Engine installato e in esecuzione
+- Comandi base: `useradd`, `groups`, `id`
+
+---
+
+## Passo 1: Verifica l'ambiente
+
+Prima di creare utenti, verifichiamo che l'ambiente sia pronto.
+
+Esegui:
+```bash
+# Verifica che Docker sia in esecuzione
+sudo systemctl status docker
+
+# Verifica che il gruppo docker esista
+getent group docker
+```
+
+Atteso:
+- Docker deve essere "active (running)"
+- Il gruppo docker deve essere mostrato
+
+Se qualcosa non funziona, consulta [Troubleshooting](#troubleshooting).
+
+---
+
+## Passo 2: Crea un nuovo utente Linux
+
+Creiamo un utente che simulerà un utente cloud senza permessi IAM.
+
+Esegui:
+```bash
+# Crea l'utente lab01_student
+sudo useradd -m -s /bin/bash lab01_student
+
+# Verifica che l'utente sia stato creato
+id lab01_student
+```
+
+Atteso:
+```
+uid=1001(lab01_student) gid=1001(lab01_student) gruppi=1001(lab01_student)
+```
+
+Spiegazione:
+- `-m` crea la home directory
+- `-s /bin/bash` imposta la shell di default
+- L'utente ha solo il proprio gruppo iniziale
+
+---
+
+## Passo 3: Verifica i gruppi dell'utente
+
+Controlliamo a quali gruppi appartiene l'utente.
+
+Esegui:
+```bash
+groups lab01_student
+```
+
+Atteso:
+```
+lab01_student : lab01_student
+```
+
+Nota: L'utente NON è nel gruppo `docker`. Questo è corretto simuliamo un utente senza permessi.
+
+---
+
+## Passo 4: Verifica che l'utente NON può accedere a Docker
+
+Prova a eseguire un comando Docker come l'utente `lab01_student`.
+
+Esegui:
+```bash
+# Esegui docker ps come lab01_student
+sudo -u lab01_student docker ps
+```
+
+Atteso:
+```
+permission denied while trying to connect to the Docker daemon socket
+```
+
+Questo è il comportamento corretto! L'utente non ha ancora permessi Docker.
+
+---
+
+## Passo 5: Imposta una password per l'utente (opzionale)
+
+Se vuoi poter fare login come questo utente:
+
+Esegui:
+```bash
+sudo passwd lab01_student
+```
+
+Inserisci una password quando richiesto.
+
+---
+
+## Verifica
+
+Hai completato questo tutorial quando:
+- [ ] L'utente `lab01_student` esiste
+- [ ] L'utente NON è nel gruppo docker
+- [ ] L'utente NON può eseguire comandi docker
+- [ ] Il comando `groups lab01_student` mostra solo il proprio gruppo
+
+## Prossimo Passo
+
+Nel [prossimo tutorial](./02-docker-group-permissions.md) imparerai a dare permessi Docker all'utente tramite i gruppi.
+
+---
+
+## Troubleshooting
+
+**Problema: `useradd: user 'lab01_student' already exists`**
+
+Soluzione:
+```bash
+# Elimina l'utente esistente e ricrealo
+sudo userdel -r lab01_student
+sudo useradd -m -s /bin/bash lab01_student
+```
+
+**Problema: Docker non è in esecuzione**
+
+Soluzione:
+```bash
+sudo systemctl start docker
+sudo systemctl enable docker
+```
+
+**Problema: Il gruppo docker non esiste**
+
+Soluzione:
+```bash
+sudo groupadd docker
+```
+```
+
+Key points:
+- Step-by-step with verification after each step
+- "Little often" - small steps, frequent verification
+- Clear expected output
+- Troubleshooting section
+- Links to next tutorial
+
+
+ test -f labs/lab-01-iam/tutorial/01-create-linux-users.md && grep -q "Passo 1\|Passo 2\|Passo 3" labs/lab-01-iam/tutorial/01-create-linux-users.md && wc -l labs/lab-01-iam/tutorial/01-create-linux-users.md | awk '{if($1>=60) print "PASS"; else print "FAIL: Tutorial too short ("$1" lines, expected 60+)"}'
+
+ Tutorial Part 1 created with step-by-step user creation guide
+
+
+
+ Task 2: Create Tutorial - Part 2: Docker Group Permissions
+ labs/lab-01-iam/tutorial/02-docker-group-permissions.md
+
+Create second tutorial covering Docker group permissions:
+
+```markdown
+# Tutorial: Permessi Docker tramite Gruppi Linux
+
+In questo tutorial imparerai come dare permessi Docker a un utente tramite l'appartenenza al gruppo `docker`. Questo simula l'assegnazione di policy IAM a un utente cloud.
+
+## Obiettivo
+Aggiungere l'utente `lab01_student` al gruppo `docker`, permettendo l'accesso al socket Docker.
+
+## Prerequisiti
+- Completato [Tutorial 1: Creare Utenti Linux](./01-create-linux-users.md)
+- L'utente `lab01_student` esiste e NON è nel gruppo docker
+
+---
+
+## Passo 1: Verifica lo stato corrente
+
+Prima di modificare i permessi, verifichiamo lo stato attuale.
+
+Esegui:
+```bash
+# Verifica i gruppi dell'utente
+groups lab01_student
+
+# Verifica i permessi del socket Docker
+ls -l /var/run/docker.sock
+```
+
+Atteso:
+- `groups` mostra solo `lab01_student` (NON docker)
+- Il socket Docker ha permessi `srw-rw----` ed è di proprietà `root:docker`
+
+Spiegazione: Il socket Docker (`/var/run/docker.sock`) è accessibile solo a `root` e ai membri del gruppo `docker`.
+
+---
+
+## Passo 2: Aggiungi l'utente al gruppo docker
+
+Ora aggiungiamo l'utente al gruppo per dargli accesso Docker.
+
+Esegui:
+```bash
+# Aggiungi lab01_student al gruppo docker
+sudo usermod -aG docker lab01_student
+
+# Verifica l'appartenenza al gruppo
+groups lab01_student
+```
+
+Atteso:
+```
+lab01_student : lab01_student docker
+```
+
+Nota: Il gruppo `docker` ora appare nell'elenco!
+
+Spiegazione:
+- `-aG` significa "append" (aggiunge senza rimuovere altri gruppi) e "group" (modifica i gruppi)
+- Questo è equivalente ad assegnare una policy IAM a un utente cloud
+
+---
+
+## Passo 3: Importante - Login necessario
+
+I gruppi vengono valutati al momento del login. La sessione corrente dell'utente non vedrà ancora il nuovo gruppo.
+
+Per verificare il gruppo membership (senza dover fare login):
+```bash
+# Questo mostra i gruppi anche se non sono ancora attivi nella sessione
+groups lab01_student
+```
+
+Per rendere attivi i nuovi gruppi, l'utente deve fare una di queste operazioni:
+1. Fare logout e login
+2. Eseguire `newgrp docker`
+3. Eseguire `su - lab01_student`
+
+---
+
+## Passo 4: Verifica l'accesso Docker
+
+Ora verifichiamo che l'utente può accedere a Docker.
+
+Esegui:
+```bash
+# Metodo 1: Usa newgrp per attivare il gruppo nella sessione corrente
+sudo -u lab01_student -i docker ps
+```
+
+Atteso:
+```
+CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
+```
+
+Il comando funziona! L'utente ora ha accesso Docker.
+
+---
+
+## Passo 5: Verifica con un container di test
+
+Facciamo partire un container semplice per confermare che tutto funziona.
+
+Esegui:
+```bash
+# Esegui un container Alpine come lab01_student
+sudo -u lab01_student -i docker run --rm alpine:3.19 whoami
+```
+
+Atteso:
+```
+root
+```
+
+Nota: Il container mostra "root" perché questo è l'utente di default DENTRO il container (non è l'utente che ha lanciato il comando). Nel [Tutorial 3](./03-verify-iam-setup.md) imparerai a far girare i container come utente non-root.
+
+---
+
+## Parallelismo con AWS IAM
+
+| Operazione Locale | AWS IAM Equivalente |
+|-------------------|---------------------|
+| `usermod -aG docker user` | `AttachUserPolicy` o `AddUserToGroup` |
+| Utente nel gruppo `docker` | Utente IAM con policy permessive |
+| Accesso al socket Docker | Accesso alle API AWS |
+
+---
+
+## Verifica
+
+Hai completato questo tutorial quando:
+- [ ] L'utente `lab01_student` è nel gruppo docker
+- [ ] L'utente può eseguire `docker ps`
+- [ ] L'utente può fare partire container
+- [ ] Capisci il parallelismo con IAM User + Policy
+
+## Prossimo Passo
+
+Nel [prossimo tutorial](./03-verify-iam-setup.md) imparerai a verificare l'intera configurazione e a far girare container non-root.
+
+---
+
+## Troubleshooting
+
+**Problema: L'utente non può ancora eseguire docker ps**
+
+Soluzione 1: Verifica di aver usato `sudo -u lab01_student -i`
+```bash
+# Il flag -i è importante per caricare l'ambiente corretto
+sudo -u lab01_student -i docker ps
+```
+
+Soluzione 2: Verifica che l'utente sia nel gruppo
+```bash
+groups lab01_student
+# Se non vedi "docker", ripeti il Passo 2
+```
+
+**Problema: Il socket Docker ha permessi errati**
+
+Soluzione:
+```bash
+# Correggi i permessi del socket
+sudo chmod 660 /var/run/docker.sock
+sudo chown root:docker /var/run/docker.sock
+```
+
+**Problema: `usermod: user 'lab01_student' does not exist`**
+
+Soluzione: Prima crea l'utente seguendo il [Tutorial 1](./01-create-linux-users.md).
+```
+
+Key points:
+- Explain the group membership evaluation timing issue
+- Show parallelism with AWS IAM
+- Multiple troubleshooting scenarios
+- Clear verification steps
+
+
+ test -f labs/lab-01-iam/tutorial/02-docker-group-permissions.md && grep -q "IAM\|AWS\|Parallelismo" labs/lab-01-iam/tutorial/02-docker-group-permissions.md && wc -l labs/lab-01-iam/tutorial/02-docker-group-permissions.md | awk '{if($1>=60) print "PASS"; else print "FAIL: Tutorial too short ("$1" lines, expected 60+)"}'
+
+ Tutorial Part 2 created with Docker group permissions guide
+
+
+
+ Task 3: Create Tutorial - Part 3: Verification and Non-Root Containers
+ labs/lab-01-iam/tutorial/03-verify-iam-setup.md
+
+Create third tutorial covering verification and non-root containers:
+
+```markdown
+# Tutorial: Verifica Configurazione IAM e Container Non-Root
+
+In questo tutorial verificherai l'intera configurazione IAM e imparerai a far girare container come utente non-root, seguendo il principio del minimo privilegio.
+
+## Obiettivo
+Verificare che la configurazione IAM funzioni e far girare container come utente non-root (INF-01).
+
+## Prerequisiti
+- Completati [Tutorial 1](./01-create-linux-users.md) e [Tutorial 2](./02-docker-group-permissions.md)
+- L'utente `lab01_student` esiste ed è nel gruppo docker
+
+---
+
+## Passo 1: Esegui lo script di verifica
+
+Il lab include uno script automatizzato per verificare tutto.
+
+Esegui:
+```bash
+bash labs/lab-01-iam/tests/99-final-verification.sh
+```
+
+Questo comando controllerà:
+1. Configurazione utenti e gruppi
+2. Accesso Docker
+3. Esecuzione container non-root
+4. Documentazione completa
+5. Parallelismi IAM
+
+Se tutti i check sono verdi, sei pronto per procedere!
+
+---
+
+## Passo 2: Verifica manuale - Accesso Docker
+
+Verifichiamo manualmente che l'utente possa accedere a Docker.
+
+Esegui:
+```bash
+# Verifica che docker ps funzioni
+sudo -u lab01_student -i docker ps
+
+# Verifica informazioni sul sistema Docker
+sudo -u lab01_student -i docker info
+```
+
+Entrambi i comandi dovrebbero funzionare senza errori.
+
+---
+
+## Passo 3: Crea un container NON-ROOT
+
+Ora creiamo un container che gira come utente non-root, seguendo il principio del minimo privilegio.
+
+Esegui:
+```bash
+cd labs/lab-01-iam
+
+# Crea un Dockerfile di test
+cat > Dockerfile.test << 'EOF'
+FROM alpine:3.19
+
+# Crea un utente non-root
+RUN addgroup -g 1000 appgroup && \
+ adduser -D -u 1000 -G appgroup appuser
+
+# Passa all'utente non-root
+USER appuser
+
+# Verifica che il container gira come appuser
+CMD ["sh", "-c", "whoami && sleep 3600"]
+EOF
+```
+
+Spiegazione:
+- Creiamo un utente `appuser` con UID 1000
+- Passiamo a questo utente con `USER`
+- Il container ora girerà come `appuser`, non come `root`
+
+---
+
+## Passo 4: Build e run del container
+
+Ora costruiamo e facciamo partire il container.
+
+Esegui:
+```bash
+# Costruisci l'immagine
+sudo -u lab01_student -i docker build -f Dockerfile.test -t test-non-root .
+
+# Fai partire il container
+sudo -u lab01_student -i docker run --name lab01-test-container -d test-non-root
+```
+
+Atteso:
+- Build completa senza errori
+- Container ID viene mostrato
+
+---
+
+## Passo 5: Verifica che il container NON gira come root
+
+Verifichiamo l'utente del container in tre modi.
+
+Esegui:
+```bash
+# Metodo 1: docker exec whoami
+docker exec lab01-test-container whoami
+```
+
+Atteso:
+```
+appuser
+```
+
+Esegui:
+```bash
+# Metodo 2: docker inspect
+docker inspect lab01-test-container --format='{{.Config.User}}'
+```
+
+Atteso:
+```
+appuser
+```
+
+Esegui:
+```bash
+# Metodo 3: docker top (mostra il processo sull'host)
+docker top lab01-test-container
+```
+
+Atteso:
+- La colonna USER mostra `1000` (non `0`)
+
+---
+
+## Passo 6: Verifica INF-01 - Nessun container root
+
+Il requisito INF-01 richiede che NESSUN container giri come root.
+
+Esegui:
+```bash
+bash labs/lab-01-iam/tests/03-non-root-test.sh
+```
+
+Questo script verificherà tutti i container e garantirà che nessuno giri come root.
+
+---
+
+## Passo 7: Pulisci il container di test
+
+Dopo aver verificato, puliamo il container di test.
+
+Esegui:
+```bash
+# Ferma e rimuovi il container
+docker stop lab01-test-container
+docker rm lab01-test-container
+
+# Rimuovi l'immagine
+docker rmi test-non-root
+```
+
+---
+
+## Principio del Minimo Privilegio
+
+Perché NON usare root nei container?
+
+| Rischio Root | Mitigazione Non-Root |
+|--------------|----------------------|
+| Container compromesso = host compromesso | Utente limitato = danno contenuto |
+| Container può leggere/scrivere qualsiasi file sull'host | Container può solo accedere ai suoi file |
+| Escalation privilegi possibile | Privilegi già limitati |
+
+Questo è lo stesso principio di IAM in cloud: dai solo i permessi minimi necessari.
+
+---
+
+## Verifica
+
+Hai completato questo tutorial quando:
+- [ ] Lo script di verifica passa senza errori
+- [ ] Il container di test gira come utente non-root
+- [ ] Tutti e tre i metodi di verifica mostrano lo stesso utente non-root
+- [ ] Capisci perché INF-01 è importante per la sicurezza
+
+---
+
+## Troubleshooting
+
+**Problema: `docker exec` mostra "root"**
+
+Soluzione: Verifica che il Dockerfile abbia la direttiva `USER`
+```bash
+# Verifica che USER sia nel Dockerfile
+grep USER Dockerfile.test
+# Dovrebbe mostrare: USER appuser
+```
+
+**Problema: `docker top` mostra UID 0**
+
+Soluzione: Il container potrebbe essere stato configurato con docker-compose. Verifica:
+```bash
+# Verifica la direttiva user in docker-compose
+grep -A 5 "user:" labs/lab-01-iam/docker-compose.yml
+```
+
+**Problema: Il test INF-01 fallisce**
+
+Soluzione: Assicurati che TUTTI i container abbiano la direttiva USER o user:
+```bash
+# Controlla tutti i container
+docker ps --format "{{.Names}}" | xargs -I {} sh -c 'echo "Container: {}" && docker inspect --format="{{.Config.User}}" {}'
+```
+```
+
+Key points:
+- Multiple verification methods for non-root execution
+- Clear explanation of security principle
+- Automated test integration
+- Comprehensive troubleshooting
+
+
+ test -f labs/lab-01-iam/tutorial/03-verify-iam-setup.md && grep -q "INF-01\|minimo privilegio\|non-root" labs/lab-01-iam/tutorial/03-verify-iam-setup.md && wc -l labs/lab-01-iam/tutorial/03-verify-iam-setup.md | awk '{if($1>=40) print "PASS"; else print "FAIL: Tutorial too short ("$1" lines, expected 40+)"}'
+
+ Tutorial Part 3 created with verification and non-root container guide
+
+
+
+ Task 4: Create How-to Guides
+ labs/lab-01-iam/how-to-guides/add-user-to-docker-group.md, labs/lab-01-iam/how-to-guides/verify-non-root-container.md, labs/lab-01-iam/how-to-guides/reset-docker-permissions.md
+
+Create three how-to guides for common procedures:
+
+**File 1: labs/lab-01-iam/how-to-guides/add-user-to-docker-group.md**
+```markdown
+# How-To: Aggiungere un Utente al Gruppo Docker
+
+Guida rapida per aggiungere un utente Linux al gruppo Docker e dargli accesso al socket.
+
+## Comando Rapido
+
+```bash
+# Aggiungi utente esistente al gruppo docker
+sudo usermod -aG docker nome_utente
+```
+
+## Verifica
+
+```bash
+# Verifica l'appartenenza al gruppo
+groups nome_utente
+
+# Verifica l'accesso docker
+sudo -u nome_utente -i docker ps
+```
+
+## Nota Importante
+
+I gruppi vengono valutati al login. Per attivare il nuovo gruppo immediatamente:
+
+```bash
+# Opzione 1: newgrp (attiva solo per questo comando)
+sudo -u nome_utente -i docker ps
+
+# Opzione 2: su - (nuova sessione login)
+su - nome_utente
+docker ps
+
+# Opzione 3: logout/login (sessione interattiva)
+```
+
+## Rimuovi Utente dal Gruppo Docker
+
+```bash
+# Rimuovi utente dal gruppo docker
+sudo gpasswd -d nome_utente docker
+
+# Oppure modifica i gruppi supplementari
+sudo usermod -G nome_utente nome_utente
+```
+
+## Vedi Anche
+
+- [Tutorial: Permessi Docker tramite Gruppi](../tutorial/02-docker-group-permissions.md)
+- [Reference: Permessi Socket Docker](../reference/docker-socket-permissions.md)
+```
+
+**File 2: labs/lab-01-iam/how-to-guides/verify-non-root-container.md**
+```markdown
+# How-To: Verificare che un Container Giri come Non-Root
+
+Guida rapida per verificare che un container non giri come utente root (requisito INF-01).
+
+## Metodo 1: docker exec whoami
+
+```bash
+docker exec whoami
+```
+
+Se mostra `root`, il container NON è conforme a INF-01.
+
+## Metodo 2: docker inspect
+
+```bash
+docker inspect --format='{{.Config.User}}'
+```
+
+- Se vuoto, il container gira come root (default)
+- Se mostra un UID/nome, il container gira come quell'utente
+
+## Metodo 3: docker top
+
+```bash
+docker top
+```
+
+Guarda la colonna USER:
+- `0` o `root` = NON conforme
+- Altri UID (es. `1000`) = CONFORME
+
+## Verifica Tutti i Container
+
+```bash
+# Verifica tutti i container in esecuzione
+docker ps --format "{{.Names}}" | while read container; do
+ echo "Container: $container"
+ docker exec $container whoami 2>/dev/null || echo "N/A"
+done
+```
+
+## Verifica con docker-compose
+
+```bash
+# Verifica tutti i servizi nel compose file
+docker-compose ps --services | while read service; do
+ container=$(docker-compose ps -q $service)
+ echo "Service: $service, User: $(docker exec $container whoami)"
+done
+```
+
+## Vedi Anche
+
+- [Tutorial: Container Non-Root](../tutorial/03-verify-iam-setup.md)
+- [Test: Script Non-Root](../tests/03-non-root-test.sh)
+```
+
+**File 3: labs/lab-01-iam/how-to-guides/reset-docker-permissions.md**
+```markdown
+# How-To: Reset dei Permessi Docker
+
+Guida per ripristinare i permessi del socket Docker e risolvere problemi di accesso.
+
+## Reset dei Permessi del Socket
+
+```bash
+# Ferma il demone Docker
+sudo systemctl stop docker
+
+# Ripristina la proprietà del socket
+sudo chown root:docker /var/run/docker.sock
+
+# Ripristina i permessi (660 = rw-rw----)
+sudo chmod 660 /var/run/docker.sock
+
+# Riavvia Docker
+sudo systemctl start docker
+```
+
+## Verifica
+
+```bash
+# Verifica i permessi del socket
+ls -l /var/run/docker.sock
+```
+
+Atteso: `srw-rw---- 1 root docker ...`
+
+## Ricrea il Gruppo Docker
+
+Se il gruppo docker è stato eliminato:
+
+```bash
+# Crea il gruppo docker
+sudo groupadd docker
+
+# Riavvia Docker per assicurarti che il socket appartenga al gruppo
+sudo systemctl restart docker
+```
+
+## Risoluzione Problemi Comuni
+
+### Problema: "Got permission denied while trying to connect"
+
+**Causa:** Utente non nel gruppo docker o permessi socket errati
+
+**Soluzione:**
+```bash
+# Verifica gruppi utente
+groups $USER
+
+# Aggiungi al gruppo se necessario
+sudo usermod -aG docker $USER
+
+# Verifica permessi socket
+ls -l /var/run/docker.sock
+
+# Correggi se necessario
+sudo chmod 660 /var/run/docker.sock
+sudo chown root:docker /var/run/docker.sock
+```
+
+### Problema: Socket non esiste
+
+**Causa:** Docker non è in esecuzione
+
+**Soluzione:**
+```bash
+# Avvia Docker
+sudo systemctl start docker
+
+# Verifica che il socket sia stato creato
+ls -l /var/run/docker.sock
+```
+
+### Problema: Group membership non attiva
+
+**Causa:** I gruppi vengono valutati al login
+
+**Soluzione:**
+```bash
+# Attiva il gruppo per la sessione corrente
+newgrp docker
+
+# Oppure fai login di nuovo
+su - $USER
+```
+
+## Reset Completo dell'Ambiente
+
+Per reset completo dell'ambiente Docker tra i lab:
+
+```bash
+# Usa lo script di reset
+bash scripts/reset-env.sh
+
+# Oppure reset manuale
+docker stop $(docker ps -aq)
+docker rm $(docker ps -aq)
+docker system prune -a
+```
+
+## Vedi Anche
+
+- [How-To: Ambiente Reset](../../how-to-guides/reset-docker-environment.md)
+- [Tutorial: Permessi Docker](../tutorial/02-docker-group-permissions.md)
+```
+
+Key points:
+- Procedure-focused, not step-by-step learning
+- Command-first structure
+- Links to tutorials and reference
+- Troubleshooting common issues
+
+
+ test -f labs/lab-01-iam/how-to-guides/add-user-to-docker-group.md && test -f labs/lab-01-iam/how-to-guides/verify-non-root-container.md && test -f labs/lab-01-iam/how-to-guides/reset-docker-permissions.md && grep -q "##" labs/lab-01-iam/how-to-guides/*.md | wc -l | awk '{if($1>=9) print "PASS"; else print "FAIL: How-to guides need more sections"}'
+
+ Three how-to guides created for common procedures
+
+
+
+ Task 5: Create Reference Documents
+ labs/lab-01-iam/reference/docker-socket-permissions.md, labs/lab-01-iam/reference/linux-users-groups.md, labs/lab-01-iam/reference/iam-parallels.md
+
+Create three reference documents with technical specifications:
+
+**File 1: labs/lab-01-iam/reference/docker-socket-permissions.md**
+```markdown
+# Reference: Permessi del Socket Docker
+
+Specifiche tecniche del socket Docker Unix domain socket e controllo accessi.
+
+## Percorso del Socket
+
+```
+/var/run/docker.sock
+```
+
+## Permessi Standard
+
+```
+srw-rw---- 1 root docker 0 Mar 24 20:00 /var/run/docker.sock
+```
+
+| Campo | Valore | Significato |
+|-------|--------|-------------|
+| Tipo | `s` | Socket Unix domain |
+| Permessi | `rw-rw----` (660) | Owner e gruppo possono leggere/scrivere |
+| Owner | `root` | Il demone Docker gira come root |
+| Gruppo | `docker` | Membri del gruppo docker possono accedere |
+| Altro | `---` | Nessun altro permesso |
+
+## Controllo Accessi
+
+L'accesso al socket è controllato dai permessi file system standard Linux:
+
+### Chi puo accedere?
+
+| Utente | Accesso | Motivo |
+|--------|---------|--------|
+| root | Si | Proprietario del socket |
+| Membri del gruppo docker | Si | Permesso gruppo (rw) |
+| Altri utenti | No | Nessun permesso |
+
+### Verifica Permessi
+
+```bash
+# Mostra permessi dettagliati
+stat -c "%a %U %G %n" /var/run/docker.sock
+# Output: 660 root docker /var/run/docker.sock
+
+# Verifica gruppo del socket
+stat -c "%G" /var/run/docker.sock
+# Output: docker
+
+# Verifica proprietario
+stat -c "%U" /var/run/docker.sock
+# Output: root
+```
+
+## Modifica Permessi
+
+```bash
+# Modifica permessi (non raccomandato: 666 permette accesso a tutti)
+sudo chmod 660 /var/run/docker.sock
+
+# Modifica gruppo
+sudo chown root:docker /var/run/docker.sock
+
+# Modifica proprietario (non raccomandato)
+sudo chown $USER /var/run/docker.sock
+```
+
+⚠️ **WARNING:** Non usare mai `chmod 666` o `777` sul socket Docker. Questo elimina tutti i controlli di accesso.
+
+## Docker Daemon e Socket
+
+### Allocazione Socket
+
+Il demone Docker crea il socket all'avvio:
+
+```bash
+# Avvia demone (crea/ricrea socket)
+sudo systemctl start docker
+
+# Riavvia per ripristinare permessi
+sudo systemctl restart docker
+```
+
+### Rootless Docker
+
+Con rootless Docker, il socket si trova in:
+
+```
+$XDG_RUNTIME_DIR/docker.sock
+# Tipicamente: /run/user/1000/docker.sock
+```
+
+## Troubleshooting
+
+| Problema | Diagnosi | Soluzione |
+|----------|----------|-----------|
+| Permission denied | Utente non in gruppo docker | `sudo usermod -aG docker $USER` |
+| Socket non trovato | Docker non in esecuzione | `sudo systemctl start docker` |
+| Permessi errati | chmod eseguito sul socket | `sudo systemctl restart docker` |
+| Gruppo errato | Chown sul socket | `sudo chown root:docker /var/run/docker.sock` |
+
+## Comandi Rapidi
+
+```bash
+# Verifica permessi attuali
+ls -l /var/run/docker.sock
+
+# Verifica chi puo accedere
+namei -l /var/run/docker.sock
+
+# Trova processi con handle al socket
+sudo lsof /var/run/docker.sock
+```
+
+## Vedi Anche
+
+- [Reference: Utenti e Gruppi Linux](./linux-users-groups.md)
+- [Explanation: Parallelismi IAM](../explanation/docker-iam-parallels.md)
+```
+
+**File 2: labs/lab-01-iam/reference/linux-users-groups.md**
+```markdown
+# Reference: Utenti e Gruppi Linux
+
+Specifiche tecniche per la gestione utenti e gruppi in Linux per il lab IAM.
+
+## Comandi Utente
+
+### useradd - Crea utente
+
+```bash
+sudo useradd -m -s /bin/bash nome_utente
+```
+
+| Flag | Significato |
+|------|-------------|
+| `-m` | Crea home directory |
+| `-s /bin/bash` | Imposta shell di login |
+| `-G group1,group2` | Aggiunge a gruppi supplementari |
+| `-u 1000` | Specifica UID |
+
+### usermod - Modifica utente
+
+```bash
+# Aggiungi a gruppo (append)
+sudo usermod -aG docker nome_utente
+
+# Modifica shell
+sudo usermod -s /bin/zsh nome_utente
+
+# Modifica gruppi supplementari (sovrascrive)
+sudo usermod -G docker,nome_utente nome_utente
+```
+
+⚠️ **IMPORTANTE:** Usa `-aG` (append) per aggiungere a un gruppo senza rimuovere gli altri.
+
+### userdel - Elimina utente
+
+```bash
+# Elimina utente (mantieni home)
+sudo userdel nome_utente
+
+# Elimina utente e home directory
+sudo userdel -r nome_utente
+```
+
+### passwd - Imposta password
+
+```bash
+# Imposta password per utente
+sudo passwd nome_utente
+
+# Cambia la tua password
+passwd
+```
+
+## Comandi Gruppo
+
+### groupadd - Crea gruppo
+
+```bash
+sudo groupadd docker
+```
+
+### groupmod - Modifica gruppo
+
+```bash
+# Rinomina gruppo
+sudo groupmod -n nuovo_nome vecchio_nome
+
+# Modifica GID
+sudo groupmod -g 1001 docker
+```
+
+### gpasswd - Gestisci membri gruppo
+
+```bash
+# Aggiungi utente al gruppo
+sudo gpasswd -a utente gruppo
+
+# Rimuovi utente dal gruppo
+sudo gpasswd -d utente gruppo
+
+# Imposta amministratori gruppo
+sudo gpasswd -A utente1,utente2 gruppo
+```
+
+### groupdel - Elimina gruppo
+
+```bash
+sudo groupdelete docker
+```
+
+## Comandi Informazione
+
+### id - Mostra info utente
+
+```bash
+# Mostra UID, GID e gruppi dell'utente corrente
+id
+
+# Mostra info di un utente specifico
+id nome_utente
+
+# Solo UID
+id -u nome_utente
+
+# Solo gruppi
+id -G nome_utente
+```
+
+Output esempio:
+```
+uid=1001(lab01_student) gid=1001(lab01_student) groups=1001(lab01_student),999(docker)
+```
+
+### groups - Mostra gruppi utente
+
+```bash
+# Gruppi dell'utente corrente
+groups
+
+# Gruppi di un utente specifico
+groups nome_utente
+```
+
+### getent - Query database di sistema
+
+```bash
+# Verifica che un gruppo esista
+getent group docker
+
+# Output: docker:x:999:utente1,utente2
+# nome:x:GID:lista_membri
+
+# Verifica che un utente esista
+getent passwd nome_utente
+
+# Output: nome_utente:x:1001:1001:,,,:/home/nome_utente:/bin/bash
+# nome:x:UID:GID:commento:home:shell
+```
+
+## File di Configurazione
+
+### /etc/passwd
+
+```bash
+# Visualizza tutti gli utenti
+cat /etc/passwd
+
+# Aggiungi utente manualmente (non raccomandato)
+echo "utente:x:1001:1001::/home/utente:/bin/bash" | sudo tee -a /etc/passwd
+```
+
+Formato:
+```
+username:x:UID:GID:commento:home:shell
+```
+
+### /etc/group
+
+```bash
+# Visualizza tutti i gruppi
+cat /etc/group
+
+# Aggiungi gruppo manualmente
+echo "docker:x:999:utente1,utente2" | sudo tee -a /etc/group
+```
+
+Formato:
+```
+gruppo:x:GID:lista_membri
+```
+
+### /etc/shadow
+
+```bash
+# Password e scadenza (richiede root)
+sudo cat /etc/shadow
+```
+
+## Valutazione Gruppi al Login
+
+I gruppi vengono valutati quando l'utente fa login:
+
+| Momento | Gruppi Valutati |
+|---------|-----------------|
+| Avvio sistema | No |
+| Login interattivo | Si |
+| `su - utente` | Si (nuovo login) |
+| `newgrp group` | Si (solo sessione corrente) |
+| `sudo -u utente cmd` | No (gruppi dell'utente originale) |
+| Aggiunta gruppo con usermod | No (fino al prossimo login) |
+
+## UID/GID Standard
+
+| UID/GID | Utente/Gruppo |
+|---------|---------------|
+| 0 | root |
+| 1-999 | Utenti di sistema |
+| 1000-60000 | Utenti normali |
+| 999 | docker (tipico) |
+
+## Comandi Rapidi
+
+```bash
+# Lista tutti gli utenti umani
+cat /etc/passwd | grep ':[1-9][0-9][0-9][0-9]:'
+
+# Lista tutti i gruppi
+cat /etc/group | cut -d: -f1
+
+# Utenti in un gruppo
+members gruppo
+# Oppure:
+getent group gruppo | cut -d: -f4
+```
+
+## Vedi Anche
+
+- [Reference: Permessi Socket Docker](./docker-socket-permissions.md)
+- [How-To: Aggiungi Utente al Gruppo Docker](../how-to-guides/add-user-to-docker-group.md)
+```
+
+**File 3: labs/lab-01-iam/reference/iam-parallels.md**
+```markdown
+# Reference: Parallelismi Docker e AWS IAM
+
+Tabella di riferimento rapido per i parallelismi tra concetti Docker/Linux e AWS IAM.
+
+## Tabella Parallelismi
+
+| Concetto Locale | AWS IAM Equivalente | Descrizione |
+|-----------------|---------------------|-------------|
+| 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 |
+| `usermod -aG docker` | `AttachUserPolicy` | Assegna permessi a utente |
+| Appartenenza gruppo `docker` | Policy attachment | Permessi attivi per utente |
+
+## Comandi a Confronto
+
+### Creazione Utente
+
+| Operazione Locale | Comando AWS |
+|-------------------|-------------|
+| `sudo useradd -m user` | `aws iam create-user --user-name user` |
+| `sudo passwd user` | `aws iam create-login-profile --user-name user --password Pass123!` |
+
+### Gestione Permessi
+
+| Operazione Locale | Comando AWS |
+|-------------------|-------------|
+| `sudo usermod -aG docker user` | `aws iam attach-user-policy --user-name user --policy-arn arn:aws:iam::aws:policy/PowerUserAccess` |
+| `sudo gpasswd -d user docker` | `aws iam detach-user-policy --user-name user --policy-arn arn:aws:iam::aws:policy/PowerUserAccess` |
+
+### Verifica Permessi
+
+| Operazione Locale | Comando AWS |
+|-------------------|-------------|
+| `groups user` | `aws iam list-attached-user-policies --user-name user` |
+| `id user` | `aws iam get-user --user-name user` |
+| `sudo -u user docker ps` | `aws sts get-caller-identity` |
+
+### Elevazione Privilegi
+
+| Operazione Locale | Comando AWS |
+|-------------------|-------------|
+| `sudo command` | Assumere IAM Role |
+| `su - root` | `aws sts assume-role` |
+
+## Differenze Chiave
+
+| Aspetto | Locale | Cloud AWS |
+|---------|--------|-----------|
+| Autenticazione | Password, SSH key | Access key, Secret key, Session token |
+| Autorizzazione | Gruppi Linux, permessi file | IAM Policies, JSON document |
+| Scope | Singolo host | Account AWS intero |
+| Audit | `last`, `/var/log/auth.log` | CloudTrail |
+| MFA | Non disponibile | Disponibile |
+
+## Modelli di Policy
+
+### Modello Allow
+
+**Locale:**
+```bash
+# Utente nel gruppo docker puo accedere al socket
+sudo usermod -aG docker utente
+```
+
+**AWS:**
+```json
+{
+ "Effect": "Allow",
+ "Action": "docker:*",
+ "Resource": "*"
+}
+```
+
+### Modello Deny
+
+**Locale:**
+```bash
+# Utente NON nel gruppo docker non puo accedere
+# (default deny)
+```
+
+**AWS:**
+```json
+{
+ "Effect": "Deny",
+ "Action": "docker:*",
+ "Resource": "*"
+}
+```
+
+## Best Practices Comuni
+
+| Best Practice | Locale | Cloud |
+|---------------|--------|-------|
+| Minimo privilegio | Utenti non-root | IAM Policies restrittive |
+| Separazione doveri | Gruppi distinti | Gruppi IAM distinti |
+| Audit logging | auth.log | CloudTrail |
+| Rotazione credenziali | `chage` | Rotate access keys |
+
+## Comandi Utili
+
+```bash
+# Verifica membri gruppo docker
+getent group docker
+
+# Simulazione:_lista politiche IAM
+aws iam list-attached-user-policies --user-name user
+
+# Verifica permessi socket
+ls -l /var/run/docker.sock
+
+# Simulazione:_simula accesso AWS
+aws sts get-caller-identity
+```
+
+## Vedi Anche
+
+- [Explanation: Docker IAM Parallels](../explanation/docker-iam-parallels.md)
+- [Tutorial: Permessi Docker](../tutorial/02-docker-group-permissions.md)
+```
+
+Key points:
+- Pure reference material (no tutorial content)
+- Tables and specifications
+- Command comparisons
+- Quick reference format
+
+
+ test -f labs/lab-01-iam/reference/docker-socket-permissions.md && test -f labs/lab-01-iam/reference/linux-users-groups.md && test -f labs/lab-01-iam/reference/iam-parallels.md && grep -q "|" labs/lab-01-iam/reference/*.md | wc -l | awk '{if($1>=15) print "PASS"; else print "FAIL: Reference docs need more tables"}'
+
+ Three reference documents created with technical specifications
+
+
+
+ Task 6: Create Explanation Document (IAM Parallels)
+ labs/lab-01-iam/explanation/docker-iam-parallels.md
+
+Create explanation document that connects local Docker concepts to cloud IAM:
+
+```markdown
+# Explanation: Parallelismi tra Docker Permissions e AWS IAM
+
+In questo documento esploreremo come i permessi Docker e la gestione utenti Linux simulano i concetti di Identity and Access Management (IAM) nei cloud provider come AWS. Comprendere questi parallelismi ti aiuterà a trasferire le conoscenze acquisite localmente agli ambienti cloud reali.
+
+## Cos'è IAM?
+
+**IAM (Identity and Access Management)** è il framework che controlla:
+- **Identity:** Chi sei (autenticazione)
+- **Access:** Cosa puoi fare (autorizzazione)
+
+AWS IAM, Azure IAM, Google Cloud IAM sono tutti basati sullo stesso concetto fondamentale: le identità hanno permessi specifici su risorse specifiche.
+
+---
+
+## Il Parallelismo Fondamentale
+
+### Utente Linux = IAM User
+
+| Locale | Cloud |
+|--------|-------|
+| Un utente Linux (`lab01_student`) | Un IAM User (`alice`) |
+| Può fare login al sistema | Può fare login ad AWS |
+| Ha UID univoco | Ha User ID univoco (AIDAI...) |
+| Appartiene a gruppi | Appartiene a IAM Groups |
+
+**Similitudine:** Entrambi rappresentano un'identità umana o di servizio che può autenticarsi.
+
+**Differenza:** Gli utenti Linux sono locali a una singola macchina, gli IAM Users sono globali all'account AWS.
+
+### Gruppo Linux = IAM Group
+
+| Locale | Cloud |
+|--------|-------|
+| Gruppo `docker` | IAM Group `Developers` |
+| Membri ereditano permessi del gruppo | Membri ereditano policies del gruppo |
+| Utente può essere in multipli gruppi | Utente può essere in multipli gruppi |
+| `groups user` mostra membrianze | `aws iam list-groups-for-user` |
+
+**Similitudine:** I gruppi rendono facile gestire i permessi per molti utenti. Aggiungi un utente al gruppo e ha automaticamente tutti i permessi del gruppo.
+
+**Differenza:** I gruppi Linux sono definiti localmente, i gruppi IAM sono definiti centralmente e possono avere utenti跨-region.
+
+### Socket Docker = Service Endpoint
+
+| Locale | Cloud |
+|--------|-------|
+| `/var/run/docker.sock` | AWS API endpoint (`https://ec2.amazonaws.com`) |
+| Accessibile solo con permessi corretti | Accessibile solo con credenziali valide |
+| `chmod 660` limita l'accesso | IAM policies limitano l'accesso |
+
+**Similitudine:** Entrambe sono risorse protette che richiedono autorizzazione per essere utilizzate.
+
+**Differenza:** Il socket Docker è un file Unix locale, gli API endpoint sono servizi web remoti.
+
+### Permessi File = IAM Policy
+
+| Locale | Cloud |
+|--------|-------|
+| `rw-rw----` su socket | JSON policy con `Effect: Allow/Deny` |
+| Utente deve essere nel gruppo `docker` | Utente deve avere policy permessiva |
+| `chmod` cambia permessi | `AttachUserPolicy` assegna policy |
+
+**Similitudine:** Entrambi definiscono regole esplicite su chi puo fare cosa.
+
+**Differenza:** I permessi Linux sono semplici (read/write/execute), le IAM policies sono espressioni complesse con condizioni, wildcard, e resource-level permissions.
+
+---
+
+## Esempio Pratico: Setup di un Nuovo Sviluppatore
+
+### Scenario Locale
+
+```bash
+# 1. Crea utente per il nuovo sviluppatore
+sudo useradd -m -s /bin/bash mario_rossi
+
+# 2. Aggiungi al gruppo docker (permette di lanciare container)
+sudo usermod -aG docker mario_rossi
+
+# 3. Verifica
+groups mario_rossi
+# Output: mario_rossi : mario_rossi docker
+
+# 4. Mario ora puo lanciare container
+sudo -u mario_rossi docker run alpine whoami
+```
+
+### Scenario Cloud AWS (Equivalente)
+
+```bash
+# 1. Crea IAM User per il nuovo sviluppatore
+aws iam create-user --user-name mario_rossi
+
+# 2. Crea gruppo per sviluppatori (se non esiste)
+aws iam create-group --group-name Developers
+
+# 3. Allega policy al gruppo (permette di usare EC2/containers)
+aws iam attach-group-policy \
+ --group-name Developers \
+ --policy-arn arn:aws:iam::aws:policy/PowerUserAccess
+
+# 4. Aggiungi utente al gruppo
+aws iam add-user-to-group \
+ --group-name Developers \
+ --user-name mario_rossi
+
+# 5. Verifica
+aws iam list-groups-for-user --user-name mario_rossi
+# Output: Groups: [Developers]
+
+# 6. Mario ora puo lanciare istanze EC2 (equivalente a container)
+aws ec2 run-instances --image-id ami-12345 ...
+```
+
+**Parallelismo:**
+- Entrambi iniziano creando un'identità
+- Entrambi usano gruppi per gestire i permessi
+- Entrambi verificano l'appartenenza al gruppo
+- Entrambi ora possono lanciare risorse (container/EC2)
+
+---
+
+## Il Principio del Minimo Privilegio
+
+### Locale: Non-Root Containers
+
+**Perché non root?**
+- Root in container = root sull'host (se vulnerabilità kernel)
+- Root puo leggere/scrivere qualsiasi file
+- Root puo modificare configurazioni di sistema
+
+**Soluzione locale:**
+```dockerfile
+# Dockerfile con utente non-root
+FROM alpine:3.19
+RUN adduser -D -u 1000 appuser
+USER appuser
+CMD ["sh", "-c", "whoami"]
+```
+
+**Verifica:**
+```bash
+docker exec container whoami
+# Output: appuser (NON root)
+```
+
+### Cloud: IAM Policies Restrittive
+
+**Perché policy minime?**
+- Chiave compromessa = danno limitato
+- Principio di least privilege
+- Audit e compliance requirements
+
+**Soluzione cloud:**
+```json
+{
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Effect": "Allow",
+ "Action": [
+ "s3:GetObject",
+ "s3:PutObject"
+ ],
+ "Resource": "arn:aws:s3:::my-bucket/*"
+ }
+ ]
+}
+```
+
+**Verifica:**
+```bash
+# Simula accesso dell'utente
+aws iam simulate-principal-policy \
+ --policy-source-arn arn:aws:iam::123456789012:user/mario_rossi \
+ --action-names s3:DeleteBucket \
+ # Output: Decision: Deny (policy non permette DeleteBucket)
+```
+
+**Parallelismo:**
+- Entrambi limitano cosa l'identità puo fare
+- Entrambi riducono la superficie di attacco
+- Entrambi sono verificabili tramite test
+
+---
+
+## Differenze tra Locale e Cloud
+
+### 1. Scope dei Permessi
+
+| Locale | Cloud |
+|--------|-------|
+| Permessi validi solo su questa macchina | Permessi validi per tutto l'account AWS |
+| Utente locale accede solo a risorse locali | IAM user accede a risorse globali |
+| Gruppi definiti in `/etc/group` | Gruppi definiti in IAM (centralizzato) |
+
+**Implicazione:** Nel cloud, un utente con permessi S3 puo accedere a tutti i bucket S3 nell'account, non solo a quelli "vicini" come nel filesystem locale.
+
+### 2. Complessità delle Policy
+
+| Locale | Cloud |
+|--------|-------|
+| Semplice: lettura/scrittura/esecuzione | Complesso: conditions, IP restrictions, MFA |
+| Basato su owner/group/other | Basato su JSON con wildcards |
+| Binario: o hai permesso o no | Granulare: resource-level, tag-based, time-based |
+
+**Esempio Cloud (non possibile localmente):**
+```json
+{
+ "Effect": "Allow",
+ "Action": "s3:*",
+ "Resource": "*",
+ "Condition": {
+ "IpAddress": {
+ "aws:SourceIp": ["203.0.113.0/24"]
+ },
+ "DateGreaterThan": {
+ "aws:CurrentTime": "2024-01-01T00:00:00Z"
+ },
+ "Bool": {
+ "aws:MultiFactorAuthPresent": "true"
+ }
+ }
+}
+```
+
+**Implicazione:** Le IAM policies sono piu potenti ma anche piu complesse da capire e debuggare.
+
+### 3. Audit e Logging
+
+| Locale | Cloud |
+|--------|-------|
+| `/var/log/auth.log` per login sudo | CloudTrail per tutte le chiamate API |
+| `last` mostra ultimi login | IAM Access Analyzer mostra attivita |
+| Manuale correlare eventi | Ricerche automatiche su CloudTrail Logs |
+
+**Implicazione:** Nel cloud hai audit trail automatico, completo e ricercabile. Localmente devi configurare e mantenere i log.
+
+### 4. Autenticazione
+
+| Locale | Cloud |
+|--------|-------|
+| Password, SSH key | Access Key ID, Secret Access Key, Session Token |
+| Password scade mai (default) | Access keys devono essere ruotate regolarmente |
+| MFA non disponibile | MFA obbligatorio per root/users in molte organizzazioni |
+
+**Implicazione:** Nel cloud, l'autenticazione e piu sicura di default (rotazione automatica, MFA, sessioni temporanee).
+
+---
+
+## Comandi Equivalenti: Quick Reference
+
+| Operazione | Locale | Cloud AWS |
+|------------|--------|-----------|
+| **Crea utente** | `sudo useradd -m user` | `aws iam create-user --user-name user` |
+| **Aggiungi a gruppo** | `sudo usermod -aG docker user` | `aws iam add-user-to-group --group-name Developers --user-name user` |
+| **Verifica permessi** | `groups user` | `aws iam list-attached-user-policies --user-name user` |
+| **Test accesso** | `sudo -u user docker ps` | `aws sts get-caller-identity` |
+| **Eleva privilegi** | `sudo command` | `aws sts assume-role` |
+| **Revoca permessi** | `sudo gpasswd -d user docker` | `aws iam detach-user-policy --user-name user --policy-arn ...` |
+| **Elimina utente** | `sudo userdel user` | `aws iam delete-user --user-name user` |
+
+---
+
+## Best Practices Transferibili
+
+### 1. Mai Usare Root per Lavoro Normale
+
+**Locale:**
+```bash
+# SBAGLIATO: Log in come root
+ssh root@server
+
+# GIUSTO: Log in come utente normale, usa sudo quando serve
+ssh user@server
+sudo command
+```
+
+**Cloud:**
+```bash
+# SBAGLIATO: Usa root account AWS (l'email con cui ti sei registrato)
+# Mai usare root account per operazioni quotidiane
+
+# GIUSTO: Crea IAM User con permessi limitati
+aws iam create-user --user-name daily-ops-user
+aws iam attach-user-policy --user-name daily-ops-user --policy-arn ...
+```
+
+### 2. Usa Gruppi per Gestire Permessi
+
+**Locale:**
+```bash
+# Invece di dare permessi a ogni singolo utente
+sudo usermod -aG docker user1
+sudo usermod -aG docker user2
+sudo usermod -aG docker user3
+
+# Tutti automaticamente ereditano i permessi del gruppo docker
+```
+
+**Cloud:**
+```bash
+# Invece di attachare policy a ogni singolo utente
+aws iam create-group --group-name Developers
+aws iam attach-group-policy --group-name Developers --policy-arn ...
+aws iam add-user-to-group --group-name Developers --user-name user1
+aws iam add-user-to-group --group-name Developers --user-name user2
+
+# Tutti automaticamente ereditano le policies del gruppo Developers
+```
+
+### 3. Verifica i Permessi
+
+**Locale:**
+```bash
+# Verifica che l'utente abbia i permessi corretti
+groups user
+id user
+sudo -u user docker ps
+```
+
+**Cloud:**
+```bash
+# Verifica che l'utente abbia le policies corrette
+aws iam list-attached-user-policies --user-name user
+aws iam simulate-principal-policy --policy-source-arn ... --action-names s3:GetObject
+```
+
+---
+
+## Conclusione
+
+I concetti che hai imparato in questo lab - utenti, gruppi, permessi - si applicano direttamente ad AWS IAM e altri cloud provider. La differenza principale e la scala e la complessita: nel cloud, questi concetti sono potenziati con condizioni granulari, audit automatico, e credenziali ruotabili.
+
+Quando lavorerai con AWS IAM, ricorda:
+- IAM User = Utente Linux (identità)
+- IAM Group = Gruppo Linux (raccolta di utenti con stessi permessi)
+- IAM Policy = Permessi file/socket (regole di accesso)
+- Service Endpoint = Socket Docker (risorsa protetta)
+
+Comprendendo questi parallelismi, sarai in grado di applicare le conoscenze locali al cloud con fiducia.
+
+---
+
+## Approfondimenti
+
+- [AWS IAM Documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html)
+- [IAM Best Practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html)
+- [Tutorial: Permessi Docker](../tutorial/02-docker-group-permissions.md)
+- [Reference: Tabella Parallelismi](../reference/iam-parallels.md)
+```
+
+Key points:
+- Clear explanation of IAM concepts
+- Side-by-side comparisons
+- Practical examples
+- Best practices transferable to cloud
+- Links to AWS documentation
+- Covers PARA-01 (Docker mapped to IAM), PARA-03 (differences documented), PARA-04 (commands shown)
+
+
+ test -f labs/lab-01-iam/explanation/docker-iam-parallels.md && grep -q "IAM\|AWS\|differenza\|difference" labs/lab-01-iam/explanation/docker-iam-parallels.md && wc -l labs/lab-01-iam/explanation/docker-iam-parallels.md | awk '{if($1>=80) print "PASS"; else print "FAIL: Explanation too short ("$1" lines, expected 80+)"}'
+
+ Explanation document created with IAM parallels and local-cloud differences
+
+
+
+
+
+1. All 4 Diátaxis document types exist: tutorial/, how-to-guides/, reference/, explanation/
+2. Tutorial follows "little often" principle (small incremental steps)
+3. How-to guides are procedure-focused (not tutorial-style)
+4. Reference documents are technical specifications without tutorial content
+5. Explanation document draws clear parallels between Docker and IAM (PARA-01, PARA-03, PARA-04)
+6. All documents use Italian language without emojis
+7. All documents have cross-references to related content
+
+
+
+1. Tutorial has 3 parts covering user creation, Docker permissions, and verification
+2. How-to guides cover common procedures independent of tutorial flow
+3. Reference documents provide technical specifications in quick-reference format
+4. Explanation document clearly maps Docker concepts to AWS IAM concepts
+5. All requirement IDs satisfied: LAB-01, DOCT-01, DOCT-02, DOCT-03, DOCT-04, DOCT-05, PARA-01, PARA-03, PARA-04
+
+
+
diff --git a/.planning/phases/02-lab-01-iam-sicurezza/02-03-PLAN.md b/.planning/phases/02-lab-01-iam-sicurezza/02-03-PLAN.md
new file mode 100644
index 0000000..567d531
--- /dev/null
+++ b/.planning/phases/02-lab-01-iam-sicurezza/02-03-PLAN.md
@@ -0,0 +1,504 @@
+---
+phase: 02-lab-01-iam-sicurezza
+plan: 03
+type: execute
+wave: 2
+depends_on: [02-01, 02-02]
+files_modified:
+ - labs/lab-01-iam/Dockerfile
+ - labs/lab-01-iam/docker-compose.yml
+ - labs/lab-01-iam/tests/04-verify-infrastructure.sh
+autonomous: true
+requirements: [LAB-01, INF-01, TEST-01]
+user_setup: []
+must_haves:
+ truths:
+ - "docker-compose.yml defines services with non-root user directive (INF-01)"
+ - "Dockerfile creates non-root user and switches before CMD (INF-01)"
+ - "Test scripts validate non-root execution (INF-01)"
+ - "Infrastructure follows test-driven approach (GREEN phase of TDI)"
+ artifacts:
+ - path: "labs/lab-01-iam/Dockerfile"
+ provides: "Non-root container image definition"
+ min_lines: 15
+ - path: "labs/lab-01-iam/docker-compose.yml"
+ provides: "Service orchestration with user directive"
+ min_lines: 20
+ - path: "labs/lab-01-iam/tests/04-verify-infrastructure.sh"
+ provides: "Infrastructure verification script"
+ min_lines: 25
+ key_links:
+ - from: "docker-compose.yml"
+ to: "Dockerfile"
+ via: "build context and image reference"
+ pattern: "build:.*\\..*Dockerfile"
+ - from: "tests/04-verify-infrastructure.sh"
+ to: "docker-compose.yml, Dockerfile"
+ via: "Infrastructure validation"
+ pattern: "docker-compose.*-f.*docker-compose.yml"
+---
+
+
+Create Docker infrastructure (Dockerfile and docker-compose.yml) that implements non-root container execution (INF-01). Following TDD methodology, infrastructure is created AFTER tests exist, and tests should now pass (GREEN phase).
+
+Purpose: Implement minimum infrastructure to satisfy LAB-01 and INF-01 requirements while ensuring all containers run as non-root.
+Output: Dockerfile with non-root user, docker-compose.yml with user directive, and infrastructure verification test.
+
+
+
+@/home/luca/.claude/get-shit-done/workflows/execute-plan.md
+@/home/luca/.claude/get-shit-done/templates/summary.md
+
+
+
+@.planning/PROJECT.md
+@.planning/ROADMAP.md
+@.planning/STATE.md
+@.planning/phases/02-lab-01-iam-sicurezza/02-RESEARCH.md
+@.planning/phases/02-lab-01-iam-sicurezza/02-VALIDATION.md
+@CLAUDE.md
+
+# From RESEARCH.md - Non-Root Container Pattern
+
+```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
+USER appuser
+
+# Verify non-root execution
+CMD ["sh", "-c", "echo 'Running as:' && whoami"]
+```
+
+```yaml
+# docker-compose.yml with user directive
+services:
+ test-container:
+ image: alpine:3.19
+ user: "1000:1000" # UID:GID for non-root
+ command: ["sh", "-c", "whoami && sleep 3600"]
+```
+
+# From RESEARCH.md - Verification Methods
+
+```bash
+# Method 1: Execute whoami inside container
+docker exec whoami
+# Expected output: appuser (NOT root)
+
+# Method 2: Inspect container configuration
+docker inspect --format='{{.State.User}}'
+
+# Method 3: Check process on host
+docker top
+# Look at USER column - should show UID (e.g., 1000), NOT 0 (root)
+```
+
+# Common Pitfalls to Avoid
+
+- Running containers as root (violates INF-01)
+- Using `--privileged` flag (defeats container isolation)
+- Skipping verification of non-root execution
+- Forgetting `user:` directive in docker-compose.yml
+
+# TDD Methodology - GREEN Phase
+
+Now that tests exist (Wave 0), implement MINIMUM infrastructure to make them pass:
+1. docker-compose.yml with `user:` directive
+2. Dockerfile with `USER` directive
+3. Run tests to verify GREEN phase
+4. Do NOT over-engineer - minimum to pass tests is sufficient
+
+
+
+
+
+ Task 1: Create Dockerfile with non-root user
+ labs/lab-01-iam/Dockerfile
+
+ - Base image: alpine:3.19 (small, secure)
+ - Creates non-root user with UID/GID 1000
+ - Switches to non-root user with USER directive
+ - CMD demonstrates non-root execution with whoami
+ - Follows INF-01 requirement (no root execution)
+
+
+Create Dockerfile that implements non-root container execution:
+
+```dockerfile
+# Lab 01 - IAM & Sicurezza
+# Dockerfile per container non-root (INF-01 requirement)
+#
+# Questo Dockerfile dimostra come creare un container che gira
+# come utente non-root, seguendo il principio del minimo privilegio.
+
+FROM alpine:3.19
+
+# Label per metadata
+LABEL maintainer="Lab 01 - IAM & Sicurezza"
+LABEL description="Container non-root per dimostrare permessi IAM"
+LABEL version="1.0"
+
+# Crea utente non-root con UID/GID specifici per consistenza
+# UID 1000 e GID 1000 sono comuni per utenti non-root
+RUN addgroup -g 1000 labuser && \
+ adduser -D -u 1000 -G labuser labuser
+
+# Imposta la working directory (creata con adduser -D)
+WORKDIR /home/labuser
+
+# Crea un file semplice per verificare i permessi di scrittura
+RUN echo "Questo file e stato creato durante la build" > /home/labuser/test.txt && \
+ chown labuser:labuser /home/labuser/test.txt
+
+# PASSA A UTENTE NON-ROOT PRIMA DI QUALSIASI OPERAZIONE
+# Questo e il punto chiave per INF-01: nessun processo gira come root
+USER labuser
+
+# Verifica che il container gira come utente non-root
+CMD ["sh", "-c", "\
+echo '========================================' && \
+echo 'Lab 01 - IAM & Sicurezza' && \
+echo 'Container non-root verification (INF-01)' && \
+echo '========================================' && \
+echo '' && \
+echo 'Utente corrente:' && \
+whoami && \
+echo '' && \
+echo 'UID:' && \
+id -u && \
+echo '' && \
+echo 'GID:' && \
+id -g && \
+echo '' && \
+echo 'Gruppi:' && \
+groups && \
+echo '' && \
+echo 'Home directory:' && \
+pwd && \
+echo '' && \
+echo 'Contenuto di test.txt (permessi scrittura):' && \
+cat test.txt && \
+echo '' && \
+echo '========================================' && \
+echo 'Se vedi \"labuser\" sopra, INF-01 e soddisfatto!' && \
+echo '========================================' && \
+echo '' && \
+echo 'Container in esecuzione. Premi Ctrl-C per uscire.' && \
+sleep 3600 \
+"]
+```
+
+Key implementation points:
+- Base image Alpine 3.19 (minimal, secure)
+- Creates `labuser` with UID/GID 1000
+- USER directive switches to non-root BEFORE CMD
+- CMD demonstrates and verifies non-root execution
+- Follows INF-01 requirement strictly
+- Labels for metadata and documentation
+- Working directory set to user's home
+- Test file to verify write permissions
+
+TDD Context: This is the GREEN phase - tests already exist (from Wave 0), this Dockerfile should make those tests pass.
+
+
+ cd labs/lab-01-iam && docker build -t lab01-non-root . && docker run --rm lab01-non-root | grep -q "labuser" && echo "PASS: Container runs as non-root" || echo "FAIL: Container not running as labuser"
+
+ Dockerfile creates non-root container verified by whoami output
+
+
+
+ Task 2: Create docker-compose.yml with user directive
+ labs/lab-01-iam/docker-compose.yml
+
+ - Defines service with local image build
+ - Specifies user directive (1000:1000) for non-root execution
+ - Includes container_name for easy reference
+ - Follows INF-01 requirement (no root)
+ - Enables test scripts to verify configuration
+
+
+Create docker-compose.yml that enforces non-root execution:
+
+```yaml
+# Lab 01 - IAM & Sicurezza
+# Docker Compose configuration per container non-root
+#
+# Questo file definisce i servizi per il lab, assicurandosi che
+# TUTTI i container girino come utente non-root (INF-01).
+
+version: "3.8"
+
+services:
+ # Container di test per verificare l'esecuzione non-root
+ lab01-test:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ image: lab01-non-root:latest
+ container_name: lab01-iam-test
+ # CRITICO: user directive assicura esecuzione non-root (INF-01)
+ # Format: UID:GID
+ # 1000:1000 corrisponde all'utente labuser creato nel Dockerfile
+ user: "1000:1000"
+ # Non esponiamo porte (non necessario per questo lab)
+ # Le porte private non devono essere esposte sull'host (best practice)
+ restart: unless-stopped
+ # Nessun volume mount necessario per questo lab semplice
+ # I volumi saranno introdotti nei lab successivi
+ healthcheck:
+ # Healthcheck per verificare che il container sia sano
+ test: ["CMD", "sh", "-c", "whoami | grep -q labuser"]
+ interval: 30s
+ timeout: 5s
+ retries: 3
+ start_period: 5s
+
+# Nessuna rete definita - useremo la default bridge network
+# Le reti custom isolate saranno introdotte nel Lab 02 (Network & VPC)
+
+# Nessun volume definito - i volumi saranno introdotti nel Lab 04 (Storage & S3)
+```
+
+Key implementation points:
+- Service definition with local build context
+- `user: "1000:1000"` directive enforces non-root execution
+- Container name matches test expectations
+- Healthcheck verifies non-root user
+- Comments explain why no volumes/networks (future labs)
+- Follows docker-compose V3.8 syntax
+- No ports exposed (security best practice)
+
+TDD Context: Tests from Wave 0 check for user directive - this configuration should satisfy those tests.
+
+INF-01 Compliance:
+- User directive explicitly set
+- Healthcheck verifies non-root execution
+- No possibility of root execution
+
+
+ cd labs/lab-01-iam && docker-compose config > /dev/null 2>&1 && echo "PASS: docker-compose.yml is valid" || echo "FAIL: docker-compose.yml has errors"
+
+ docker-compose.yml defines service with non-root user directive
+
+
+
+ Task 3: Create infrastructure verification script
+ labs/lab-01-iam/tests/04-verify-infrastructure.sh
+
+ - Test 1: docker-compose.yml is valid YAML
+ - Test 2: Dockerfile builds successfully
+ - Test 3: Service has user directive set
+ - Test 4: Built container runs as non-root
+ - Test 5: All INF-01 requirements satisfied
+
+
+Create infrastructure verification script (TDD GREEN phase verification):
+
+```bash
+#!/bin/bash
+# Infrastructure Verification: Lab 01
+# Verifies that docker-compose.yml and Dockerfile satisfy all requirements
+# This is the GREEN phase check - tests should pass after infrastructure implementation
+
+set -euo pipefail
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+BLUE='\033[0;34m'
+NC='\033[0m'
+
+TEST_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+PROJECT_ROOT="$(cd "$TEST_DIR/../.." && pwd)"
+LAB_DIR="$PROJECT_ROOT/labs/lab-01-iam"
+
+cd "$LAB_DIR"
+
+echo -e "${BLUE}========================================${NC}"
+echo -e "${BLUE}Lab 01 Infrastructure Verification${NC}"
+echo -e "${BLUE}GREEN Phase Check${NC}"
+echo -e "${BLUE}========================================${NC}"
+echo ""
+
+pass_count=0
+fail_count=0
+
+# Test 1: docker-compose.yml is valid
+echo -e "${BLUE}[1/6] Checking docker-compose.yml syntax...${NC}"
+if docker-compose config >/dev/null 2>&1; then
+ echo -e " ${GREEN}✓${NC} docker-compose.yml is valid YAML"
+ ((pass_count++))
+else
+ echo -e " ${RED}✗${NC} docker-compose.yml has syntax errors"
+ ((fail_count++))
+fi
+echo ""
+
+# Test 2: Dockerfile exists and is readable
+echo -e "${BLUE}[2/6] Checking Dockerfile...${NC}"
+if [ -f "Dockerfile" ]; then
+ echo -e " ${GREEN}✓${NC} Dockerfile exists"
+
+ # Check for USER directive
+ if grep -q "^USER" Dockerfile; then
+ user_line=$(grep "^USER" Dockerfile)
+ echo -e " ${GREEN}✓${NC} USER directive found: $user_line"
+ ((pass_count++))
+ else
+ echo -e " ${RED}✗${NC} No USER directive found in Dockerfile"
+ ((fail_count++))
+ fi
+else
+ echo -e " ${RED}✗${NC} Dockerfile not found"
+ ((fail_count++))
+fi
+echo ""
+
+# Test 3: docker-compose.yml has user directive
+echo -e "${BLUE}[3/6] Checking docker-compose.yml user directive...${NC}"
+if grep -q "user:" docker-compose.yml; then
+ user_value=$(grep "user:" docker-compose.yml | head -1 | sed 's/.*user: *//' | tr -d '"')
+ echo -e " ${GREEN}✓${NC} user directive found: $user_value"
+
+ # Verify it's not root (0:0)
+ if [[ "$user_value" != *"0:0"* ]] && [[ "$user_value" != *"root"* ]]; then
+ echo -e " ${GREEN}✓${NC} User is not root (INF-01 compliant)"
+ ((pass_count++))
+ else
+ echo -e " ${RED}✗${NC} User is root (INF-01 violation)"
+ ((fail_count++))
+ fi
+else
+ echo -e " ${RED}✗${NC} No user directive in docker-compose.yml"
+ ((fail_count++))
+fi
+echo ""
+
+# Test 4: Build Docker image
+echo -e "${BLUE}[4/6] Building Docker image...${NC}"
+if docker build -t lab01-non-root -q Dockerfile >/dev/null 2>&1; then
+ echo -e " ${GREEN}✓${NC} Docker image built successfully"
+ ((pass_count++))
+else
+ echo -e " ${RED}✗${NC} Docker image build failed"
+ ((fail_count++))
+fi
+echo ""
+
+# Test 5: Verify container runs as non-root
+echo -e "${BLUE}[5/6] Verifying non-root execution...${NC}"
+if docker run --rm lab01-non-root whoami 2>/dev/null | grep -q "labuser"; then
+ echo -e " ${GREEN}✓${NC} Container runs as non-root user (labuser)"
+ ((pass_count++))
+else
+ echo -e " ${RED}✗${NC} Container not running as labuser"
+ ((fail_count++))
+fi
+echo ""
+
+# Test 6: Verify docker-compose service
+echo -e "${BLUE}[6/6] Verifying docker-compose service...${NC}"
+# Start container in detached mode
+if docker-compose up -d >/dev/null 2>&1; then
+ echo -e " ${GREEN}✓${NC} docker-compose service started"
+
+ # Wait for container to be ready
+ sleep 3
+
+ # Check container is running
+ if docker ps --format "{{.Names}}" | grep -q "^lab01-iam-test$"; then
+ echo -e " ${GREEN}✓${NC} Container is running"
+
+ # Verify user
+ actual_user=$(docker exec lab01-iam-test whoami 2>/dev/null || echo "unknown")
+ if [ "$actual_user" = "labuser" ]; then
+ echo -e " ${GREEN}✓${NC} docker-compose container runs as non-root"
+ ((pass_count++))
+ else
+ echo -e " ${RED}✗${NC} docker-compose container running as $actual_user (expected labuser)"
+ ((fail_count++))
+ fi
+ else
+ echo -e " ${RED}✗${NC} Container not running"
+ ((fail_count++))
+ fi
+
+ # Cleanup
+ docker-compose down --volumes >/dev/null 2>&1
+else
+ echo -e " ${RED}✗${NC} Failed to start docker-compose service"
+ ((fail_count++))
+fi
+echo ""
+
+# Summary
+echo -e "${BLUE}========================================${NC}"
+echo -e "${BLUE}Verification Summary${NC}"
+echo -e "${BLUE}========================================${NC}"
+echo "Passed: $pass_count/6"
+echo "Failed: $fail_count/6"
+echo ""
+
+if [ $fail_count -eq 0 ]; then
+ echo -e "${GREEN}All checks passed!${NC}"
+ echo -e "${GREEN}GREEN phase complete - infrastructure satisfies tests${NC}"
+ echo ""
+ echo "Next: Run full test suite"
+ echo " bash labs/lab-01-iam/tests/run-all-tests.sh"
+ echo -e "${BLUE}========================================${NC}"
+ exit 0
+else
+ echo -e "${RED}Some checks failed${NC}"
+ echo -e "${RED}Infrastructure needs fixes before tests will pass${NC}"
+ echo -e "${BLUE}========================================${NC}"
+ exit 1
+fi
+```
+
+Key implementation points:
+- Validates docker-compose.yml syntax
+- Verifies USER directive in Dockerfile
+- Verifies user directive in docker-compose.yml
+- Builds and tests Docker image
+- Starts container with docker-compose and verifies execution
+- Proper cleanup after testing
+- Clear pass/fail indicators
+
+TDD Context: This script confirms the GREEN phase - infrastructure implementation makes tests pass.
+
+
+ chmod +x labs/lab-01-iam/tests/04-verify-infrastructure.sh && cd labs/lab-01-iam && bash ../tests/04-verify-infrastructure.sh
+
+ Infrastructure verification script confirms all requirements satisfied
+
+
+
+
+
+1. Dockerfile creates non-root user with USER directive
+2. docker-compose.yml specifies user directive for service
+3. docker-compose config validates without errors
+4. Docker build succeeds without warnings
+5. Container execution verified as non-root (whoami, docker inspect, docker top)
+6. All Wave 0 tests now pass (GREEN phase of TDD)
+7. INF-01 requirement satisfied: no container runs as root
+
+
+
+1. Dockerfile follows non-root best practices from RESEARCH.md
+2. docker-compose.yml enforces non-root execution via user directive
+3. Infrastructure verification confirms all requirements met
+4. Tests from Wave 0 (02-01-PLAN.md) now pass
+5. LAB-01 requirement satisfied: students can configure users and Docker permissions
+6. INF-01 requirement satisfied: no container runs as root
+
+
+