Skip to content

Instantly share code, notes, and snippets.

@mvanholsteijn
Last active August 15, 2025 14:01
Show Gist options
  • Save mvanholsteijn/3725a546fa52c014f7a828616f7f1d3f to your computer and use it in GitHub Desktop.
Save mvanholsteijn/3725a546fa52c014f7a828616f7f1d3f to your computer and use it in GitHub Desktop.
add-service-account-key - adds a key to a google cloud service account and encrypt the result with your public key
#!/bin/bash
#
# NAME
# add_service_account_key - adds a key to a google cloud service
# account and encrypt the result with your public key
#
# SYNOPSIS
# add-service-account-key <service-account-email> <public key pem>
#
# DESCRIPTION
# Adds a new service account key to the service account. The newly
# created key is encrypted using a generated data encrypt key. The DEK
# is encrypted with the public key.
#
# Both encrypted files are stored in the zip file encrypted.zip
#
#
function add_service_account_key() {
SERVICE_ACCOUNT="$1"
PROJECT=$(echo "$SERVICE_ACCOUNT" | cut -d'@' -f2 | cut -d'.' -f1)
PUBLIC_KEY="$2"
PUBLIC_KEY_FILE=$(mktemp)
echo "$PUBLIC_KEY" > "$PUBLIC_KEY_FILE"
# convert an RSA public key to a normal public key
if grep -q "RSA PUBLIC" "$PUBLIC_KEY_FILE"; then
echo "$PUBLIC_KEY" | openssl rsa -pubin -RSAPublicKey_in -pubout > "$PUBLIC_KEY_FILE"
fi
# generate data encryption key
KEY_FILE=$(mktemp)
chmod 0600 "$KEY_FILE"
openssl rand 214 > "$KEY_FILE"
gcloud iam service-accounts keys create - \
"--iam-account=$SERVICE_ACCOUNT" \
"--project=$PROJECT" --quiet | \
openssl \
aes-256-cbc -e -pbkdf2 -kfile $KEY_FILE > sa-key.json.encrypted
openssl rsautl -encrypt -pubin -inkey "$PUBLIC_KEY_FILE" \
-in "$KEY_FILE" -out key.bin.encrypted
zip encrypted.zip sa-key.json.encrypted key.bin.encrypted
rm -f "$KEY_FILE" sa-key.json.encrypted key.bin.encrypted
cat <<!
#
# to decrypt the public service-account key file, type:
unzip encrypted.zip
#
# Decrypt the data encryption key, assuming you provided the public key of ~/.ssh/id_rsa
openssl pkeyutl -decrypt -inkey ~/.ssh/id_rsa -in key.bin.encrypted -out key.bin
#
# Decrypt to service account key file with the decrypted key
openssl aes-256-cbc -d -pbkdf2 -in sa-key.json.encrypted -out sa-key.json -kfile key.bin
!
}
if [[ $# -ne 2 ]]; then
echo "Usage: $0 <service-account-email> <public-key>" >&2
exit 1
fi
add_service_account_key "$1" "$2"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment