Skip to content

Instantly share code, notes, and snippets.

@2mind
Forked from ghostsquad/secrets.seal.sh
Created September 16, 2021 11:06
Show Gist options
  • Select an option

  • Save 2mind/7d214433f975139ab2a2d1dbcf88a29f to your computer and use it in GitHub Desktop.

Select an option

Save 2mind/7d214433f975139ab2a2d1dbcf88a29f to your computer and use it in GitHub Desktop.

Revisions

  1. @ghostsquad ghostsquad created this gist Aug 28, 2020.
    97 changes: 97 additions & 0 deletions secrets.seal.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,97 @@
    #! /usr/bin/env bash

    set -Eeuo pipefail

    scripts_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
    source "${scripts_dir}/functions.sh"

    test_jq
    test_yq
    test_kubeseal
    test_jsonnet

    component="${1}"
    debug "component: ${component}"

    environment_name=$(read_config environmentName)
    sealed_secret_scope=$(read_config kubernetes.sealedSecretScope)
    sealed_secrets_controller_name=$(read_config kubernetes.sealedSecretsControllerName)
    sealed_secrets_controller_namespace=$(read_config kubernetes.sealedSecretsControllerNamespace)
    kubernetes_namespace=$(read_config "${component}.namespace")
    kube_api_server=$(read_config kubernetes.apiServer)

    secret_jsonnet_file="${deploy_dir}/lib/kubernetes/secret.jsonnet"

    secrets_manager_secret_tmp_file="${my_temp_dir}/secretsmanager_secret.json"
    "${scripts_dir}/secretsmanager.get.sh" "${component}" > "${secrets_manager_secret_tmp_file}"
    secret_tmp_file="${my_temp_dir}/secret.json"

    $JSONNET --output-file "${secret_tmp_file}" \
    \
    --tla-str SEALED_SECRET_SCOPE="${sealed_secret_scope}" \
    --tla-str NAME_PREFIX="${component}" \
    --tla-code STRING_DATA="$(cat "${secrets_manager_secret_tmp_file}")" \
    \
    "${secret_jsonnet_file}" \

    deploy_env_dir="${deploy_dir}/environments/${environment_name}"
    sealed_secret_file="${deploy_env_dir}/environments/${environment_name}/${component}-sealed-secret.jsonnet"

    create_sealed_secret() {
    log "πŸ”’ Sealing secret..."
    log "πŸ”’ Kube ApiServer: ${kube_api_server}"
    log "πŸ”’ Scope: ${sealed_secret_scope}"
    log "πŸ”’ Namespace: ${kubernetes_namespace}"
    sealed_secret_contents=$(
    $KUBESEAL \
    --scope "${sealed_secret_scope}" \
    --namespace "${kubernetes_namespace}" \
    --controller-name "${sealed_secrets_controller_name}" \
    --controller-namespace "${sealed_secrets_controller_namespace}" \
    --server "${kube_api_server}" \
    -o json \
    < "${secret_tmp_file}"
    )
    echo "${sealed_secret_contents}" | cat "${repo_dir}/do-not-edit-header.txt" - > "${sealed_secret_file}"
    log "✍️ Created ${sealed_secret_file}"
    log "πŸ˜€ This file is SAFE to check into git!"
    log "${green}βœ”${reset} Seal Secret Created Successfully!"
    exit 0
    }

    # https://github.com/bitnami-labs/sealed-secrets/issues/376
    # sealed secrets are encrypted with a random salt each time
    # so when reencrypting, the encryptedData will change even if the original value does not
    # since that was a bit surprising during my normal workflow, I've implemented
    # a check to compare the secret sha before regenerating the sealed secret
    #
    # there is a security concern here, that an attacker would know the value of the secret sha
    # regardless of the encrypted string. This could make it easier to guess or attack
    #
    # this risk is mitigated though because these encrypted secrets are only ever stored in
    # private github repos

    # secret name includes md5 of the data
    # so if the secret is updated, the name will be updated
    debug "getting current secret name..."
    debug "$(cat "${secret_tmp_file}")"
    current_secret_name=$($JQ -r '.metadata.name' "${secret_tmp_file}")

    debug "getting existing secret name..."
    if [ -r "${sealed_secret_file}" ]; then
    existing_secret_name=$(jsonnet "${sealed_secret_file}" | jq -r '.spec.template.metadata.name')
    debug "found existing secret name: ${existing_secret_name}"
    if [ "${FORCE_CREATE:-0}" = "0" ] && [ "${existing_secret_name}" = "${current_secret_name}" ]; then
    log "πŸ“ Secret matches, stopping early..."
    log "${green}βœ”${reset} Sealed Secret Verified!"
    exit 0
    else
    create_sealed_secret
    fi
    else
    create_sealed_secret
    fi

    # two spaces here is not a mistake. Not all emojis have
    # the correct spacing to make it show up correct
    log "${green}βœ”${reset} Done Editing Secrets!"