#!/usr/bin/env bash set -euo pipefail root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P) verify="$root/scripts/verify-dwh-auth-docs.sh" temp_root= report_pass() { printf 'case=%s status=PASS\n' "$1" } report_fail() { printf 'case=%s status=FAIL\n' "$1" >&2 exit 1 } cleanup() { if [[ "$temp_root" == /tmp/thothii-dwh-auth-docs.* && -d "$temp_root" ]]; then rm -rf -- "$temp_root" fi } trap cleanup EXIT [[ -x "$verify" ]] || report_fail verifier_missing temp_root=$(mktemp -d /tmp/thothii-dwh-auth-docs.XXXXXXXX) || report_fail fixture_root fixture_root="$temp_root/fixture" mkdir -p "$fixture_root/docs/install" "$fixture_root/docs/operations" \ "$fixture_root/docs/testing/evidence" "$fixture_root/scripts" "$fixture_root/deploy/psd" for relative in \ docs/install/dwh-auth-server.md \ docs/install/dwh-auth-client-enrollment.md \ docs/install/dwh-auth-tls.md \ docs/operations/psd-dwh-auth-rollout.md \ docs/testing/dwh-auth-manual-acceptance.md \ docs/testing/evidence/psd-dwh-auth-rollout-report-template.md \ docs/install/local-workspace-registry.md \ docs/install/server-workspace-registry.md \ docs/install/psd-workspace-setup.md \ docs/guida-utente.md \ docs/index.md \ mkdocs.yml; do mkdir -p "$fixture_root/$(dirname "$relative")" cp "$root/$relative" "$fixture_root/$relative" done cp -a "$root/docs/." "$fixture_root/docs/" cp "$root/deploy/psd/workspace-bindings.env.example" "$fixture_root/deploy/psd/workspace-bindings.env.example" "$verify" --root "$fixture_root" || report_fail positive_source report_pass positive_source expect_rejected() { local name=$1 target=$2 addition=$3 local case_root="$temp_root/$name" cp -a "$fixture_root" "$case_root" printf '\n%s\n' "$addition" >>"$case_root/$target" if "$verify" --root "$case_root" >/dev/null 2>&1; then report_fail "$name" fi report_pass "$name" } exercise_header_file_curl() { local v1_header="$temp_root/synthetic-v1.header" local legacy_header="$temp_root/synthetic-legacy.header" command -v curl >/dev/null 2>&1 || report_fail header_file_curl_command printf '%s\n' 'X-API-Key: synthetic-v1' >"$v1_header" printf '%s\n' 'X-API-Key: legacy opaque value /:[]' >"$legacy_header" chmod 0600 "$v1_header" "$legacy_header" if ! python3 - "$v1_header" "$legacy_header" <<'PY' import http.server import pathlib import stat import subprocess import sys import threading accepted = {"synthetic-v1", "legacy opaque value /:[]"} class Handler(http.server.BaseHTTPRequestHandler): def log_message(self, _format, *_args): pass def do_GET(self): self.send_response(204 if self.headers.get("X-API-Key") in accepted else 401) self.end_headers() server = http.server.ThreadingHTTPServer(("127.0.0.1", 0), Handler) thread = threading.Thread(target=server.serve_forever, daemon=True) thread.start() try: for header_file in sys.argv[1:]: if stat.S_IMODE(pathlib.Path(header_file).stat().st_mode) != 0o600: raise SystemExit(1) result = subprocess.run( ["curl", "--silent", "--show-error", "--output", "/dev/null", "--write-out", "%{http_code}", "--header", f"@{header_file}", f"http://127.0.0.1:{server.server_port}/rpc/ping"], check=False, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True, ) if result.returncode != 0 or result.stdout != "204": raise SystemExit(1) finally: server.shutdown() thread.join() PY then report_fail header_file_curl_synthetic fi report_pass header_file_curl_synthetic } # Build synthetic only-in-fixture text at runtime: it is never a provisioned credential. fake_key="thtdwh_v1.$(printf 'A%.0s' {1..16}).$(printf 'A%.0s' {1..43})" fake_digest="$(printf 'A%.0s' {1..43})" expect_rejected credential_literal docs/install/dwh-auth-client-enrollment.md "$fake_key" expect_rejected opaque_legacy_header_literal docs/install/dwh-auth-client-enrollment.md "curl --header 'X-API-Key: opaque-legacy-fixture' https://example.invalid/dwh/rpc/ping" expect_rejected credential_digest_literal docs/testing/evidence/psd-dwh-auth-rollout-report-template.md "\"secret_sha256\": \"$fake_digest\"" expect_rejected curl_insecure docs/install/dwh-auth-tls.md 'curl -k https://example.invalid/dwh/rpc/ping' expect_rejected tls_disabled docs/install/dwh-auth-tls.md 'verify_tls=false' expect_rejected secret_in_environment docs/install/dwh-auth-client-enrollment.md "export THT_WS_PSD_CLINICAL_DWH_API_KEY=$fake_key" expect_rejected secret_in_argv docs/install/dwh-auth-client-enrollment.md "curl -H 'X-API-Key: $fake_key' https://example.invalid/dwh/rpc/ping" expect_rejected curl_config_artifact docs/install/dwh-auth-server.md 'curl --config /root/dwh-auth-provision/request.conf https://example.invalid/dwh/rpc/ping' expect_rejected world_readable_secret docs/install/dwh-auth-server.md 'chmod 0644 /root/dwh-auth-provision/client.key' expect_rejected sudo_raw_nginx_capture docs/operations/psd-dwh-auth-rollout.md 'sudo nginx -T > /tmp/nginx-full.conf' expect_rejected raw_diff_capture docs/operations/psd-dwh-auth-rollout.md 'sudo diff -u /etc/nginx/sites-available/policlinicosandonato /root/backup.conf' expect_rejected git_raw_diff_capture docs/operations/psd-dwh-auth-rollout.md 'git diff --no-index /root/old.conf /root/new.conf' expect_rejected raw_nginx_capture docs/operations/psd-dwh-auth-rollout.md 'nginx -T > /tmp/nginx-full.conf' expect_rejected compose_coupling docs/install/dwh-auth-server.md 'docker compose up dwh-auth' expect_replacement_rejected() { local name=$1 target=$2 needle=$3 replacement=$4 local case_root="$temp_root/$name" cp -a "$fixture_root" "$case_root" [[ $(grep -Foc -- "$needle" "$case_root/$target") -eq 1 ]] || report_fail "${name}_fixture" sed -i "s~$needle~$replacement~" "$case_root/$target" if "$verify" --root "$case_root" >/dev/null 2>&1; then report_fail "$name"; fi report_pass "$name" } expect_global_replacement_rejected() { local name=$1 target=$2 needle=$3 replacement=$4 local case_root="$temp_root/$name" cp -a "$fixture_root" "$case_root" [[ $(grep -Foc -- "$needle" "$case_root/$target") -gt 0 ]] || report_fail "${name}_fixture" sed -i "s~$needle~$replacement~g" "$case_root/$target" if "$verify" --root "$case_root" >/dev/null 2>&1; then report_fail "$name"; fi report_pass "$name" } exercise_header_file_curl expect_replacement_rejected missing_exact_gui_label docs/install/dwh-auth-client-enrollment.md "Validate workspace source" "Validate workspace" expect_replacement_rejected server_transport_contradiction docs/operations/psd-dwh-auth-rollout.md 'server PSD: `postgres_direct` read-only' 'server PSD: `rest_api` read-only' expect_replacement_rejected missing_mac_local_marker deploy/psd/workspace-bindings.env.example "Mac/local/remota" "server PSD" expect_replacement_rejected missing_private_ca docs/install/psd-workspace-setup.md "TLS_CA_FILE" "TLS_CA_REMOVED" expect_global_replacement_rejected missing_socket_path docs/install/dwh-auth-server.md "/run/dwh-auth/verify.sock" "/run/dwh-auth/other.sock" expect_replacement_rejected rest_transport_flag deploy/psd/workspace-bindings.env.example "THT_WS_PSD_CLINICAL_DWH_TRANSPORT=rest_api" "THT_WS_PSD_CLINICAL_DWH_TRANSPORT=postgres_direct" expect_replacement_rejected wrong_key_output_path docs/install/dwh-auth-server.md "key_output=/root/dwh-auth-provision/psd-mac-primary.key" "key_output=/root/dwh-auth-provision/psd-mac-primary-primary.key" expect_replacement_rejected wrong_legacy_key_id docs/install/dwh-auth-server.md "legacy_key_id=legacy-shared" "legacy_key_id=legacy-public-key-id" expect_global_replacement_rejected missing_header_file_transport docs/install/dwh-auth-server.md '--header "@' '--header "X-API-Key: ' expect_global_replacement_rejected missing_legacy_header_file docs/install/dwh-auth-server.md "legacy_header_file" "retired_auth_header" expect_global_replacement_rejected missing_safe_restore docs/install/dwh-auth-server.md "registry_staging" "registry_overlay" expect_replacement_rejected unsafe_restore_overlay docs/install/dwh-auth-server.md "sudo tar --acls --xattrs -C \"\$registry_staging\" -xf \"\$registry_backup\"" "sudo tar --acls --xattrs -C /var/lib -xf \"\$registry_backup\"" expect_replacement_rejected missing_guarded_registry_publish docs/install/dwh-auth-server.md "if ! sudo mv -T -- \"\$registry_root\" \"\$registry_previous\"; then" "sudo mv -T -- \"\$registry_root\" \"\$registry_previous\"" expect_replacement_rejected missing_candidate_check_guard docs/install/dwh-auth-server.md "if ! sudo /usr/local/sbin/dwh-auth --registry-root \"\$registry_candidate\" check; then" "sudo /usr/local/sbin/dwh-auth --registry-root \"\$registry_candidate\" check" expect_replacement_rejected unsafe_registry_publish_target docs/install/dwh-auth-server.md "if ! sudo mv -T -- \"\$registry_root\" \"\$registry_previous\"; then" "if ! sudo mv \"\$registry_root\" \"\$registry_previous\"; then" expect_replacement_rejected missing_key_file_byte_guard docs/install/dwh-auth-server.md "key_file_bytes=PASS" "key_file_bytes=SKIPPED" expect_replacement_rejected missing_failed_registry_publish_target docs/install/dwh-auth-server.md "if ! sudo mv -T -- \"\$registry_root\" \"\$registry_staging/failed-dwh-auth\"; then" "if ! sudo mv \"\$registry_root\" \"\$registry_staging/failed-dwh-auth\"; then" expect_global_replacement_rejected missing_rollback_registry_publish_target docs/install/dwh-auth-server.md "if ! sudo mv -T -- \"\$registry_previous\" \"\$registry_root\"; then" "if ! sudo mv \"\$registry_previous\" \"\$registry_root\"; then" expect_global_replacement_rejected missing_exact_header_bytes docs/install/dwh-auth-server.md 'dd if="$1" bs=65536 status=none' 'dd if="$1" bs=1' expect_replacement_rejected missing_actual_key_journal_scan docs/install/dwh-auth-server.md "journal_actual_key_scan=PASS" "journal_generic_scan=PASS" expect_replacement_rejected missing_journal_actual_key_match docs/install/dwh-auth-server.md "any(key in line for key in actual_keys)" "False" expect_replacement_rejected missing_journal_returncode_guard docs/install/dwh-auth-server.md "if result.returncode != 0:" "if result.returncode == 0:" expect_replacement_rejected missing_socket_legacy_probe docs/install/dwh-auth-server.md "socket_legacy=PASS" "socket_legacy=SKIPPED" expect_replacement_rejected missing_https_post_revoke_v1 docs/install/dwh-auth-server.md "https_v1_post_revoke=PASS" "https_v1_post_revoke=SKIPPED" expect_replacement_rejected missing_https_post_revoke_legacy docs/install/dwh-auth-server.md "https_legacy_post_revoke=PASS" "https_legacy_post_revoke=SKIPPED" expect_global_replacement_rejected rollout_post_revoke_status docs/operations/psd-dwh-auth-rollout.md "v1=2xx post-revoca" "v1=204 post-revoca" report_pass summary