#!/usr/bin/env bash # Verification harness for sealed-mode egress: Docker/Compose or Kubernetes. # Examples: # ./verify-egress-block.sh docker stella_default out/airgap-probe.json # ./verify-egress-block.sh k8s default out/k8s-probe.json set -euo pipefail mode=${1:-} context=${2:-} out=${3:-} if [[ -z "$mode" || -z "$context" || -z "$out" ]]; then echo "Usage: $0 [target ...]" >&2 exit 2 fi shift 3 TARGETS=($@) ROOT=$(cd "$(dirname "$0")/../.." && pwd) PROBE_PY="$ROOT/ops/devops/sealed-mode-ci/egress_probe.py" case "$mode" in docker) network="$context" python3 "$PROBE_PY" --network "$network" --output "$out" "${TARGETS[@]}" ;; k8s|kubernetes) ns="$context" targets=("${TARGETS[@]}") if [[ ${#targets[@]} -eq 0 ]]; then targets=("https://example.com" "https://www.cloudflare.com" "https://releases.stella-ops.org/healthz") fi image="curlimages/curl:8.6.0" tmpfile=$(mktemp) cat > "$tmpfile" < set -euo pipefail; rc=0; for url in ${targets[@]}; do echo "PROBE $url"; if curl -fsS --max-time 8 "$url"; then echo "UNEXPECTED_SUCCESS $url"; rc=1; else echo "BLOCKED $url"; fi; done; exit $rc; securityContext: runAsNonRoot: true readOnlyRootFilesystem: true MANIFEST kubectl apply -f "$tmpfile" >/dev/null kubectl wait --for=condition=Ready pod/sealed-egress-probe -n "$ns" --timeout=30s >/dev/null 2>&1 || true set +e kubectl logs -n "$ns" sealed-egress-probe > "$out.log" 2>&1 kubectl wait --for=condition=Succeeded pod/sealed-egress-probe -n "$ns" --timeout=60s pod_rc=$? kubectl get pod/sealed-egress-probe -n "$ns" -o json > "$out" kubectl delete pod/sealed-egress-probe -n "$ns" >/dev/null 2>&1 || true set -e if [[ $pod_rc -ne 0 ]]; then echo "Egress check failed; see $out and $out.log" >&2 exit 1 fi ;; *) echo "Unknown mode: $mode" >&2 exit 2 ;; esac echo "Egress verification complete → $out"