wxccai/bin/load-assets-sync-secret.sh
jmcqueen 66255a7b0c Docs: prefer .env for ASSETS_SYNC_TOKEN; Keychain is optional dev path
The bot runs on a Linux host where macOS Keychain isn't available, so .env
is the default supported storage for the personal PAT. Both paths land in
the same process.env slot, but the previous README framing implied Keychain
was mandatory.

- .env.example: promote ASSETS_SYNC_TOKEN from a comment to a real
  REPLACE_ME field; note chmod 600 and rotation guidance
- README: split the setup section into "Setup A - production/Linux (.env)"
  and "Setup B - local dev on macOS (Keychain)"; clarify that the wrapper
  is a no-op if ASSETS_SYNC_TOKEN is already exported
- bin/load-assets-sync-secret.sh: soften the header comment to match

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:22:40 -04:00

78 lines
3.1 KiB
Bash
Executable file

#!/usr/bin/env sh
# -----------------------------------------------------------------------------
# load-assets-sync-secret.sh
#
# Loads the personal Atlassian PAT used for the Assets → Stores cache sync
# from macOS Keychain into ASSETS_SYNC_TOKEN, then execs whatever command you
# passed as arguments.
#
# Rationale:
# The service account is silently filtered out of Object Type 109 (Store
# Address / Hierarchy) — see Forgejo issue #1. The stores cache is populated
# using a personal PAT instead. On a shared dev Mac, Keychain is a nicer home
# for that PAT than .env (encrypted at rest, per-user access). On the prod
# Linux host where the bot actually runs, put the PAT in .env directly with
# `chmod 600 .env` — this script exits as a no-op if ASSETS_SYNC_TOKEN is
# already exported into the process env.
#
# Setup (one-time, per machine):
#
# # 1. Store the token in Keychain
# security add-generic-password \
# -s jira-assets-sync \
# -a mcqueenj@ae.com \
# -w '<paste-your-atlassian-api-token-here>' \
# -U
#
# # 2. Set the email (either exported here or in ~/.zshrc)
# export ASSETS_SYNC_EMAIL="mcqueenj@ae.com"
#
# Usage:
#
# ./bin/load-assets-sync-secret.sh npm start
# ./bin/load-assets-sync-secret.sh node src/app.js
#
# Environment variables (override defaults if needed):
#
# ASSETS_SYNC_KEYCHAIN_SERVICE Keychain service name (default: jira-assets-sync)
# ASSETS_SYNC_KEYCHAIN_ACCOUNT Keychain account name (default: value of $ASSETS_SYNC_EMAIL)
# ASSETS_SYNC_TOKEN If already set, skip the Keychain read entirely.
# -----------------------------------------------------------------------------
set -eu
if [ -z "${ASSETS_SYNC_TOKEN:-}" ]; then
SERVICE="${ASSETS_SYNC_KEYCHAIN_SERVICE:-jira-assets-sync}"
ACCOUNT="${ASSETS_SYNC_KEYCHAIN_ACCOUNT:-${ASSETS_SYNC_EMAIL:-}}"
if [ -z "$ACCOUNT" ]; then
printf 'load-assets-sync-secret.sh: neither ASSETS_SYNC_TOKEN nor an account name is set.\n' >&2
printf ' Export ASSETS_SYNC_EMAIL=you@ae.com or ASSETS_SYNC_KEYCHAIN_ACCOUNT=<account>.\n' >&2
exit 1
fi
if ! command -v security >/dev/null 2>&1; then
printf 'load-assets-sync-secret.sh: `security` not found (this script is macOS-only).\n' >&2
printf ' On Linux/prod, export ASSETS_SYNC_TOKEN directly from your secret manager.\n' >&2
exit 1
fi
if ! ASSETS_SYNC_TOKEN=$(security find-generic-password -s "$SERVICE" -a "$ACCOUNT" -w 2>/dev/null); then
printf 'load-assets-sync-secret.sh: Keychain lookup failed for service="%s" account="%s".\n' "$SERVICE" "$ACCOUNT" >&2
printf ' Store the token with:\n' >&2
printf ' security add-generic-password -s %s -a %s -w '\''<token>'\'' -U\n' "$SERVICE" "$ACCOUNT" >&2
exit 1
fi
export ASSETS_SYNC_TOKEN
fi
# Only echoes existence, never the token itself.
printf 'load-assets-sync-secret.sh: ASSETS_SYNC_TOKEN loaded (%d chars) for %s\n' \
"${#ASSETS_SYNC_TOKEN}" "${ASSETS_SYNC_EMAIL:-<unset ASSETS_SYNC_EMAIL>}" >&2
if [ $# -eq 0 ]; then
printf 'load-assets-sync-secret.sh: no command given; exiting after loading token.\n' >&2
exit 0
fi
exec "$@"