← 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
M send-quadrille-email.sh
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)