rotate_secrets.sh 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #!/bin/bash
  2. # Copyright 2024 Google LLC
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. # Script to re-encrypt stored secrets with a new cryptographic key.
  16. #
  17. # Usage:
  18. # rotate_secrets.sh <current_secret_key> <new_secret_key> <secrets_directory>
  19. #
  20. # Arguments:
  21. # <current_secret_key>: The current secret key.
  22. # <new_secret_key>: The new secret key.
  23. # <directory>: The directory to rotate encrypted files in.
  24. #
  25. # Note:
  26. # A new cryptographic key can be generated with `openssl rand -base64 32`.
  27. #
  28. if [[ $# -ne 3 ]]; then
  29. cat 1>&2 <<EOF
  30. Error: Expected exactly 3 arguments.
  31. USAGE: *** [current_secret_key]
  32. USAGE: *** [new_secret_key]
  33. USAGE: $3 [secrets_directory]
  34. EOF
  35. exit 1
  36. fi
  37. current_secret_key=$1
  38. new_secret_key=$2
  39. secrets_directory=$3
  40. if [[ ! -d "$secrets_directory" ]]; then
  41. echo "Error: The given directory does not exist."
  42. exit 1
  43. fi
  44. # Search for encrypted files in the given directory.
  45. files=$(find "$secrets_directory" -name "*.gpg")
  46. # For each file, decrypt the encrypted contents and re-encrypt with the new
  47. # secret.
  48. for encrypted_file in $files; do
  49. echo "Decrypting $encrypted_file"
  50. scripts_dir=$(dirname "$0")
  51. # The decrypted file's path will match the encrypted file's path, minus the
  52. # trailing `.gpg` extension.
  53. decrypted_file=${encrypted_file%.*}
  54. source "$scripts_dir/decrypt_gha_secret.sh" \
  55. "$encrypted_file" "$decrypted_file" "$current_secret_key"
  56. if [ ! -f "$decrypted_file" ]; then
  57. echo "Error: The file could not be decrypted: $encrypted_file"
  58. exit 1
  59. fi
  60. # Remove current encrypted file or else re-encryption will fail due to the
  61. # gpg file already existing. The below script invocation will re-encrypt
  62. # the file to the `encrypted_file` path.
  63. rm "$encrypted_file"
  64. echo "Encrypting with new secret to $encrypted_file"
  65. source "$scripts_dir/encrypt_gha_secret.sh" "$decrypted_file" "$new_secret_key"
  66. if [ ! -f "$encrypted_file" ]; then
  67. echo "Error: The file could not be encrypted: $decrypted_file"
  68. exit 1
  69. fi
  70. # Cleanup the decrypted file now that it's been re-encrypted.
  71. rm "$decrypted_file"
  72. done