mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-14 08:59:01 +02:00
feat(security): receipt admin scripts + user git-ops (zero exceptions)
Wire the remaining shell egress through gstack-egress-lib.sh: - gstack-gbrain-mcp-verify: both JSON-RPC probe POSTs (initialize + tools/list) receipted fail-closed via payload files (hash == wire bytes). A refused receipt lands in the NETWORK class — no send. - gstack-security-dashboard / gstack-community-dashboard: the community-pulse GETs receipted fail-open (read-only stats must not break over an audit hiccup). - gstack-gbrain-supabase-provision: api_call receipted fail-closed. Each retry attempt hands the helper a fresh copy of the body file (the helper consumes its payload). The receipt hashes the request body only — the PAT never reaches the ledger or any log. Refusal exits 8 without retrying. - git-class sha256:null receipts, fail-open: gstack-artifacts-init (ls-remote, initial push, fetch/pull recovery, retry push), gstack-brain-restore (staging clone, existing-repo fetch), gstack-session-update (self-update pull). gstack-team-init needs no wiring: every git clone in it is inside an echoed instruction string, not an executed command. The lib now self-locates with shell builtins only (no dirname), so sourcing works under the whitelist-PATH test harnesses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> (cherry picked from commit b8c5e2055b21ab72878b3e46f8047782ee65a11c)
This commit is contained in:
@@ -30,6 +30,10 @@ set -euo pipefail
|
||||
GSTACK_HOME="${GSTACK_HOME:-$HOME/.gstack}"
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
CONFIG_BIN="$SCRIPT_DIR/gstack-config"
|
||||
|
||||
# Egress receipt helpers (_receipted_git): fail-open for user-directed
|
||||
# git ops against the user's own artifacts remote.
|
||||
. "$SCRIPT_DIR/gstack-egress-lib.sh"
|
||||
# v1.27.0.0+ canonical name; brain-remote is the legacy fallback during the
|
||||
# migration window. The migration script renames the file in place.
|
||||
if [ -f "$HOME/.gstack-artifacts-remote.txt" ]; then
|
||||
@@ -78,7 +82,9 @@ STAGING=$(mktemp -d "${TMPDIR:-/tmp}/gstack-brain-restore.XXXXXX")
|
||||
trap 'rm -rf "$STAGING" 2>/dev/null' EXIT
|
||||
|
||||
echo "Cloning $REMOTE_URL to staging..."
|
||||
if ! git clone --quiet "$REMOTE_URL" "$STAGING/repo" 2>/dev/null; then
|
||||
RESTORE_HOST="${REMOTE_URL#*://}"; RESTORE_HOST="${RESTORE_HOST#*@}"; RESTORE_HOST="${RESTORE_HOST%%[/:]*}"
|
||||
if ! _receipted_git open brain-restore "${RESTORE_HOST:-unknown}" brain-restore-clone "user ran gstack-brain-restore" \
|
||||
bash -c 'git clone --quiet "$1" "$2" 2>/dev/null' _ "$REMOTE_URL" "$STAGING/repo"; then
|
||||
echo "Clone failed. Check:" >&2
|
||||
echo " - URL is correct: $REMOTE_URL" >&2
|
||||
echo " - Auth: gh auth status (github) / glab auth status (gitlab)" >&2
|
||||
@@ -160,7 +166,8 @@ done
|
||||
# ---- move .git into place ----
|
||||
if [ -d "$GSTACK_HOME/.git" ]; then
|
||||
# Existing .git with matching remote — just fetch + fast-forward.
|
||||
git -C "$GSTACK_HOME" fetch origin >/dev/null 2>&1 || true
|
||||
_receipted_git open brain-restore "${RESTORE_HOST:-unknown}" brain-restore-fetch "user ran gstack-brain-restore" \
|
||||
bash -c 'git -C "$1" fetch origin >/dev/null 2>&1' _ "$GSTACK_HOME" || true
|
||||
else
|
||||
mv "$STAGING/repo/.git" "$GSTACK_HOME/.git"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user