Files
small-scripts/scripts/gen-secret
Paul O'Reilly c470867039 Remove URL-unsafe characters from gen-secret charset
Remove ^, +, ~, :, @ from the allowed charset. The ^ character breaks
SQLAlchemy DATABASE_URL parsing, + becomes space in URL query strings,
: and @ are URL delimiters. The remaining charset (A-Za-z0-9._-) is
safe in URLs, database connection strings, YAML, JSON, and shell
without any encoding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 21:29:08 +13:00

64 lines
1.2 KiB
Bash
Executable File

#!/usr/bin/env bash
set -uo pipefail
CHARSET='A-Za-z0-9._\-'
DEFAULT_LENGTH=32
usage() {
cat <<'EOF'
Usage: gen-secret [OPTIONS] [LENGTH]
Generate a cryptographically random string safe for bash, YAML, JSON, and URLs.
Arguments:
LENGTH Number of characters (default: 32)
Options:
-n, --dryrun Preview what would happen
-h, --help Show this help
EOF
}
dryrun=false
length=""
while [[ $# -gt 0 ]]; do
case "$1" in
-h|--help)
usage
exit 0
;;
-n|--dryrun)
dryrun=true
shift
;;
-*)
echo "Error: Unknown option: $1" >&2
exit 1
;;
*)
if [[ -n "$length" ]]; then
echo "Error: Too many arguments" >&2
exit 1
fi
length="$1"
shift
;;
esac
done
length="${length:-$DEFAULT_LENGTH}"
if ! [[ "$length" =~ ^[0-9]+$ ]] || [[ "$length" -le 0 ]]; then
echo "Error: Length must be a positive integer" >&2
exit 1
fi
if $dryrun; then
echo "[dryrun] Would generate a ${length}-character secret from charset: [${CHARSET}]"
exit 0
fi
tr -dc "$CHARSET" < /dev/urandom | head -c "$length"
echo