#!/usr/bin/env bash # PANELS · Fase 0 · verifica que el aislamiento entre módulos realmente # se cumple (no solo que las credenciales existan). Pensado para correr # después de 01-04 (Postgres) y 05 (Redis), en cualquier ambiente. # # Uso: source el .env con DATABASE_URL_*/REDIS_URL_* y correr este script. set -uo pipefail cd "$(dirname "$0")" fail=0 check() { local desc="$1"; local expect_fail="$2"; shift 2 if "$@" >/tmp/verify-out.$$ 2>&1; then ok=1 else ok=0 fi if [[ "$expect_fail" == "yes" && "$ok" == "0" ]] || [[ "$expect_fail" == "no" && "$ok" == "1" ]]; then echo "OK - $desc" else echo "FAIL - $desc" cat /tmp/verify-out.$$ fail=1 fi rm -f /tmp/verify-out.$$ } : "${DATABASE_URL_PLATFORM:?}"; : "${DATABASE_URL_IAM:?}"; : "${DATABASE_URL_CORE:?}" : "${REDIS_URL_IAM:?}"; : "${REDIS_URL_CORE:?}" extract_pw() { echo "$1" | sed -E 's#[a-zA-Z]+://[^:]+:([^@]+)@.*#\1#'; } PLATFORM_HOST=$(echo "$DATABASE_URL_PLATFORM" | sed -E 's#.*@([^/]+)/.*#\1#') echo "== Postgres: DML normal funciona ==" check "iam_app puede hacer SELECT en su esquema" no psql "$DATABASE_URL_IAM" -c "SELECT 1;" check "core_app puede hacer SELECT en su esquema" no psql "$DATABASE_URL_CORE" -c "SELECT 1;" echo "== Postgres: aislamiento cruzado ==" check "iam_app NO puede leer schema core" yes psql "$DATABASE_URL_IAM" -c "SELECT * FROM core.pg_tables LIMIT 1;" check "core_app NO puede leer schema iam" yes psql "$DATABASE_URL_CORE" -c "SELECT 1 FROM iam.pg_am LIMIT 1;" check "iam_app NO puede hacer DDL (solo _owner puede)" yes psql "$DATABASE_URL_IAM" -c "CREATE TABLE iam.probe_$$(id int);" PLATFORM_APP_PW=$(extract_pw "$DATABASE_URL_PLATFORM") IAM_APP_PW=$(extract_pw "$DATABASE_URL_IAM") check "platform_app NO puede CONNECT a panels_product" yes \ psql "postgresql://panels_platform_app:${PLATFORM_APP_PW}@${PLATFORM_HOST%/*}/panels_product" -c "SELECT 1;" check "iam_app NO puede CONNECT a panels_platform" yes \ psql "postgresql://panels_iam_app:${IAM_APP_PW}@${PLATFORM_HOST%/*}/panels_platform" -c "SELECT 1;" echo "== Redis: ACL por módulo ==" IAM_REDIS_HOST=$(echo "$REDIS_URL_IAM" | sed -E 's#redis://[^@]+@##') IAM_REDIS_PW=$(extract_pw "$REDIS_URL_IAM") CORE_REDIS_PW=$(extract_pw "$REDIS_URL_CORE") check "panels_iam_redis puede escribir iam:*" no \ redis-cli -u "redis://panels_iam_redis:${IAM_REDIS_PW}@${IAM_REDIS_HOST}" SET iam:verify:probe 1 check "panels_iam_redis NO puede leer core:* (NOPERM)" no \ bash -c "redis-cli -u 'redis://panels_iam_redis:${IAM_REDIS_PW}@${IAM_REDIS_HOST}' GET core:probe 2>&1 | grep -q NOPERM" check "panels_core_redis NO puede leer iam:* (NOPERM)" no \ bash -c "redis-cli -u 'redis://panels_core_redis:${CORE_REDIS_PW}@${IAM_REDIS_HOST}' GET iam:probe 2>&1 | grep -q NOPERM" echo "" if [[ "$fail" == "0" ]]; then echo "Todas las verificaciones de aislamiento pasaron." else echo "Hay verificaciones fallidas -- revisar antes de continuar." exit 1 fi