mirror of
https://github.com/hanzoai/ci.git
synced 2026-10-20 15:28:05 +00:00
A gated preview answers the read-back 401, and that is the gate working
Hanzo CI/CD / cicd (push) Failing after 2m14s
CI/CD / gate (push) Failing after 2m14s
Hanzo CI/CD / cicd (push) Failing after 2m14s
CI/CD / gate (push) Failing after 2m14s
The read-back demands HTTP 200 from the live URL. A client preview cannot give one: hanzo-apps hosts are guarded, so they answer an API caller 401 and a browser a redirect to hanzo.id. The same workflow's "every host is gated" step REFUSES to publish any host that answers otherwise, so the two steps asked one deploy to be two contradictory things. It cost 27 of 29 client sites. The first slug of each repo uploaded and flipped live, the read-back called it unreadable, and `set -e` took the remaining sites down with it -- leaving hosts that resolve and gate with nothing behind them. A browser-shaped probe that does not follow tells a gate from a failure: a gate redirects to hanzo.id naming that host as its own callback, which proves the host is routed and guarded. Its bytes still are not read back, so the run says so rather than counting it verified. Every other failure path is unchanged: an empty body, a short read and a plain non-200 all still fail. Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
@@ -489,10 +489,40 @@ else
|
||||
echo " $got bytes"; return 0
|
||||
}
|
||||
|
||||
# A client preview is gated on purpose: the guard answers an API caller 401 and
|
||||
# a browser a redirect to hanzo.id, so its bytes are NOT readable anonymously
|
||||
# and the 200 above can never arrive. That is the gate working, not an
|
||||
# unreadable object -- the "every host is gated" step in the calling workflow
|
||||
# REQUIRES exactly this answer, so demanding 200 here asks one deploy to be two
|
||||
# contradictory things. It cost 27 of 29 client sites: the first slug of each
|
||||
# repo published, the read-back failed it, and `set -e` took the rest down with
|
||||
# it, leaving hosts that resolve and gate with nothing behind them.
|
||||
#
|
||||
# Asking as a browser, without following, tells a gate from a failure: a gate
|
||||
# redirects to hanzo.id naming THIS host as the callback, which proves the host
|
||||
# is routed and guarded. Anything else still fails.
|
||||
gated() {
|
||||
local out code loc host
|
||||
host=${live#*://}; host=${host%%/*}
|
||||
out=$(curl -sS --max-time 30 -o /dev/null -H 'Accept: text/html' \
|
||||
-w '%{http_code} %{redirect_url}' "$live" 2>/dev/null) || return 1
|
||||
code=${out%% *}; loc=${out#* }
|
||||
case "$code" in 301|302|303|307|308) ;; *) return 1 ;; esac
|
||||
case "$loc" in https://hanzo.id/*|https://*.hanzo.id/*) ;; *) return 1 ;; esac
|
||||
case "$loc" in *"$host"*) ;; *) return 1 ;; esac
|
||||
return 0
|
||||
}
|
||||
|
||||
ok=
|
||||
for attempt in 1 2 3; do
|
||||
printf 'read-back %s (attempt %d): ' "$live" "$attempt"
|
||||
if readback; then ok=1; break; fi
|
||||
# Named out loud, because a gated host counted as verified in silence is how
|
||||
# a site that serves nothing would pass this check.
|
||||
if gated; then
|
||||
echo " gated by hanzo.id: routed and guarded, so its bytes are not read back"
|
||||
ok=1; break
|
||||
fi
|
||||
[ "$attempt" -lt 3 ] && sleep 5
|
||||
done
|
||||
|
||||
|
||||
+26
-1
@@ -122,7 +122,7 @@ fi
|
||||
shim="$tmp/bin"; mkdir -p "$shim"
|
||||
cat > "$shim/curl" <<'SHIM'
|
||||
#!/usr/bin/env bash
|
||||
out=/dev/null hdr=/dev/null url= method=GET body= src= fields=()
|
||||
out=/dev/null hdr=/dev/null url= method=GET body= src= wfmt= fields=()
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-o) out="$2"; shift 2 ;;
|
||||
@@ -135,6 +135,7 @@ while [ $# -gt 0 ]; do
|
||||
# than the thing sent, which is precisely the error a size test cannot carry.
|
||||
--data-binary) src="${2#@}"; shift 2 ;;
|
||||
-F) fields+=("$2"); shift 2 ;;
|
||||
-w) wfmt="$2"; shift 2 ;;
|
||||
http*) url="$1"; shift ;;
|
||||
*) shift ;;
|
||||
esac
|
||||
@@ -163,6 +164,16 @@ case "$url" in
|
||||
case "${T_BACK:-ok}" in
|
||||
empty) : > "$out"; len=0 ;;
|
||||
short) printf 'hi' > "$out"; len=99 ;;
|
||||
# A gated client preview. The plain read-back is an API
|
||||
# caller and gets 401; the browser-shaped probe gets the
|
||||
# guard's redirect, naming this host as its own callback.
|
||||
gated) : > "$out"
|
||||
printf 'content-length: 0\r\n' > "$hdr"
|
||||
case "$wfmt" in
|
||||
*redirect_url*) printf '302 https://hanzo.id/v1/iam/oauth/authorize?client_id=hanzo-guard&redirect_uri=https%%3A%%2F%%2Fa-slug.hanzo.app%%2F__guard%%2Fcallback' ;;
|
||||
*) printf '401' ;;
|
||||
esac
|
||||
exit 0 ;;
|
||||
*) printf '<h1>hi</h1>\n' > "$out"
|
||||
len=$(wc -c < "$out" | tr -d ' ') ;;
|
||||
esac
|
||||
@@ -394,5 +405,19 @@ out=$(PATH="$shim:$PATH" HANZO_API=https://api.test HANZO_DEPLOY_TOKEN=sk-test \
|
||||
t "a short read fails the deploy" "$([ "$rc" != 0 ] && echo failed)" "failed"
|
||||
t " ...reporting both counts, thrice" "$(printf '%s' "$out" | grep -c 'content-length promised')" "3"
|
||||
|
||||
# A gated client preview answers the read-back 401 BY DESIGN -- and the same
|
||||
# workflow's "every host is gated" step refuses to publish any host that answers
|
||||
# otherwise. Demanding 200 here asked one deploy to be two contradictory things:
|
||||
# the first slug of each repo published, the read-back called it unreadable, and
|
||||
# `set -e` took the remaining 27 client sites down with it, leaving hosts that
|
||||
# resolve and gate with nothing behind them.
|
||||
rm -f "$tmp/calls"
|
||||
out=$(PATH="$shim:$PATH" HANZO_API=https://api.test HANZO_DEPLOY_TOKEN=sk-test \
|
||||
SITE_JOBS=1 T_DIR="$tmp" T_ENQ="$ENQ" T_DONE="$DONE" T_BACK=gated \
|
||||
bash "$SD" a-slug "$site" 2>&1); rc=$?
|
||||
t "a gated preview publishes" "$rc" "0"
|
||||
t " ...and says it was not read back" "$(printf '%s' "$out" | grep -c 'gated by hanzo.id')" "1"
|
||||
t " ...not calling it unreadable" "$(printf '%s' "$out" | grep -c 'does not serve its own bytes')" "0"
|
||||
|
||||
[ $fail -eq 0 ] && echo "PASS" || echo "FAIL"
|
||||
exit $fail
|
||||
|
||||
Reference in New Issue
Block a user