Skip to content

Instantly share code, notes, and snippets.

@magnetikonline
Last active September 24, 2024 04:37
Show Gist options
  • Save magnetikonline/391a8632c664c2a9f7940bf9f957e83d to your computer and use it in GitHub Desktop.
Save magnetikonline/391a8632c664c2a9f7940bf9f957e83d to your computer and use it in GitHub Desktop.
Import all GPG keys for GitHub organisation users.

Import all GPG keys for GitHub organisation users

Fetches a GitHub organisation member list and proceeds to gpg --import public GPG key(s) for each member associated against their profile.

Requires:

  • curl for GitHub API calls
  • jq for parsing GitHub REST API responses
  • and (obviously) gpg

Usage

Create a GitHub personal access token (classic or fine-grained) with read access to organisation members:

  • Classic token: read:org scope.
  • Fine-grained token: Members Read-only organization permission.

Next, execute the script:

export GITHUB_TOKEN="INSERT_TOKEN_VALUE_HERE"
ORG_NAME="INSERT_GITHUB_ORG" ./import-github-gpg.sh

Done!

#!/bin/bash -e
function exitError {
echo "Error: $1" >&2
exit 1
}
function main {
local IFS=$'\n'
if [[ ! -x $(command -v jq) ]]; then
exitError "unable to locate jq"
fi
if [[ -z $GITHUB_TOKEN ]]; then
exitError "expected GITHUB_TOKEN not found"
fi
if [[ -z $ORG_NAME ]]; then
exitError "expected ORG_NAME not found"
fi
local fetchPage=1
local hasResult=:
while [[ $hasResult ]]; do
# pull list page of members for GitHub organisation
local response=$(
curl \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer $GITHUB_TOKEN"\
--silent \
"https://api.github.com/orgs/$ORG_NAME/members?page=$fetchPage"
)
# for each member profile URL, attempt to pull and import public GPG key(s)
hasResult=
local profileUrl
for profileUrl in $(echo "$response" | jq --raw-output ".[].html_url"); do
hasResult=:
local response=$(curl --silent "$profileUrl.gpg")
if [[ $response =~ Note:\ This\ user\ hasn\'t\ uploaded\ any\ GPG\ keys\. ]]; then
echo "$profileUrl - skipping (no GPG key)"
else
echo "$profileUrl - importing key"
echo "$response" | gpg --import
echo
fi
done
fetchPage=$((fetchPage+1))
done
echo
echo "Finished"
}
main
@falsefalse
Copy link

excellent, works like a charm in 2023, thank you

@corani
Copy link

corani commented Sep 24, 2024

Using GitHub CLI I could do the same with:

#!/bin/bash

if [ "$1" == "" ]; then
    echo "Usage: $0 <org>"
    exit 1
fi

ORG=$1
echo "Importing GPG keys for all members of ${ORG}..."

for LOGIN in $(gh api --paginate "orgs/${ORG}/members" -q '.[].login'); do
    echo "Checking: ${LOGIN}"

    KEY=$(gh api "users/${LOGIN}/gpg_keys" -q '.[].raw_key')
    if [ "$KEY" != "" ]; then
        echo "$KEY" | gpg --import
    fi
done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment