私のアプリケーションを実行するには、データベースの認証情報、APIの認証情報など、たくさんのシークレットが必要です。GoogleApp Engineスタンダードで実行していますJava 11.これらのシークレットが必要です環境変数として、またはアプリケーションへの引数として、フレームワークがそれらを取得して、それに応じて接続を確立できるようにします。私の特定のフレームワークはSpring Bootですが、DjangoとRailsおよび他の多くは同じメソッドを使用しています。
これを行う最良の方法は何ですか?
この質問に対する答えの1つは se Google Cloud Key Management です。これは有望に見えますが、これらの値をApp Engineの環境変数に変換する方法を理解できません。出来ますか? サーバー間アプリケーションの認証の設定 を読みましたが、App Engineでシークレットを環境変数に変換する方法に関する指示がありません(私はそれを欠落していますか?)。
私が見た他の選択肢には、それらをapp.yaml
にハードコーディングすることや、決してコミットされずに自分のマシンに存在する別のファイルが含まれます。つまり、展開できるのは私だけです...別のマシンからデプロイします。これは私にとって問題です。
私が見た別の潜在的な解決策は、問題をGoogle Cloud Buildに委任し、CKMから値/ファイルをフェッチしてApp Engineにプッシュすることです( 1 、 2 =)。私はGCBを使用していませんが、基本的なものなので、使用することはないと思います。
App EngineにHerokuのような環境変数ページがあったらいいのにと思います。
[更新](2020年2月現在)GCPのシークレットマネージャーはベータ版、参照:
https://cloud.google.com/secret-manager/docs/overview
Java固有の実装については、以下を参照してください。 https://cloud.google.com/secret-manager/docs/creating-and-accessing-secrets#secretmanager-access-secret-version-Java
特定の解決策は、アプリの設定方法によって異なりますが、シークレットにアクセスして、値を含む環境変数を作成するか、アプリに渡すことができます。
GCP IAMを使用してサービスアカウントを作成し、アクセスを管理したり、Secret Manager Secret Accessor
のような役割を既存のメンバー/サービスに追加したりできます(たとえば、この場合、その権限をApp Engine default service account
に追加しました)。
GAE標準のNode.jsで試してみましたが、うまく機能しているようです。パフォーマンステストは一切行いませんでしたが、特にアプリの起動時またはビルドプロセスの一部としてシークレットが主に必要な場合は問題ありません。
ローカル(非GCP)の開発/テストの場合、適切なシークレットマネージャーの権限を持つサービスアカウントを作成し、jsonサービスキーを取得できます。次に、GOOGLE_APPLICATION_CREDENTIALS
という名前の環境変数をファイルのパスに設定します。例:
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/local_service_key.json
そのシェルセッションで実行されているアプリは、追加の認証コードなしで権限を取得する必要があります。参照: https://cloud.google.com/docs/authentication/getting-started (バージョン管理からキーファイルを除外する必要があります。)
現時点では、App Engineスタンダードスタンダードには、アプリケーションシークレットを保存するためのGoogle提供のソリューションがありません。
[UPDATE]
アプリケーションを制御する前に、環境変数を有効にする必要があるという別の回答に対するコメントに気付きました。その場合、現在のところApp Engineのオプションはありません。管理されたシークレットを提供できるシステムの目標により適した別のサービス(Kubernetes)にデプロイします。
[更新の終了]
App Engineスタンダードのシークレットには2つの選択肢があります。
どちらのオプションでも、暗号化することでセキュリティの層を追加できます。ただし、暗号化を追加すると、何らかの方法でアプリに提供する必要がある別のシークレット(復号化キー)が追加されます。鶏または卵の状況。
App Engineスタンダードはサービスアカウントを使用します。このサービスアカウントは、他のリソースへのアクセスを制御するIDとして使用できます。その他のリソースの例は、KMSやCloud Storageです。つまり、App Engineに別のシークレットを追加しなくても、KMSまたはCloud Storageに安全にアクセスできます。
あなたの会社がすべてのアプリケーションシークレットを暗号化することを望んでいるとします。 App Engineサービスアカウントを、単一のキーのKMSへのアクセスを承認されたIDとして使用できます。
注:次の例では、Windows構文を使用しています。行の継続を置き換える^
と\
Linux/macOSの場合。
KMSキーリングを作成します。キーリングは削除できないため、これは1回限りの操作です。
set GCP_KMS_KEYRING=app-keyring
set GCP_KMS_KEYNAME=app-keyname
gcloud kms keyrings create %GCP_KMS_KEYRING% --location global
KMSキーを作成します。
gcloud kms keys create %GCP_KMS_KEYNAME% ^
--location global ^
--keyring %GCP_KMS_KEYRING% ^
--purpose encryption
作成したキーリングとキーのKMSポリシーにサービスアカウントを追加します。
これにより、App EngineはKMSのシークレットを必要とせずにデータを復号化できます。サービスアカウントIDはアクセス制御を提供します。 KMSには役割は必要ありません。 app.yamlに含めることができるKMSキーリングとキー名を提供する必要があります。
set GCP_SA=<replace with the app engine service acccount email adddress>
set GCP_KMS_ROLE=roles/cloudkms.cryptoKeyDecrypter
gcloud kms keys add-iam-policy-binding %GCP_KMS_KEYNAME% ^
--location global ^
--keyring %GCP_KMS_KEYRING% ^
--member serviceAccount:%GCP_SA% ^
--role %GCP_KMS_ROLE%
この例では、MySQLデータベースにアクセスする必要があると仮定します。資格情報をJSONファイルに保存して暗号化します。ファイルの名前はconfig.json
。
{
"DB_Host": "127.0.0.1",
"DB_PORT": "3306",
"DB_USER": "Roberts",
"DB_PASS": "Keep-This-Secret"
}
Cloud KMSを使用してconfig.jsonを暗号化し、暗号化した結果をconfig.enc:に保存します
call gcloud kms encrypt ^
--location=global ^
--keyring %GCP_KMS_KEYRING% ^
--key=%GCP_KMS_KEYNAME% ^
--plaintext-file=config.json ^
--ciphertext-file=config.enc
暗号化されたファイルはCloud Storageに保存できます。暗号化されているので、ビルドファイルと一緒にファイルを保存できますが、お勧めしません。
最後のコードは、Javaにコードを記述することです。これは、KMSを使用してKMSを使用してconfig.encファイルを復号化するプログラムの一部です。Googleには、KMS復号化の例がいくつかあります。
秘密の管理については、私は個人的に Berglas プロジェクトのファンです。 KMSに基づいており、さらにDEKとKEKを管理します
今日はGoで記述されており、Javaに準拠していません。 一部の同僚のためにpython library を書きました。使用するつもりであれば、Javaパッケージを書くことができます。ハード。
お知らせ下さい
バーグラスは面白そうだ。
もう1つのオプションは、秘密をapp.yamlファイル(複数可)に入れ、バージョン管理にコミットする前に暗号化することです。
https://github.com/StackExchange/blackbox のように、バージョン管理に入れる前にシークレットを暗号化する多くのツールがあります。
長所:
短所: