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
ghsession on its default scopes. Addadmin:orgor 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.
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.
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.
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_keyUse them on this machine
List the authentication key as an IdentityFile under Host github.com in ~/.ssh/config. With a backup, the entry reads:
Host github.com
IdentityFile ~/.ssh/id_ed25519_sk
IdentityFile ~/.ssh/id_ed25519_sk_backupThen add the signing key to your allowed signers:
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
git config --global user.signingkey ~/.ssh/id_ed25519_sk_signing.pubWhen 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
- Manage members: add, promote and offboard them.
- Manage repositories: create them and apply their settings with
repo update. - Operate production: follow the infra runbooks.
- Answer a compromise: when an account, a key or a token leaks, cut the attacker off and recover.
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.
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.
bashORG=a-novel APP=anovelbot-agent gh api "orgs/$ORG/installations" \ --jq ".installations[] | select(.app_slug == \"$APP\") | .permissions"Store the App's client ID as the organization Actions variable
AGENT_BOT_CLIENT_ID.Generate a private key, and store it as
AGENT_BOT_PRIVATE_KEYin the organization's project of Bitwarden,a-novelora-novel-kit. Delete the downloaded file.Apply the settings with
--all, which copies the key into each repository's governance environment.Comment on a scratch pull request to check.