fetch_ml/scripts/check-audit-sink.sh
Jeremie Fraeys dddc2913e1
chore(tools): update scripts, native libs, and documentation
Update tooling and documentation:
- Smoke test script with scheduler health checks
- Release cleanup script
- Native test scripts with Redis integration
- TUI SSH test script
- Performance regression detector with scheduler metrics
- Profiler with distributed tracing
- Native CMake with test targets
- Dataset hash tests
- Storage symlink resistance tests
- Configuration reference documentation updates
2026-02-26 12:08:58 -05:00

165 lines
4.7 KiB
Bash

#!/bin/bash
# Pre-deployment audit sink gate script
# Verifies the write-once audit sink is reachable and writable
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Default values
ENV="staging"
TIMEOUT=10
AUDIT_SINK_HOST=""
AUDIT_SINK_PORT=""
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--env)
ENV="$2"
shift 2
;;
--timeout)
TIMEOUT="$2"
shift 2
;;
--host)
AUDIT_SINK_HOST="$2"
shift 2
;;
--port)
AUDIT_SINK_PORT="$2"
shift 2
;;
--help)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " --env ENV Environment (staging|prod) [default: staging]"
echo " --timeout SECONDS Timeout in seconds [default: 10]"
echo " --host HOST Audit sink host (auto-detected if not set)"
echo " --port PORT Audit sink port (auto-detected if not set)"
echo " --help Show this help message"
exit 0
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Auto-detect audit sink based on environment
if [ -z "$AUDIT_SINK_HOST" ]; then
case $ENV in
staging)
AUDIT_SINK_HOST="ml-staging-audit-sink"
AUDIT_SINK_PORT="6379"
;;
prod)
AUDIT_SINK_HOST="ml-prod-audit-sink"
AUDIT_SINK_PORT="6379"
;;
*)
echo -e "${RED}Error: Unknown environment '$ENV'${NC}"
exit 1
;;
esac
fi
echo "Checking audit sink for environment: $ENV"
echo "Host: $AUDIT_SINK_HOST"
echo "Port: $AUDIT_SINK_PORT"
echo "Timeout: ${TIMEOUT}s"
# Check if we can reach the audit sink
echo ""
echo "Step 1: Checking network reachability..."
if command -v nc &> /dev/null; then
if timeout $TIMEOUT nc -z "$AUDIT_SINK_HOST" "$AUDIT_SINK_PORT" 2>/dev/null; then
echo -e "${GREEN}✓ Audit sink is reachable on port $AUDIT_SINK_PORT${NC}"
else
echo -e "${RED}✗ Audit sink is NOT reachable on $AUDIT_SINK_HOST:$AUDIT_SINK_PORT${NC}"
echo "This is a HARD STOP for HIPAA deployments."
exit 1
fi
elif command -v redis-cli &> /dev/null; then
# Try to ping via redis-cli if available
if timeout $TIMEOUT redis-cli -h "$AUDIT_SINK_HOST" -p "$AUDIT_SINK_PORT" ping 2>/dev/null | grep -q "PONG"; then
echo -e "${GREEN}✓ Audit sink responded to Redis ping${NC}"
else
echo -e "${RED}✗ Audit sink did not respond to Redis ping${NC}"
echo "This is a HARD STOP for HIPAA deployments."
exit 1
fi
else
echo -e "${YELLOW}⚠ Neither nc nor redis-cli available - skipping reachability check${NC}"
echo "For production, ensure one of these tools is installed."
fi
# Check if audit sink is writable (append-only test)
echo ""
echo "Step 2: Checking write capability..."
# For a proper audit sink, we should be able to write but not modify
# This is typically implemented with Redis append-only file (AOF) persistence
# and restricted commands
if command -v docker &> /dev/null; then
# Check if the audit sink container is running
CONTAINER_NAME="ml-${ENV}-audit-sink"
if docker ps | grep -q "$CONTAINER_NAME"; then
echo -e "${GREEN}✓ Audit sink container '$CONTAINER_NAME' is running${NC}"
# Test write capability
TEST_KEY="audit_test_$(date +%s)"
TEST_VALUE="test_$(uuidgen 2>/dev/null || echo $RANDOM)"
if docker exec "$CONTAINER_NAME" redis-cli SET "$TEST_KEY" "$TEST_VALUE" EX 60 > /dev/null 2>&1; then
echo -e "${GREEN}✓ Audit sink accepts writes${NC}"
# Verify we can read it back
READ_VALUE=$(docker exec "$CONTAINER_NAME" redis-cli GET "$TEST_KEY" 2>/dev/null)
if [ "$READ_VALUE" = "$TEST_VALUE" ]; then
echo -e "${GREEN}✓ Audit sink read-after-write successful${NC}"
else
echo -e "${YELLOW}⚠ Audit sink read-after-write mismatch${NC}"
fi
# Clean up
docker exec "$CONTAINER_NAME" redis-cli DEL "$TEST_KEY" > /dev/null 2>&1 || true
else
echo -e "${RED}✗ Audit sink does not accept writes${NC}"
exit 1
fi
else
echo -e "${YELLOW}⚠ Audit sink container '$CONTAINER_NAME' not found${NC}"
echo "Container may not be running or may have a different name."
fi
else
echo -e "${YELLOW}⚠ Docker not available - skipping container check${NC}"
fi
# Final summary
echo ""
echo "==================================="
echo "Audit Sink Check Summary"
echo "==================================="
echo -e "${GREEN}✓ Audit sink is reachable and writable${NC}"
echo ""
echo "Deployment can proceed."
echo "Note: This check does NOT verify:"
echo " - Append-only configuration"
echo " - Log retention policies"
echo " - Chain integrity"
echo " - Tamper resistance"
echo ""
echo "These must be verified separately for full HIPAA compliance."
exit 0