#!/usr/bin/env bash # # provision-hub-tokens.sh - add one Hub client token per door to the secrets # file. # # The Hub accepts one bearer token per client, not per person # (docs/hub-api.md section 3). This script adds the five HUB_TOKEN_* keys to # ~/.config/environment.d/10-secrets.conf. # # It is idempotent. It adds only the keys that are missing. It never prints a # token value and never overwrites an existing token. # # This changes host credentials. It needs Sam's OK before it runs # (AGENTS.md "ask first: credentials"). # # Usage: # scripts/provision-hub-tokens.sh --check # report present/missing, change nothing # scripts/provision-hub-tokens.sh --dry-run # same as --check, no change # scripts/provision-hub-tokens.sh # add the missing keys # # Exit codes: # 0 done (or all keys already present) # 1 the secrets file is missing or is not usable # 2 bad usage # set -euo pipefail readonly SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" readonly PROJECT_DIR="$(cd -- "$SCRIPT_DIR/.." && pwd)" readonly SECRETS_FILE="${HUB_SECRETS_FILE:-$HOME/.config/environment.d/10-secrets.conf}" # The five doors from docs/hub-api.md section 3. readonly TOKEN_KEYS=(HUB_TOKEN_PHONE HUB_TOKEN_ESP32 HUB_TOKEN_DSH HUB_TOKEN_CONSOLE HUB_TOKEN_ADMIN) mode="apply" case "${1:-}" in --check|--dry-run) mode="check" ;; "") ;; *) echo "usage: $(basename "$0") [--check|--dry-run]" >&2; exit 2 ;; esac # gen_hex32 prints 64 hex characters (32 random bytes). It uses openssl when # it is installed, and /dev/urandom otherwise. This host has no openssl. gen_hex32() { if command -v openssl >/dev/null 2>&1; then openssl rand -hex 32 return fi od -An -N32 -tx1 /dev/urandom | tr -d ' \n' } if [[ ! -f "$SECRETS_FILE" ]]; then echo "error: secrets file not found: $SECRETS_FILE" >&2 exit 1 fi # has_key reports whether KEY is already set in the file. has_key() { local key="$1" grep -qE "^[[:space:]]*${key}=" "$SECRETS_FILE" } missing=() for key in "${TOKEN_KEYS[@]}"; do if has_key "$key"; then echo "present: $key" else echo "missing: $key" missing+=("$key") fi done if [[ ${#missing[@]} -eq 0 ]]; then echo "done: all ${#TOKEN_KEYS[@]} Hub tokens are present. No change." exit 0 fi if [[ "$mode" == "check" ]]; then echo "check only: ${#missing[@]} token(s) would be added. No change." exit 0 fi # Back up first. The backup keeps the same restrictive mode. backup="${SECRETS_FILE}.bak.$(date -u +%Y%m%dT%H%M%SZ)" cp -p "$SECRETS_FILE" "$backup" chmod 600 "$backup" echo "backup: $backup" # Add the missing keys. openssl writes the value; nothing prints it. { echo "" echo "# Hub client tokens (one per door, docs/hub-api.md section 3)." echo "# Added by scripts/provision-hub-tokens.sh on $(date -u +%Y-%m-%dT%H:%M:%SZ)." for key in "${missing[@]}"; do value="$(gen_hex32)" printf '%s="%s"\n' "$key" "$value" done } >> "$SECRETS_FILE" chmod 600 "$SECRETS_FILE" echo "done: added ${#missing[@]} key(s) to $SECRETS_FILE (values not shown)."