Skip to content

Sysadmins ​

Sysadmins hold admin rights over the repositories and the cloud, and keep the organizations' credentials. On top of the contributor setup, they meet stricter security requirements and add three tools: the Google Cloud CLI, OpenTofu and Bitwarden.

Security requirements ​

  • A FIDO2 security key, with a backup. Your SSH keys, for GitHub logins and commit signing, live on a hardware key, as set up below. Key files are not allowed.
  • Nothing open when you leave. Set up connection sharing. Close the connection and unplug your security key whenever you leave your machine, since its signing key needs no touch.
  • Elevated scopes for one task only. Keep your gh session on its default scopes. Add admin:org or another for a single run, then remove it.
  • No credential in clear. Keep tokens in the CLI's encrypted store, never in a file or your shell history.

GitHub with a security key ​

This replaces the key file of the contributor setup. Each security key holds two SSH keys. The authentication key asks for a touch on every new connection to GitHub. The signing key signs without one, so commits, rebases and agents never wait on you.

Name the key ​

Set the key's file name and the title GitHub shows for it. Start with your main key. For a backup, add _backup to the file name and use backup in the title.

bash
KEY_FILE=~/.ssh/id_ed25519_sk
KEY_TITLE="$(hostname) main"

Create the SSH keys ​

Plug the security key in. On macOS, run brew install openssh first, as the system OpenSSH lacks security key support. Leave the signing key's passphrase empty, or every commit asks for it.

bash
ssh-keygen -t ed25519-sk -C "$(git config user.email)" -f "$KEY_FILE"
ssh-keygen -t ed25519-sk -O no-touch-required -C "$(git config user.email)" -f "${KEY_FILE}_signing"

Register them on GitHub ​

gh asks for a temporary permission to upload the keys.

bash
gh auth refresh -h github.com -s admin:public_key,admin:ssh_signing_key
gh ssh-key add "$KEY_FILE.pub" --type authentication --title "$KEY_TITLE"
gh ssh-key add "${KEY_FILE}_signing.pub" --type signing --title "$KEY_TITLE"
gh auth refresh -h github.com --remove-scopes admin:public_key,admin:ssh_signing_key

Use them on this machine ​

List the authentication key as an IdentityFile under Host github.com in ~/.ssh/config. With a backup, the entry reads:

text
Host github.com
    IdentityFile ~/.ssh/id_ed25519_sk
    IdentityFile ~/.ssh/id_ed25519_sk_backup

Then add the signing key to your allowed signers:

bash
SIGNERS=$(git config --global gpg.ssh.allowedSignersFile)
echo "$(git config user.email) namespaces=\"git\" $(cat "${KEY_FILE}_signing.pub")" >> "$SIGNERS"

Repeat from Name the key for each backup.

Sign with your main key ​

bash
git config --global user.signingkey ~/.ssh/id_ed25519_sk_signing.pub

When you work with a backup, point user.signingkey at its signing key instead. Last, delete the contributor setup's key file from your GitHub account, both its authentication and signing entries.

Duties ​

Set up the bot for an organization ​

Each organization has its own Agent App. It posts the bot comments and runs the governance workflows, such as the merge gate. These steps serve a new organization or a re-created App.

  1. Register a GitHub App on the organization, with the permissions of an existing Agent App, which this prints. Disable the webhook, then install the App on every repository.

    bash
    ORG=a-novel
    APP=anovelbot-agent
    gh api "orgs/$ORG/installations" \
      --jq ".installations[] | select(.app_slug == \"$APP\") | .permissions"
  2. Store the App's client ID as the organization Actions variable AGENT_BOT_CLIENT_ID.

  3. Generate a private key, and store it as AGENT_BOT_PRIVATE_KEY in the organization's project of Bitwarden, a-novel or a-novel-kit. Delete the downloaded file.

  4. Apply the settings with --all, which copies the key into each repository's governance environment.

  5. Comment on a scratch pull request to check.