PowerShell
オブジェクトパイプラインとエラー処理機構を持つ、Microsoftが最も堅牢で最新のWindows自動化に推奨するコマンドラインシェル兼スクリプト言語。
平文パスワードの埋め込みリスク
パスワードをスクリプトに平文で書くことで、Git履歴・共有フォルダ・ログなどコピーが生まれる経路すべてが漏えい経路になる問題。
スクリプトへのパスワード直書き
PSCredential
ユーザー名とSecureStringのパスワードをひとまとめにした.NET/PowerShellの資格情報オブジェクト。
PSCredentialオブジェクト
Get-Credential
ユーザー名とパスワードの入力を促し、PSCredentialオブジェクトを返すコマンドレット。
SecureString
文字列を暗号化して保持する.NETのクラス。暗号化はWindowsでのみ行われ、.NET公式は新規開発での使用を推奨していない。
タスクスケジューラの無人実行
指定したアカウントで、スケジュールやログオンなどのトリガーに従いプログラムを実行するWindowsの仕組み。ログオン種別(対話トークン・パスワード保存・S4Uなど)の設定によっては、ユーザーがログオンしていなくても実行できる。
Export-Clixml(資格情報ファイル)
資格情報などのオブジェクトをXMLファイルへ保存するコマンドレット。Windowsでは保存内容がDPAPIで暗号化され、保存したユーザー・マシンでしか復号できない。
DPAPI
実行中のマシン上でアプリの秘密情報を保護するWindowsのデータ保護API。
データ保護API
SecretManagementモジュール
秘密の保管場所(ボールト)への統一インターフェースを提供するPowerShellモジュール。実際の保存は拡張ボールトが担う。
SecretStoreモジュール
ローカルファイルに暗号化保存するMicrosoft製の拡張ボールト。SecretManagementの既定のボールト実装として使われる。
Azure Key Vault
秘密情報を安全に保管できるAzureのシークレット管理サービスで、Power Automateの資格情報の保管先として設定できる。
gMSA(group Managed Service Account)
パスワードの自動生成・自動更新とSPN管理の簡素化を提供するActive Directoryドメインのサービスアカウント。ドメインコントローラー側のKDSルートキーの準備を前提とする。
グループ管理サービスアカウント
Active Directory(AD DS)
オンプレミスのWindowsドメインを構成するディレクトリサービス。
オンプレAD
マネージドID
Azure上のリソースに割り当てたEntra ID上のIDを使い、資格情報を保存せずにトークンを取得して認証する仕組み。
Microsoft Entra ID
Microsoftのクラウド型ID・アクセス管理基盤。
ログ・トランスクリプトへの資格情報の漏えい
スクリプトブロックログやトランスクリプションが有効な環境で、処理中に扱われた資格情報や機微データがイベントログ・ファイルへそのまま記録されてしまうこと。
スクリプトブロックログ
PowerShellが処理する全スクリプトブロックの内容をイベントログに記録する機能。
保護されたイベントログ(Protected Event Logging)
対象のイベントログの内容をCMS(暗号メッセージ構文)の公開鍵で暗号化して書き込み、秘密鍵を持つ場所でだけ復号できるようにする仕組み。
PSScriptAnalyzer
PowerShellスクリプトを静的解析するMicrosoft公式のツール。
PowerShellはユーザー名とパスワードをひとまとめにしたPSCredentialオブジェクトで資格情報を受け渡す
Get-Credentialはユーザー名とパスワードの入力を促し、PSCredentialオブジェクトを返す
PSCredentialはパスワードをSecureStringとして内部に保持し、画面には表示しない
人がその場で実行するスクリプトでは、Get-Credentialで都度入力させることが平文パスワード埋め込みへの基本対策になる
無人実行のタスクはGet-Credentialで人に聞くわけにいかないため、対話入力に依存する取得方法は使えない
Windows上でExport-Clixmlを実行した場合、資格情報オブジェクトのパスワードはDPAPIで現在のユーザーとマシンに紐づけて暗号化される。LinuxやmacOSのPowerShellにはDPAPIがなく、パスワードはUnicodeの文字配列として書き出されるだけで暗号化されない
タスクスケジューラの無人実行でパスワード入力なしに認証するには、実行アカウント自身が保存したExport-Clixmlの資格情報ファイルを使う構成が最小構成の実用解になる
無人実行で秘密が1〜2個の場合、Export-ClixmlによるDPAPI保存が平文埋め込みを避ける最小構成の実用解になる
SecretManagementはボールトへの統一インターフェースで、ローカル保存にはSecretStoreを拡張ボールトとして使う
拡張ボールトにAzure Key Vaultを選ぶ場合、SecretManagementは保存先をAzure Key Vaultへ差し替えられる
秘密が複数あり保存先を将来差し替えたい場合は、Set-Secret/Get-Secretで一元管理するSecretManagement+SecretStoreを使う
SecretStoreを無人実行で使うには、ボールトパスワードをExport-ClixmlでDPAPI保護したファイルに退避してUnlock-SecretStoreで解錠する構成が公式に案内されている
SecretManagementは$env:LOCALAPPDATAとDPAPIに依存しており、プロファイルを持たないgMSAのような管理されたアカウントでは動作しない
実行アカウント自体に接続先の権限を与え、gMSAでパスワード管理をOSに任せることが最優先の現実解になる
gMSAはドメインの管理されたアカウントであり、Active Directoryのドメイン機能を前提とする
gMSAを実行アカウントに選ぶ場合、Windowsサービスだけでなくタスクスケジューラのタスクの実行アカウントにも使える
クラウド資源への接続は、キーの保存よりマネージドIDの利用を優先すべきとされる
マネージドIDはEntra ID上のIDを使ってトークンを取得し、資格情報を管理せずに認証する仕組み
スクリプトに平文で書かれたパスワードは、コマンドラインや変数として扱われた時点でスクリプトブロックログやトランスクリプトにそのまま記録されうるため、ログへの資格情報漏えいにつながる
スクリプトブロックログを有効にすると、処理したスクリプトブロックの内容がイベントログに記録され、資格情報などの機微データが含まれうる
保護されたイベントログは、対象のログ内容をCMSの公開鍵で暗号化して書き込み、秘密鍵を持つ安全な場所でだけ復号できるようにする
スクリプト内の平文からConvertTo-SecureStringへ変換する書き方は、PSScriptAnalyzerの静的解析でエラーとして検出できる
PowerShellはGet-CredentialやSecretManagementなど標準の道具でSecureStringを前提としており、平文文字列で持ち回るよりは露出が減る
クラウド資源・複数サーバーで共有する秘密は、マシン局所のDPAPIでは共有できないため、Azure Key Vaultのような専用ボールトに保存する