Skip to content

Instantly share code, notes, and snippets.

@StevenACoffman
Created September 27, 2018 21:48
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
Rotate Github Personal Access Keys
#!/bin/bash
TOKEN_UUID=$(uuidgen)
if [ -z ${GITHUB_USERID+x} ]; then
echo "GITHUB_USERID is unset, exitting";
exit 1
else
echo "GITHUB_USERID is set to '$GITHUB_USERID'"
fi
if [ -z ${GITHUB_AUTH_TOKEN_ID+x} ]; then
echo "GITHUB_AUTH_TOKEN_ID is unset, so cannot proceed.";
else
echo "GITHUB_AUTH_TOKEN_ID is already set, so rotating personal access token"
GITHUB_URL="https://api.github.com/authorizations"
# store the whole response with the status at the and
HTTP_RESPONSE=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" \
--user "${GITHUB_USERID}" \
--data '{"scopes":["repo"],"note":"Rotate-Creds-Demo'"${TOKEN_UUID}"'"}' \
$GITHUB_URL)
# extract the body
HTTP_BODY=$(echo "$HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
# extract the status
HTTP_STATUS=$(echo "$HTTP_RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
# print the body
echo "$HTTP_BODY"
# example using the status
if [ $HTTP_STATUS -eq 401 ]; then
echo "Recieved 401, so trying again with Multifactor Auth OTP"
echo -n "Enter Multi-Factor Auth code for $GITHUB_USERID: "
read -s GITHUB_OTP
echo ""
HTTP_RESPONSE=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" \
-H "X-GitHub-OTP: ${GITHUB_OTP}" \
--user "${GITHUB_USERID}" \
--data '{"scopes":["repo"],"note":"Rotate-Creds-Demo'"${TOKEN_UUID}"'"}' \
$GITHUB_URL)
# extract the body
HTTP_BODY=$(echo "$HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
# extract the status
HTTP_STATUS=$(echo "$HTTP_RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
fi
if [ ! $HTTP_STATUS -eq 201 ]; then
echo "Error [HTTP status: $HTTP_STATUS]"
echo "RESPONSE:"
echo "$HTTP_BODY"
exit 1
fi
#Note: Do not overwrite existing variables yet
GITHUB_NEW_AUTH_TOKEN=$(echo "$HTTP_BODY" | jq -r .token)
GITHUB_NEW_AUTH_TOKEN_ID=$(echo "$HTTP_BODY" | jq -r .id)
GITHUB_NEW_AUTH_TOKEN_NOTE=$(echo "$HTTP_BODY" | jq -r .note)
echo "RESPONSE:"
echo "$HTTP_BODY"
echo 'export GITHUB_AUTH_TOKEN="'"$GITHUB_NEW_AUTH_TOKEN"'"' > secret_token.sh
echo 'export GITHUB_AUTH_TOKEN_ID="'"$GITHUB_NEW_AUTH_TOKEN_ID"'"' >> secret_token.sh
echo 'export GITHUB_AUTH_TOKEN_NOTE="'"$GITHUB_NEW_AUTH_TOKEN_NOTE"'"' >> secret_token.sh
chmod u+x secret_token.sh
echo "Wrote new GITHUB_AUTH_TOKEN to secret_token.sh"
HTTP_RESPONSE=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" \
--user "${GITHUB_USERID}" \
-X DELETE "${GITHUB_URL}/${GITHUB_AUTH_TOKEN_ID}")
# extract the body
HTTP_BODY=$(echo "$HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
# extract the status
HTTP_STATUS=$(echo "$HTTP_RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
# example using the status
if [ $HTTP_STATUS -eq 401 ]; then
echo "Recieved 401, so trying again with Multifactor Auth OTP"
echo -n "Enter Multi-Factor Auth code for $GITHUB_USERID: "
read -s GITHUB_OTP
echo ""
HTTP_RESPONSE=$(curl --silent --write-out "HTTPSTATUS:%{http_code}" \
-H "X-GitHub-OTP: ${GITHUB_OTP}" \
--user "${GITHUB_USERID}" \
-X DELETE "${GITHUB_URL}/${GITHUB_AUTH_TOKEN_ID}")
# extract the body
HTTP_BODY=$(echo "$HTTP_RESPONSE" | sed -e 's/HTTPSTATUS\:.*//g')
# extract the status
HTTP_STATUS=$(echo "$HTTP_RESPONSE" | tr -d '\n' | sed -e 's/.*HTTPSTATUS://')
fi
if [ ! $HTTP_STATUS -eq 204 ]; then
echo "Error [HTTP status: $HTTP_STATUS]"
echo "RESPONSE:"
echo "$HTTP_BODY"
exit 1
fi
echo "Successfully deleted old github personal access tokens"
git ignore secret_token.sh
echo "Git ignored secret_token.sh"
fi
@StevenACoffman
Copy link
Author

@karlw00t I've used both secrets manager and parameter store, and I've seen that code. My use case was handling the tricky interaction with the github api, which that code doesn't address AFAICT.

@reveller
Copy link

reveller commented Aug 3, 2020

@StevenACoffman Were you ever able to solve this? I am in a very similar situation where I need to be able to use a service account to generate GitHub access tokens for rotation. I am planning to use AWS Secrets Manager and a rotation Lambda to perform the rotation. Having trouble with the GitHub side of things.

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