こんにちは,グレンジ Advent Calendar 2024の25日目担当の石川です.
今年は,SOPSの利用例をいくつか紹介したいと思います.
SOPSは,Secrets OPerationSの略称です.
Mozillaが公開している暗号化ツールで、YAML,JSON,ENV,INIとBINARY形式をサポートし,AWS KMS、GCP KMS,Azure Key Vault,age,およびPGPで暗号化する暗号化ファイルのエディターです.
グレンジでは、GCP KMS
をを利用して暗号化しています.
SOPSを利用することで,暗号化したいデータをGitHubなどのリポジトリで安全に管理することができます.
これにより,チーム内で安全に暗号化されたデータを共有したり,CI/CDパイプラインで安全に利用することができます.
基本的な使い方
Cloud KMS(Cloud Key Management)を利用する場合は,次のコマンドでkeyringとkeyを作成します.
PROJECT
は,自身のGCPのプロジェクト名を指定してください.
$ gcloud kms keyrings create sops-keyring \
--location=global \
--project=PROJECT
$ gcloud kms keys create sops-key \
--location=global \
--keyring=sops-keyring \
--purpose=encryption \
--project=PROJECT
sopsの実行ファイルをダウンロードして,実行権限を付与します.
$ curl -Lo sops https://github.com/getsops/sops/releases/download/v3.8.1/sops-v3.8.1.darwin.arm64
$ chmod u+x sops
他のOS,バージョンは,https://github.com/getsops/sops/releasesを参照してください.
以下のような内容で,configファイルとして.sops.yaml
を作成します.
path_regex
には,暗号化したいファイルを正規表現で指定します.
creation_rules:
- path_regex: development
gcp_kms: projects/PORJECT/locations/global/keyRings/sops-keyring/cryptoKeys/sops-key
次に暗号化したいファイルをdevelopment.yaml
として作成します.
title: グレンジ Advent Calendar 2024
url: https://qiita.com/advent-calendar/2024/grenge
次のようなコマンドで暗号化します.
sops --encrypt \
--config .sops.yaml \
development.yaml > development.enc.yaml
暗号化されたファイルは,次のようになります.
title: ENC[AES256_GCM,data:9YIX+tN2OmEe+g/awztiMf1PBrJihQ4XxTpiuBYjAJfj,iv:dKQmXDBhCcVuLPoQ4Z2IJi/V4yCBJdxt1QW0x9xFa3w=,tag:1E9daZW8DyWao94dyoLuqQ==,type:str]
url: ENC[AES256_GCM,data:Ofmcwn6mmfv/T9St79tibxDJllMXqPTG7RgX3VpWw1z6bOrFmIiUA68HjcDT,iv:Cri8ektRfNX+OI8C0wZy04uaFh+KHttY7EX2a82TsC8=,tag:Q71jIB6qKiz4QQmrCIU1Zg==,type:str]
sops:
kms: []
gcp_kms:
- resource_id: projects/PORJECT/locations/global/keyRings/sops-keyring/cryptoKeys/sops-key
created_at: "2024-12-22T14:29:52Z"
enc: CiQAUsJ80Roob/ap3jr9HMpwB4nWNJA6rnE8TgMLr+URf1zrWxISSQDfbxQ3Ps4FAreYG5D3800LPc47MOttinERMBWOJlELSWiT3XbTtuYfP1iIZTjgfJ9Nr3NRsY4HWdgkGdDxg38H7+0dVS1iV6U=
azure_kv: []
hc_vault: []
age: []
lastmodified: "2024-12-22T14:29:53Z"
mac: ENC[AES256_GCM,data:ELxroxCUYVWWbAzZTKcKC20HzhyKT+56sAGKpkJxHbD0D+Oy0pwDroQ/BGtkJma2C93/6VTsSwr/3cgBvwwdqaLWMoir2Nn20Nx9h+qusfU+9dQuB08LWB46olF2RxMOR3S0Fc//pLKnOfrDmgO1c7Lhd22HxMglHwDmqhEBBgs=,iv:DA7viPjyV4KaudbrROLB8PsMZc+7HBmNwbTmzdj/EDc=,tag:uA+uRX0Q3yM/57bKUaycHg==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.8.1
暗号化されたファイルから元のファイルを復号化するには,次のようなコマンドを実行します.
build/.toolchain/bin/sops --decrypt
--config .sops.yaml \
development.enc.yaml > development.yaml
GitHub Actionsの環境変数を暗号化する
GitHub Actionsで利用するプラグインもあります.
mozilla-sops-actionを利用することで,GitHub Actionsの環境変数を暗号化することができます.
また,Google CloudのWorkload Identityを利用して,GCPのサービスアカウントを利用する場合にも,SOPSを利用することで,環境変数を暗号化することができます.
GitHubにも,Actions secrets and variables
からsecretを設定することができますが,SOPSを利用することで,ファイルで管理することができます.
ただ,GitHub Actionsで環境変数に設定すると,実行結果で値が表示されてしまうため,::add-mask::
を利用して,値をマスクすることで秘匿することができます.
また,管理はyaml
ファイルで行い,output-typeをbinary
にすることで,容易に環境変数に設定することができます.
# Configure Workload Identity Federation and generate an access token.
- id: auth
name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2.1.7
with:
workload_identity_provider: projects/${{ inputs.project_number }}/locations/global/workloadIdentityPools/${{ inputs.pool }}/providers/${{ inputs.provider }}
service_account: ${{ inputs.service_account }}
# Setup gcloud CLI
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2.1.2
- name: Set up sops
uses: mdgreenwald/mozilla-sops-action@v1.6.0
id: install
- name: Decrypt secrets
run: |
sops --decrypt \
--config .github/actions/secret/.sops.yaml \
--output-type binary \
.github/actions/secret/secret.${{ inputs.environment }}.enc.yaml > .github/actions/secret/secret
shell: bash
- name: Set up development secret variables
run: |
cat .github/actions/secret/secret >> $GITHUB_ENV
sed -e 's/^.*=/::add-mask::/' -e '/^.*<<EOF/ { :a; N; /\nEOF$/!ba; s/^.*<<EOF\n/::add-mask::/; s/\nEOF//; s/%/%25/g; s/\r/%0D/g; s/\n/%0A/g }' .github/actions/secret/secret
shell: bash
Terragruntの変数を暗号化する
Terragruntでも,sops_decrypt_file(file_path)を利用して,SOPSで暗号化されたファイルを復号化することができます.
locals {
secret_vars = yamldecode(sops_decrypt_file(find_in_parent_folders("secrets.yaml")))
}
inputs = merge(
local.secret_vars,
{
# additional inputs
}
)
まとめ
SOPSの利用方法をいくつかご紹介しました.
Secretは,アプリケーションのソースコードやTerraformなどのインフラストラクチャの構成ファイルなどと連携することが多いので,コードに近くに配置しておきたくなります.
ただ,そのまま平文で管理すると,リポジトリが漏洩した場合に大きなリスクになります.
そういったリスク回避のためにSOPSを利用するという手段は,有効な手段の一つです.
また,GitHub ActionsやTerragruntとの連携ができるので,CI/CDパイプラインでの利用も容易です.
今回の内容が少しでも参考になれば幸いです.