#!/bin/bash set -e echo "╔══════════════════════════════════════════════════════════════╗" echo "║ SECURITY HARDENING ACCEPTANCE TESTS ║" echo "╚══════════════════════════════════════════════════════════════╝" echo "" PASSED=0 FAILED=0 PAYLOAD='{"org_id":"00000000-0000-0000-0000-000000000000","user_id":"00000000-0000-0000-0000-000000000001","queries":["test"],"top_k":1}' # Test 1: DB ports not accessible from host echo "=== Test 1: DB Network Isolation ===" for port in 5432 6333 7474 6379; do if timeout 2 nc -zv localhost $port 2>&1 | grep -q "succeeded"; then echo "❌ FAIL: Port $port is accessible from host" FAILED=$((FAILED + 1)) else echo "✅ PASS: Port $port is not accessible" PASSED=$((PASSED + 1)) fi done # Test 2: Memory API requires JWT echo "" echo "=== Test 2: Memory API JWT Protection ===" RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8000/retrieve -X POST -H "Content-Type: application/json" -d "$PAYLOAD" || true) if [ "$RESPONSE" = "401" ]; then echo "✅ PASS: Memory API requires authentication" PASSED=$((PASSED + 1)) elif [ "$RESPONSE" = "000" ]; then echo "ℹ️ Host access blocked (expected). Testing inside container..." INTERNAL=$(cat << 'PY' | docker exec -i dagi-memory-service-node1 python3 - import urllib.request, urllib.error payload = b'{"org_id":"00000000-0000-0000-0000-000000000000","user_id":"00000000-0000-0000-0000-000000000001","queries":["test"],"top_k":1}' req = urllib.request.Request("http://localhost:8000/retrieve", data=payload, headers={"Content-Type":"application/json"}, method="POST") try: with urllib.request.urlopen(req, timeout=3) as resp: print(resp.status) except urllib.error.HTTPError as e: print(e.code) except Exception: print("ERR") PY ) if [ "$INTERNAL" = "401" ]; then echo "✅ PASS: Memory API requires authentication (internal)" PASSED=$((PASSED + 1)) else echo "❌ FAIL: Memory API auth check failed (internal got $INTERNAL)" FAILED=$((FAILED + 1)) fi else echo "❌ FAIL: Memory API does not require auth (got $RESPONSE)" FAILED=$((FAILED + 1)) fi # Test 3: Control Plane requires JWT echo "" echo "=== Test 3: Control Plane JWT Protection ===" RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:9200/prompts/helion || true) if [ "$RESPONSE" = "401" ]; then echo "✅ PASS: Control Plane requires authentication" PASSED=$((PASSED + 1)) elif [ "$RESPONSE" = "000" ]; then echo "ℹ️ Host access blocked (expected). Testing inside container..." INTERNAL=$(cat << 'PY' | docker exec -i control-plane python3 - import urllib.request, urllib.error req = urllib.request.Request("http://localhost:9200/prompts/helion") try: with urllib.request.urlopen(req, timeout=3) as resp: print(resp.status) except urllib.error.HTTPError as e: print(e.code) except Exception: print("ERR") PY ) if [ "$INTERNAL" = "401" ]; then echo "✅ PASS: Control Plane requires authentication (internal)" PASSED=$((PASSED + 1)) else echo "❌ FAIL: Control Plane auth check failed (internal got $INTERNAL)" FAILED=$((FAILED + 1)) fi else echo "❌ FAIL: Control Plane does not require auth (got $RESPONSE)" FAILED=$((FAILED + 1)) fi # Test 4: Gateway public access echo "" echo "=== Test 4: Gateway Public Access ===" RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:9300/health || true) if [ "$RESPONSE" = "200" ]; then echo "✅ PASS: Gateway is publicly accessible" PASSED=$((PASSED + 1)) else echo "⚠️ WARN: Gateway health check returned $RESPONSE" fi # Summary echo "" echo "═══════════════════════════════════════════════════════════════" echo " TEST SUMMARY" echo "═══════════════════════════════════════════════════════════════" echo "Passed: $PASSED" echo "Failed: $FAILED" echo "" if [ $FAILED -eq 0 ]; then echo "✅ All critical tests passed!" exit 0 else echo "⚠️ Some tests failed - review required" exit 1 fi