github.com/m-lab/locate@v0.17.6/management/create_jwt_keys_and_secrets.sh (about) 1 #!/bin/bash 2 # 3 # create_jwt_keys_and_secrets.sh generates JWT signer and verify keys and 4 # uploads them as secrets to the Google Secret Manager. 5 6 set -eu 7 8 PROJECT=${1:?please provide project} 9 KEYID=${2:?please provide keyid} 10 11 LOCATE_PRIVATE_KEY=jwk_sig_EdDSA_locate_${KEYID} 12 LOCATE_SECRET_NAME=locate-service-signer-key 13 MONITORING_PUBLIC_KEY=jwk_sig_EdDSA_monitoring_${KEYID}.pub 14 MONITORING_SECRET_NAME=locate-monitoring-service-verify-key 15 16 GAE_SERVICE_ACCOUNT="serviceAccount:${PROJECT}@appspot.gserviceaccount.com" 17 18 which jwk-keygen &> /dev/null || \ 19 ( echo "Run: go get gopkg.in/square/go-jose.v2/jwk-keygen" && \ 20 exit 1 ) 21 22 23 # Checks if a secret exists or not. 24 function secretExists() { 25 local name=$1 26 existing_secret=$( 27 gcloud secrets list --filter "name:${name}" \ 28 --format "value(name)" \ 29 --project "${PROJECT}" 30 ) 31 if [[ -n $existing_secret ]]; then 32 echo "Secret '${name}' already exists." 33 return 0 34 else 35 return 1 36 fi 37 } 38 39 function addSecret() { 40 local name=$1 41 local file=$2 42 gcloud secrets create "${name}" \ 43 --data-file "${file}" \ 44 --project "${PROJECT}" 45 } 46 47 function addNewVersion() { 48 local name=$1 49 local file=$2 50 local disable=$3 51 gcloud secrets versions add "${name}" \ 52 --data-file "${file}" \ 53 --project "${PROJECT}" 54 55 if [[ $disable != "disable" ]]; then 56 return 57 fi 58 59 version=$( 60 gcloud secrets versions list "${name}" --limit 1 \ 61 --format "value(name)" \ 62 --project "${PROJECT}" 63 ) 64 65 gcloud secrets versions disable "${version}" \ 66 --secret "${name}" \ 67 --project "${PROJECT}" 68 } 69 70 # Checks if an IAM policy binding already exists for the specified secret name. 71 function iamPolicyBindingExists() { 72 local name=$1 73 if gcloud secrets get-iam-policy "${name}" \ 74 --project "${PROJECT}" \ 75 | grep --quiet "${GAE_SERVICE_ACCOUNT}"; then 76 echo "IAM policy binding already exists for secret: ${name}" 77 return 0 78 else 79 return 1 80 fi 81 } 82 83 # Adds an IAM policy binding for the specified secret name, allowing the default 84 # AppEngine service account to access the secret. 85 function addIAMPolicyBinding() { 86 local name=$1 87 gcloud secrets add-iam-policy-binding ${name} \ 88 --member "${GAE_SERVICE_ACCOUNT}" \ 89 --role "roles/secretmanager.secretAccessor" \ 90 --project "${PROJECT}" 91 } 92 93 # Create JWT signer key. 94 if [[ ! -f ${LOCATE_PRIVATE_KEY} ]] ; then 95 echo "Creating private locate signer key: ${LOCATE_PRIVATE_KEY}" 96 jwk-keygen --use=sig --alg=EdDSA --kid=locate_${KEYID} 97 fi 98 99 # Create secret for the JWT signer key. 100 if ! secretExists "${LOCATE_SECRET_NAME}"; then 101 addSecret "${LOCATE_SECRET_NAME}" "${LOCATE_PRIVATE_KEY}" 102 else 103 cat <<EOF 104 105 Would you like to create a new version of this secret? 106 107 WARNING: the new secret version will be disabled. Consult the README file in 108 this directory for further instructions on rotating keys. Do not enable the new 109 secret version until you have completed all the steps in the documentation. The 110 public key (.pub extension) will be found in this directory after this script 111 has completed. 112 113 Are you sure you want to continue? [y/N]: 114 EOF 115 read addversion 116 if [[ "${addversion}" == "y" ]]; then 117 addNewVersion "${LOCATE_SECRET_NAME}" "${LOCATE_PRIVATE_KEY}" "disable" 118 else 119 exit 0 120 fi 121 fi 122 123 if ! iamPolicyBindingExists "${LOCATE_SECRET_NAME}"; then 124 addIAMPolicyBinding "${LOCATE_SECRET_NAME}" 125 fi 126 127 # Create JWT monitoring keys. 128 if [[ ! -f ${MONITORING_PUBLIC_KEY} ]] ; then 129 echo "Creating monitoring keys: ${MONITORING_PUBLIC_KEY}" 130 jwk-keygen --use=sig --alg=EdDSA --kid=monitoring_${KEYID} 131 fi 132 133 # Create secret for the JWT monitoring key. 134 if ! secretExists "${MONITORING_SECRET_NAME}"; then 135 addSecret "${MONITORING_SECRET_NAME}" "${MONITORING_PUBLIC_KEY}" 136 else 137 cat <<EOF 138 139 Would you like to create a new version of this secret? 140 141 WARNING: the new secret version will be created for the monitoring verify key, 142 but will do nothing if the corresponding private key is not updated in the 143 script-exporter deployment. See the README of this repo for documentation on 144 rotating monitoring keys. 145 146 Are you sure you want to continue? [y/N]: 147 EOF 148 read addversion 149 if [[ "${addversion}" == "y" ]]; then 150 addNewVersion "${MONITORING_SECRET_NAME}" "${MONITORING_PUBLIC_KEY}" "enable" 151 else 152 exit 0 153 fi 154 fi 155 156 if ! iamPolicyBindingExists "${MONITORING_SECRET_NAME}"; then 157 addIAMPolicyBinding "${MONITORING_SECRET_NAME}" 158 fi