Azure Key Vaultでの暗号化
Azure Key Vault キーでシークレットマネージャーの接続情報を保護

KeeperシークレットマネージャーとAzure Key Vaultと連携することで、構成ファイルを暗号化できます。この連携により、接続情報をローカル環境で保護しつつ、すべての機密認証情報に対してKeeperのゼロ知識暗号化を活用できます。
機能
Keeperシークレットマネージャーの構成ファイルをAzure Key Vaultで暗号化および復号化
シークレットマネージャー接続への不正アクセスを防止
最小限のコード変更で即時に保護を実現。すべてのKeeperシークレットマネージャーSDK機能と連携
AzureのRSA非対称鍵に対応
要件
Java/Kotlin版Secrets Manager SDKに対応
Azureパッケージ (
azure-identityおよびazure-keyvault-keys) が必要WrapKeyおよびUnwrapKeyの権限を持つRSA鍵タイプのみに対応
Azureパッケージ (
@azure/identityおよび@azure/keyvault-keys) が必要WrapKeyおよびUnWrapKeyの権限を持つRSA鍵タイプのみに対応
azure-identityおよびazure-keyvault-keysのパッケージが必要
WrapKeyおよびUnWrapKeyの権限を持つRSA鍵タイプのみに対応
バージョン
net9.0に対応Azureパッケージ (
Azure.IdentityおよびAzure.Security.KeyVault.Keys) が必要WrapKeyおよびUnWrapKeyの権限を持つRSA鍵タイプのみに対応
GoLang Secrets Manager SDKに対応
Azureパッケージ (
azcore、azidentity、azkeys) に対応WrapKeyおよびUnWrapKeyの権限を持つRSA鍵タイプのみに対応
セットアップ
1. モジュールのインストール
GradleまたはMavenを使用してプロジェクトをセットアップ
Gradle
repositories {
mavenCentral()
}
dependencies {
implementation("com.keepersecurity.secrets-manager:azurekv:1.0.0")
implementation("com.keepersecurity.secrets-manager:core:17.0.0")
implementation("com.azure:azure-identity:1.15.0")
implementation("com.azure:azure-security-keyvault-keys:4.9.2")
implementation("com.fasterxml.jackson.core:jackson-databind:2.18.2")
implementation("com.fasterxml.jackson.core:jackson-core:2.18.2")
implementation("com.google.code.gson:gson:2.12.1")
implementation("org.slf4j:slf4j-api:1.7.32"){
exclude("org.slf4j:slf4j-log4j12")
}
implementation("ch.qos.logback:logback-classic:1.2.6")
implementation("ch.qos.logback:logback-core:1.2.6")
implementation("org.bouncycastle:bc-fips:1.0.2.4")
}Maven
<!-- KMS-core -->
<dependency>
<groupId>com.keepersecurity.secrets-manager</groupId>
<artifactId>azurekv</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.keepersecurity.secrets-manager</groupId>
<artifactId>core</artifactId>
<version>17.0.0</version>
</dependency>
<!-- Azure-identity -->
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>1.15.0</version>
<scope>compile</scope>
</dependency>
<!-- Azure-keyvault -->
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-security-keyvault-keys</artifactId>
<version>4.9.2</version>
</dependency>
<!--gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.12.1</version>
</dependency>
<!--jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.18.2</version>
</dependency>
<!--jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.18.2</version>
</dependency>
<!-- slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
<scope>runtime</scope>
</dependency>
<!-- logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
<scope>compile</scope>
</dependency>
<!-- logback-core -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.6</version>
<scope>compile</scope>
</dependency>
<!-- bc-fips -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bc-fips</artifactId>
<version>1.0.2.4</version>
</dependency>
npmを使用してシークレットマネージャーとAzure Key Vaultモジュール統合をインストールします。
npm install @keeper-security/secrets-manager-azureシークレットマネージャーストレージAzureモジュールは、pipを使用してインストールできます。
pip3 install keeper-secrets-manager-storageKeeperシークレットマネージャーのKSMモジュールは、Keeperシークレットマネージャーのストレージモジュールに含まれており、dotnetを使用してインストールします。
dotnet add package Keeper.SecretsManager.AzureKeyVaultシークレットマネージャーとAzure KSMモジュールの統合は、以下のコマンドでインストールします。
go get github.com/keeper-security/secrets-manager-go/integrations/azure2. Azure Key Vaultの接続を構成
Azure Key Vaultインスタンスが利用可能であることを確認してください。Azure Key Vaultに接続するために必要な以下のパラメータが必要です。
AZURE_TENANT_ID: The Microsoft Entra tenant (directory) ID.
AZURE_CLIENT_ID: The client (application) ID of an App Registration in the tenant.
AZURE_CLIENT_SECRET: A client secret that was generated for the App Registration.
Azure Key Vault統合を使用するには、Azure Appディレクトリのアプリが必要です。
3. コードにAzure Key Vaultストレージを追加する
Azure接続が構成されたら、Azureキーを使用してKSM構成の暗号化/復号化を行うためにキーを取得できます。また、Secrets Manager SDKに対して、キー ボルトをストレージとして使用するよう指示する必要があります。
Azure Key Vault統合の使用
設定が完了すると、Secrets Manager Azure Key Vault統合はすべてのSecrets Manager SDK機能をサポートします。コードは、KSM構成ファイルの暗号化および復号化を管理するために、Azureキーにアクセスできる必要があります。 指定された接続認証情報の使用
この操作を行うには、AzureKeyValueStorageインスタンスを作成し、SecretManagerOptionsコンストラクタで使用します。
AzureKeyValueStorageは、azure_key_id、azure_keyvault_URL、構成が含まれたシークレットマネージャー構成ファイルの名前を必要とします。
import java.security.Security;
import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;
import com.keepersecurity.secretmanager.azurekv.AzureKeyValueStorage;
import com.keepersecurity.secretmanager.azurekv.AzureSessionConfig;
import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
class Test {
public static void main(String args[]){
String oneTimeToken = "[One_Time_Token]";
String keyId = "https://<vault-name>.vault.azure.net/keys/<keyname>/<keyversion>";
String configFileLocation="<KSM-client-config.json>";
String azTenantId = "<azure-tenant-id>";
String azClientId = "<azure-client-id>";
String azClientSecret = "<azure-client-secret>";
String keyVaultUrl = "https://<vault-name>.vault.azure.net/";
Security.addProvider(new BouncyCastleFipsProvider());
try{
//set azure KV configuration,
AzureSessionConfig azConfig= new AzureSessionConfig(azTenantId, azClientId, azClientSecret, keyVaultUrl);
//Get Storage
AzureKeyValueStorage azkvstorage = AzureKeyValueStorage.getInternalStorage(keyId, configFileLocation, azConfig);
initializeStorage(azkvstorage, oneTimeToken);
SecretsManagerOptions options = new SecretsManagerOptions(azkvstorage);
//getSecrets(options)
}catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
この操作を行うには、SecretsManagerコンストラクタで、AzureKeyValueStorageをシークレットマネージャーのストレージとして使用します。
このストレージには、Azure Key IDと、Azure Key Vaultによって暗号化されるシークレットマネージャー構成ファイルの名前が必要となります。
import { getSecrets, initializeStorage, localConfigStorage } from '@keeper-security/secrets-manager-core';
import {AzureKeyValueStorage, AzureSessionConfig} from "@keeper/secrets-manager-azure";
const getKeeperRecords = async () => {
const tenant_id="<tenant_id>"
const client_id="<client_id>"
const client_secret="<client-secret>"
const azureSessionConfig = new AzureSessionConfig(tenant_id, client_id, client_secret)
let config_path = "<path to ksm-client-config.json>"
const logLevel = LoggerLogLevelOptions.info;
// oneTimeToken is used only once to initialize the storage
// after the first run, subsequent calls will use ksm-config.txt
const oneTimeToken = "[One Time Token]";
const keyId = 'https://<vault_name>.vault.azure.net/keys/<key_name>/<version>'
const storage = await new AzureKeyValueStorage(keyId,config_path,azureSessionConfig,logLevel).init();
await initializeStorage(storage, oneTimeToken);
const {records} = await getSecrets({storage: storage});
console.log(records)
}
getKeeperRecords()
この操作を行うには、SecretsManagerコンストラクタで、トークンと共にAzureKeyValueStorageを構成として指定し、シークレットマネージャーのストレージとして使用します。
このストレージでは、Azure Key ID、Azure-KSM統合によって暗号化されるシークレットマネージャー構成ファイルの場所、そして以下のようなAzureセッション構成が必要です。
from keeper_secrets_manager_storage.storage_azure_keyvault import AzureSessionConfig,AzureKeyValueStorage
from keeper_secrets_manager_core import SecretsManager
tenant_id = "<Tenant_ID>"
client_id = "<CLIENT_ID>"
client_secret = "<CLIENT_SECRET>"
azure_session_config = AzureSessionConfig(tenant_id, client_id, client_secret)
config_path = "<path_to_client_config_python.json>"
token="<One Time Token>"
key_id = "<key_id>"
azure_key_value_storage = AzureKeyValueStorage(key_id=keyId,config_file_location=config_path ,az_session_config=azure_session_config)
secrets_manager = SecretsManager(token = token,config=azure_key_value_storage)
records = secrets_manager.get_secrets()
for record in records:
print(record)
この操作を行うには、SecretsManagerコンストラクタで、AzureKeyValueStorageをシークレットマネージャーのストレージとして使用します。
このストレージでは、Azure Key IDと、Azure Key Vaultによって暗号化されるシークレットマネージャー構成ファイルの名前が必要です。オプションでAzureSessionConfigを指定することも可能です。認証情報が指定されていない場合は、既定の認証情報が使用されます。
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using OracleKeyManagement;
using SecretsManager;
public class Program
{
private static async Task getOneIndividualSecret()
{
var tenant_id = "<TENANT_ID>";
var client_secret = "<CLIENT_SECRET>";
var client_id = "<CLIENT_ID>";
var keyId = "<KEY_ID>";
var path = "ksmConfigDotnet.json";
var dotnet_access_token = "<ACCESS_TOKEN>";
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(LogLevel.Debug);
builder.AddConsole();
});
var logger = loggerFactory.CreateLogger<AzureKeyValueStorage>();
var azure_session_config = new AzureSessionConfig(tenant_id, client_id, client_secret);
AzureKeyValueStorage azure_storage = new AzureKeyValueStorage(keyId, path, azure_session_config, logger);
SecretsManagerClient.InitializeStorage(azure_storage, dotnet_access_token);
var options = new SecretsManagerOptions(azure_storage);
var records_list = await SecretsManagerClient.GetSecrets(options);
records_list.Records.ToList().ForEach(record => Console.WriteLine(record.RecordUid + " - " + record.Data.title));
}
static async Task Main()
{
await getOneIndividualSecret();
}
}この操作を行うには、SecretsManagerコンストラクタで、NewAzureKeyValueStorageをシークレットマネージャーのストレージとして使用します。
NewAzureKeyVaultStorageでAzure Key Vaultを使用してKSM構成を暗号化するには、以下のパラメータが必要です:
ksmConfigFileName: KSM構成ファイルの名前keyURL: Azure KeyのURL
package main
import (
"encoding/json"
"fmt"
"github.com/keeper-security/secrets-manager-go/core"
azurekv "github.com/keeper-security/secrets-manager-go/integrations/azure"
)
func main() {
ksmConfigFile := ""
oneTimeToken := "oneTimeToken"
keyURL := "<Key URL>" }
//Initialize the Azure Key Vault Storage
cfg := azurekv.NewAzureKeyValueStorage(ksmConfigFileName, keyURL, &azurekv.AzureConfig{
TenantID: "<Azure Tenant ID>",
ClientID: "<Azure Client ID>",
ClientSecret: "<Azure Client Secret>",
})
// create a new secrets manager client
secrets_manager := core.NewSecretsManager(
&core.ClientOptions{
Config: cfg,
Token: oneTimeToken,
},
)
// Fetch all the secrets from the vault
secrets, err := secrets_manager.GetSecrets([]string{})
if err != nil {
// do something
fmt.Printf("Error: %s\n", err)
} else {
for _, secret := range secrets {
fmt.Printf("Recieved secret: %s\n", secret.Title())
}
}
}追加オプション
キーの変更
KSM構成の暗号化に使用するキーを変更することも可能です。以下の例は、そのために必要なコードとなります。
// `changeKey(newKeyID)`メソッドは、新しいAzureキーでKSM構成ファイルを暗号化するために使用されます。
....
String newKeyID = "https://<vault-name>.vault.azure.net/keys/<keyname>/<keyversion>";
AzureKeyValueStorage azkvstorage = AzureKeyValueStorage.getInternalStorage(keyId, configFileLocation, azConfig);
boolean isChanged = azkvstorage.changeKey(newKeyID); // Change the key for encryption/decryption
....// 暗号化に使用するAzure Key Vaultキーを変更するには、`OciKeyValueStorage`インスタンスで`changeKey`メソッドを呼び出すことができます。
.....
const keyId = 'https://<vault_name>.vault.azure.net/keys/<key_name>/<version>'
const keyId2 = "https://<vault_name>.vault.azure.net/keys/<key_name>/<version>"
const storage = await new AzureKeyValueStorage(keyId,config_path,azureSessionConfig).init();
await storage.changeKey(keyId2);
.....azure_key_value_storage = AzureKeyValueStorage(key_id=keyId,config_file_location=config_path ,az_session_config=azure_session_config)
new_key_id = "<new key id>"
isChanged = azure_key_value_storage.change_key(new_key_id = new_key_id)
print("Key is changed " + isChanged)// 暗号化に使用するAzureキーを変更するには、`AzureKeyValueStorage`インスタンスで`ChangeKeyAsync`メソッドを呼び出すことができます。
`Microsoft.Extensions.Logging`を使用して、ログ機能を統合することも可能です。
....
var keyId2 = "<KEY_ID_2>";
var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(LogLevel.Debug);
builder.AddConsole();
});
var logger = loggerFactory.CreateLogger<AzureKeyValueStorage>();
AzureKeyValueStorage azure_storage = new AzureKeyValueStorage(keyId, path, azure_session_config, logger);
azure_storage.ChangeKeyAsync(keyId2).Wait();
.... ....
updatedConfig := &azurekv.AzureConfig{
TenantID: "<Updated Tenant ID>",
ClientID: "<Updated Client ID>",
ClientSecret: "<Updated Client Secret>",
}
updatedKeyURL := "<Updated Key URL>"
// Changes the key
// If you don't want to change Config, pass nil as a paramter
isChanged, err := cfg.ChangeKey(updatedKeyURL, updatedConfig)
if err != nil {
fmt.Printf("Error while changing key: %v", err)
} else {
fmt.Printf("Key changed: %v\n", isChanged)
}
.....構成の復号化
現在の実装を別のクラウド環境へ移行する場合や、生の認証情報を取得したい場合には、構成の復号が可能です。この関数はブール値を受け取り、trueに設定すると復号化された構成をファイルに保存し、falseの場合は復号化された構成を返します。
....
AzureKeyValueStorage azkvstorage = AzureKeyValueStorage.getInternalStorage(keyId, configFileLocation, azConfig);
azkvstorage.decryptConfig(false); // falseをパラメータとして設定すると、プレーンテキストのみが抽出されます。
//または
azkvstorage.decryptConfig(true); //trueをパラメータとして設定すると、プレーンテキストを抽出し、構成をプレーンテキストとして保存します。
.... //構成ファイルを復号化してプレーンテキストとして再保存するには、`AzureKeyValueStorage`インスタンスで`DecryptConfigAsync`メソッドを呼び出すことができます。
....
const storage = await new AzureKeyValueStorage(keyId,config_path,azureSessionConfig).init();
const decryptedConfig = storage.DecryptConfigAsync(true).wait(); // return decrypted and Saves to file
//OR
const decryptedConfig = await storage.decryptConfig(false); // returns the decrypted config
.... storage = AzureKeyValueStorage(key_id=keyId,config_file_location=config_path ,az_session_config=azure_session_config)
storage.decrypt_config() #プレーンな構成ファイルを保存
# or
storage.decrypt_config(False)#復号化された構成は戻り値として返され、ファイル自体は暗号化されたまま保持されます。//構成ファイルを復号化してプレーンテキストとして再保存するには、AzureKeyValueStorageインスタンスで DecryptConfigAsyncメソッドを呼び出します。
....
var keyId2 = "<KEY_ID_2>";
AzureKeyValueStorage azure_storage = new AzureKeyValueStorage(keyId, path, azure_session_config, logger);
await azure_storage.DecryptConfigAsync(true); // return decrypted and Saves to file
//OR
await azure_storage.DecryptConfigAsync(false); // returns the decrypted config
.... .....
configs := make(map[core.ConfigKey]interface{})
plainText, err := cfg.DecryptConfig(true)
if err != nil {
// do something
fmt.Printf("Error while decrypting config: %v", err)
} else {
if err := json.Unmarshal([]byte(plainText), &configs); err != nil {
fmt.Printf("Error while unmarshalling: %v", err)
}
fmt.Printf("Decrypted data: %v\n", configs["clientId"])
}
.....KSM統合機能を使用する準備ができました。
最終更新

