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