# Secret generation. Secrets are generated, never requested from the user, # and never printed. URL-safe alphanumerics only (avoid shell/URL/env quoting # pitfalls in .env and connection strings). # # Note: we deliberately avoid `... | head -c N` here. Under `set -o pipefail` # head closes the pipe early, the upstream producer dies with SIGPIPE, and the # whole script would abort. Instead we read a full chunk and slice in bash. # gen_secret [LENGTH] — alphanumeric token, default 32 chars. Sets SECRET. gen_secret() { local len="${1:-32}" raw="" while ((${#raw} < len)); do # openssl finishes before tr reads EOF — no early pipe close. raw+="$(openssl rand -base64 $((len + 16)) | LC_ALL=C tr -dc 'A-Za-z0-9')" done SECRET="${raw:0:len}" } # gen_hex BYTES — hex string (e.g. JWT secret). Sets SECRET. gen_hex() { SECRET="$(openssl rand -hex "${1:-32}")" }