#!/usr/bin/env bash # Provision Forgejo admin PAT into OpenBao (CCR-2026-0006). # Usage: forgejo-admin-pat-provision.sh /path/to/pat-file # Never pass the PAT on argv; use a mode-0600 file with a single-line token. set -euo pipefail PAT_FILE="${1:?usage: forgejo-admin-pat-provision.sh /path/to/pat-file (mode 0600, single line)}" BAO_PATH="${FORGEJO_ADMIN_BAO_PATH:-platform/workloads/forgejo/forgejo-admin}" API_USER="${FORGEJO_ADMIN_API_USER:-tegwick}" API_BASE_URL="${FORGEJO_ADMIN_API_BASE_URL:-https://forgejo.coulomb.social}" TOKEN_SCOPES="${FORGEJO_ADMIN_TOKEN_SCOPES:-read:package,write:package,read:repository,write:repository,read:user,write:user}" GENERATED_AT="$(date -u +%Y-%m-%dT%H:%M:%SZ)" if [[ ! -f "${PAT_FILE}" ]]; then echo "ERROR: PAT file not found: ${PAT_FILE}" >&2 exit 1 fi if [[ "$(stat -c '%a' "${PAT_FILE}")" != "600" ]]; then echo "ERROR: PAT file must be mode 0600" >&2 exit 1 fi command -v bao >/dev/null 2>&1 || { echo "ERROR: bao CLI required" >&2; exit 1; } # Smoke without printing token TOKEN="$(<"${PAT_FILE}")" code="$(curl -sS -o /dev/null -w '%{http_code}' \ -H "Authorization: token ${TOKEN}" \ "${API_BASE_URL}/api/v1/user")" if [[ "${code}" != "200" ]]; then echo "ERROR: Forgejo API smoke failed (HTTP ${code})" >&2 exit 1 fi unset TOKEN bao kv put "${BAO_PATH}" \ "API_TOKEN=@${PAT_FILE}" \ "API_USER=${API_USER}" \ "API_BASE_URL=${API_BASE_URL}" \ "TOKEN_SCOPES=${TOKEN_SCOPES}" \ "GENERATED_AT=${GENERATED_AT}" bao kv metadata get "${BAO_PATH}" >/dev/null echo "OK: ${BAO_PATH} provisioned (field presence verified; values not printed)"