[object Object]

← back to Tk10895 GroupB

TK-10895: George send script — fix set -e/pipefail guard + move secrets out of argv

58b6353d8595d60338f48cb76f59e1cd2bbebb60 · 2026-09-16 13:41:12 -0700 · Steve Abrams

- Keychain/token fetches no longer abort under set -euo pipefail, so the
  explicit missing-credential checks actually run and report.
- Pass GEORGE_TOKEN/GEORGE_BASIC via env instead of argv so the send token
  and admin Keychain password aren't visible in ps during the send.
- Successful-send behavior unchanged; only failure-path diagnostics and
  secret transport changed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GCskP2LLkHeL4xp2yDUyQ7

Files touched

Diff

commit 58b6353d8595d60338f48cb76f59e1cd2bbebb60
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Sep 16 13:41:12 2026 -0700

    TK-10895: George send script — fix set -e/pipefail guard + move secrets out of argv
    
    - Keychain/token fetches no longer abort under set -euo pipefail, so the
      explicit missing-credential checks actually run and report.
    - Pass GEORGE_TOKEN/GEORGE_BASIC via env instead of argv so the send token
      and admin Keychain password aren't visible in ps during the send.
    - Successful-send behavior unchanged; only failure-path diagnostics and
      secret transport changed.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01GCskP2LLkHeL4xp2yDUyQ7
---
 send-quadrille-email.sh | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/send-quadrille-email.sh b/send-quadrille-email.sh
index 8c9894a..a991e11 100755
--- a/send-quadrille-email.sh
+++ b/send-quadrille-email.sh
@@ -13,7 +13,8 @@ set -euo pipefail
 
 GEORGE=http://127.0.0.1:9850
 BODY_FILE=~/Projects/tk10895-groupB/quadrille-email.html
-TOKEN=$(grep -m1 '^GEORGE_EXTERNAL_SEND_TOKEN=' ~/Projects/george-gmail/.env | cut -d= -f2- | tr -d ' ')
+# `|| true` so a missing token doesn't abort here (set -e + pipefail) — let the explicit check below report it.
+TOKEN=$(grep -m1 '^GEORGE_EXTERNAL_SEND_TOKEN=' ~/Projects/george-gmail/.env 2>/dev/null | cut -d= -f2- | tr -d ' ' || true)
 
 if [ -z "$TOKEN" ]; then
   echo "!! GEORGE_EXTERNAL_SEND_TOKEN not found in ~/Projects/george-gmail/.env — cannot send."
@@ -33,9 +34,20 @@ echo
 read -r -p "Send this now? type SEND to confirm: " ans
 [ "$ans" = "SEND" ] || { echo "aborted — nothing sent."; exit 0; }
 
-python3 - "$BODY_FILE" "$TOKEN" "$GEORGE" <<'PY'
-import json, sys, urllib.request
-body_file, token, george = sys.argv[1], sys.argv[2], sys.argv[3]
+# George's API is Basic-auth'd; the MCP loads the same credential from Keychain.
+# `|| true` so a missing Keychain item doesn't abort here (set -e + pipefail) — let the check below report it.
+BASIC=$(security find-generic-password -s dw-agents -a admin -w 2>/dev/null || true)
+BASIC=${BASIC//$'\n'/}
+if [ -z "$BASIC" ]; then
+  echo "!! no Keychain credential (service dw-agents / account admin) — cannot authenticate to George."
+  exit 1
+fi
+
+# Secrets go through the environment, NOT argv — argv is visible to any local process via `ps`.
+GEORGE_TOKEN="$TOKEN" GEORGE_BASIC="$BASIC" python3 - "$BODY_FILE" "$GEORGE" <<'PY'
+import base64, json, os, sys, urllib.request
+body_file, george = sys.argv[1], sys.argv[2]
+token, basic = os.environ["GEORGE_TOKEN"], os.environ["GEORGE_BASIC"]
 payload = {
     "account": "info",
     "to": "Erica@quadrilleinc.com",
@@ -46,7 +58,11 @@ payload = {
 req = urllib.request.Request(
     george + "/api/send",
     data=json.dumps(payload).encode(),
-    headers={"Content-Type": "application/json", "X-Send-Approval": token},
+    headers={
+        "Content-Type": "application/json",
+        "X-Send-Approval": token,
+        "Authorization": "Basic " + base64.b64encode(("admin:" + basic).encode()).decode(),
+    },
 )
 try:
     print(json.load(urllib.request.urlopen(req, timeout=60)))

← 47a6046 TK-10895: vendor follow-up, table regenerated from verified  ·  back to Tk10895 GroupB  ·  (newest)