Add --gh-keys so sshd setup can run without prompts (#7086)

* Add --gh-keys so sshd setup can run without prompts

Grabbing keys from GitHub was reachable only through the interactive menu: pick
"Grab key from GitHub", then type the username into a second prompt. So the one
path that needs no secret pasted around was also the one path a script could not
take, and setting a machine up over ssh or from a provisioning run meant falling
back to --key with a key copied by hand.

--gh-keys <username> takes the same path the prompt did. The fetch and authorize
logic is unchanged and now shared, with the prompt reduced to asking for the
username and handing it over.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Reject a missing --gh-keys username before setting anything up

The username was only checked for being absent entirely, and only after the
server was installed and the firewall opened. So `--gh-keys=` with an unset
variable behind it configured the machine and then dropped into the interactive
menu, and `--gh-keys --help` took --help as the username and set the server up
on its way to failing the fetch -- a help flag that changes the system.

Check the value where it is parsed, and reject one that is empty or shaped like
an option.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Omarchybot
2026-08-16 10:14:42 +02:00
committed by GitHub
co-authored by Claude Opus 5
parent 7be59e1f4b
commit 33cda8b602
+53 -15
View File
@@ -1,32 +1,62 @@
#!/bin/bash #!/bin/bash
# omarchy:summary=Set up the OpenSSH server, open the firewall, and authorize an SSH key # omarchy:summary=Set up the OpenSSH server, open the firewall, and authorize an SSH key
# omarchy:args=[--key=<public-key>] # omarchy:args=[--key=<public-key>] [--gh-keys <github-username>]
# omarchy:examples=omarchy-setup-security-sshd | omarchy-setup-security-sshd --key="ssh-ed25519 AAAA... user@host" # omarchy:examples=omarchy-setup-security-sshd | omarchy-setup-security-sshd --gh-keys dhh | omarchy-setup-security-sshd --key="ssh-ed25519 AAAA... user@host"
# omarchy:requires-sudo=true # omarchy:requires-sudo=true
set -e set -e
AUTHORIZED_KEYS="$HOME/.ssh/authorized_keys" AUTHORIZED_KEYS="$HOME/.ssh/authorized_keys"
KEY="" KEY=""
GITHUB_USER=""
for arg in "$@"; do # Checked while parsing, before anything is installed or opened: an empty or
case "$arg" in # option-shaped username otherwise falls through to the interactive menu having
--key=*) KEY="${arg#--key=}" ;; # already changed the machine, and `--gh-keys --help` would take --help as the
# username and set the server up on its way to failing.
require_github_user() {
if [[ -z $1 || $1 == -* ]]; then
echo "omarchy-setup-security-sshd: --gh-keys needs a GitHub username." >&2
exit 2
fi
}
while (( $# > 0 )); do
case "$1" in
--key=*) KEY="${1#--key=}" ;;
--gh-keys=*)
GITHUB_USER="${1#--gh-keys=}"
require_github_user "$GITHUB_USER"
;;
--gh-keys)
shift
GITHUB_USER="${1:-}"
require_github_user "$GITHUB_USER"
;;
-h | --help) -h | --help)
echo "Usage: omarchy-setup-security-sshd [--key=<public-key>]" echo "Usage: omarchy-setup-security-sshd [--key=<public-key>] [--gh-keys <github-username>]"
echo echo
echo "Sets up the OpenSSH server, opens the SSH port in the UFW firewall," echo "Sets up the OpenSSH server, opens the SSH port in the UFW firewall,"
echo "and authorizes an SSH key (from GitHub, pasted, or passed via --key)." echo "and authorizes an SSH key (from GitHub, pasted, or passed via --key)."
echo
echo "Passing --key or --gh-keys skips the prompts, so the command can run"
echo "unattended from a script or a fresh machine's first login."
exit 0 exit 0
;; ;;
*) *)
echo "omarchy-setup-security-sshd: unknown option '$arg'. Try --help." >&2 echo "omarchy-setup-security-sshd: unknown option '$1'. Try --help." >&2
exit 2 exit 2
;; ;;
esac esac
shift
done done
if [[ -n $KEY && -n $GITHUB_USER ]]; then
echo "omarchy-setup-security-sshd: pass either --key or --gh-keys, not both." >&2
exit 2
fi
setup_sshd() { setup_sshd() {
echo "Installing and starting the OpenSSH server..." echo "Installing and starting the OpenSSH server..."
omarchy-pkg-add openssh omarchy-pkg-add openssh
@@ -70,13 +100,7 @@ authorize_key() {
} }
authorize_keys_from_github() { authorize_keys_from_github() {
local username keys added=0 local username="$1" keys added=0
username=$(gum input --prompt "GitHub username> " --placeholder "dhh") || exit 1
if [[ -z $username ]]; then
echo -e "\e[31mNo GitHub username given.\e[0m" >&2
exit 1
fi
echo "Fetching keys from https://github.com/$username.keys..." echo "Fetching keys from https://github.com/$username.keys..."
if ! keys=$(curl -fsSL "https://github.com/$username.keys") || [[ -z $keys ]]; then if ! keys=$(curl -fsSL "https://github.com/$username.keys") || [[ -z $keys ]]; then
@@ -95,6 +119,18 @@ authorize_keys_from_github() {
fi fi
} }
prompt_for_github_user() {
local username
username=$(gum input --prompt "GitHub username> " --placeholder "dhh") || exit 1
if [[ -z $username ]]; then
echo -e "\e[31mNo GitHub username given.\e[0m" >&2
exit 1
fi
authorize_keys_from_github "$username"
}
authorize_pasted_key() { authorize_pasted_key() {
local key local key
@@ -115,9 +151,11 @@ open_firewall
echo echo
if [[ -n $KEY ]]; then if [[ -n $KEY ]]; then
authorize_key "$KEY" || exit 1 authorize_key "$KEY" || exit 1
elif [[ -n $GITHUB_USER ]]; then
authorize_keys_from_github "$GITHUB_USER"
else else
case $(gum choose "Grab key from GitHub" "Paste key manually" --header "How would you like to add your SSH key?") in case $(gum choose "Grab key from GitHub" "Paste key manually" --header "How would you like to add your SSH key?") in
"Grab key from GitHub") authorize_keys_from_github ;; "Grab key from GitHub") prompt_for_github_user ;;
"Paste key manually") authorize_pasted_key ;; "Paste key manually") authorize_pasted_key ;;
*) exit 1 ;; *) exit 1 ;;
esac esac