最新の安定バージョンについては、Spring Vault 4.1.0 を使用してください!

VaultTemplate の概要

パッケージ org.springframework.vault.core にあるクラス VaultTemplate (Javadoc) は、Spring の Vault サポートの中心となるクラスで、Vault と対話するための豊富な機能セットを提供します。このテンプレートは、Vault のデータの読み取り、書き込み、削除を行うための便利な操作を提供し、ドメインオブジェクトと Vault データ間のマッピングを提供します。

一度設定されると、VaultTemplate (Javadoc) はスレッドセーフとなり、複数のインスタンス間で再利用できます。

Vault ドキュメントとドメインクラス間のマッピングは、RestTemplate に委譲することによって行われます。Spring Web サポートは、マッピングインフラストラクチャを提供します。

VaultTemplate (Javadoc) クラスは、インターフェース VaultOperations (Javadoc) を実装します。可能な限り、VaultOperations (Javadoc) のメソッドは、API と CLI に慣れている既存の Vault 開発者に API を馴染みのあるものにするために、Vault API で利用可能なメソッドにちなんで名付けられています。たとえば、"write"、"delete"、"read"、"revoke" などのメソッドがあります。設計ゴールは、Vault API と VaultOperations の使用をできるだけ簡単に移行できるようにすることでした。2 つの API の主な違いは、VaultOperations に JSON キーと値のペアではなくドメインオブジェクトを渡すことができることです。

VaultTemplate で使用されるパス(およびそこからアクセス可能なインターフェース)は、VaultEndpoint を基準とした相対パスとみなされます。完全修飾 URI のパスは、認証されたコンテキストで Vault クラスタメンバーにアクセスするために使用できます。不要な完全 URI アクセスを防ぐため、パスを VaultTemplate に渡す前に必ずサニタイズしてください。

VaultTemplate (Javadoc) インスタンスの操作を参照する推奨方法は、そのインターフェース VaultOperations (Javadoc) を使用することです。

VaultTemplate には、Vault API に直接アクセスして VaultTemplate によって明示的に公開されていない機能にアクセスする必要がある場合に、一般的なタスクを簡単に実行できる便利なメソッドが多数ありますが、いくつかの実行コールバックメソッドの 1 つを使用して、基になる API にアクセスできます。実行コールバックは、RestOperations オブジェクトへの参照を提供します。詳細については、セクション実行コールバックを参照してください。

次に、Spring コンテナーのコンテキストで Vault を操作する方法の例を見てみましょう。

Spring Vault Bean の登録と設定

Using Spring Vault does not require a Spring Context. However, instances of VaultTemplate and SessionManager (Javadoc) registered inside a managed context will participate in lifecycle events provided by the Spring IoC container. This is useful to dispose active Vault sessions upon application shutdown. You also benefit from reusing the same VaultTemplate instance across your application.

Spring Vault には、Spring コンテキスト内で使用する Bean 定義を提供するサポート構成クラスが付属しています。アプリケーション構成クラスは通常 AbstractVaultConfiguration (Javadoc) を継承し、環境固有の追加情報を提供する必要があります。

AbstractVaultConfiguration (Javadoc) から拡張するには、VaultEndpoint vaultEndpoint() および ClientAuthentication clientAuthentication() メソッドを実装する必要があります。

例 1: Java ベースの Bean メタデータを使用して Spring Vault オブジェクトを登録する
@Configuration
public class AppConfig extends AbstractVaultConfiguration {

    /**
     * Specify an endpoint for connecting to Vault.
     */
    @Override
    public VaultEndpoint vaultEndpoint() {
        return new VaultEndpoint();                            (1)
    }

    /**
     * Configure a client authentication.
     * Please consider a more secure authentication method
     * for production use.
     */
    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication("…");                   (2)
    }
}
1 デフォルトで https://localhost:8200 を指す新しい VaultEndpoint (Javadoc) を作成します。
2 このサンプルでは、すぐに開始できるように TokenAuthentication (Javadoc) を使用します。サポートされている認証方法の詳細については、[vault.core.authentication] を参照してください。
例 2: 注入されたプロパティを適用して Spring Vault を登録します
@Configuration
public class AppConfig extends AbstractVaultConfiguration {

    @Value("${vault.uri}")
    URI vaultUri;

    /**
     * Specify an endpoint that was injected as URI.
     */
    @Override
    public VaultEndpoint vaultEndpoint() {
        return VaultEndpoint.from(vaultUri);                          (1)
    }

    /**
     * Configure a Client Certificate authentication.
     * {@link RestOperations} can be obtained from {@link #restOperations()}.
     */
    @Override
    public ClientAuthentication clientAuthentication() {
        return new ClientCertificateAuthentication(restOperations()); (2)
    }
}
1VaultEndpoint (Javadoc) は、from(URI uri) や VaultEndpoint.create(String host, int port) などのさまざまなファクトリメソッドを使用して構築できます。
2ClientAuthentication メソッドの依存関係は、AbstractVaultConfiguration から取得するか、構成によって提供することができます。
カスタム構成クラスの作成は、場合によっては面倒な場合があります。既存のプロパティソースのプロパティを使用して構成できる EnvironmentVaultConfiguration (Javadoc) と Spring の Environment を参照してください。詳細については、EnvironmentVaultConfiguration の使用を参照してください。

セッション管理

Spring Vault requires a ClientAuthentication to login and access Vault. See [vault.core.authentication] on details regarding authentication. Vault login should not occur on each authenticated Vault interaction but must be reused throughout a session. This aspect is handled by a SessionManager implementation. A SessionManager decides how often it obtains a token, about revocation and renewal. Spring Vault comes with two implementations:

  • SimpleSessionManager (Javadoc) : リフレッシュや取り消しなしで、提供された ClientAuthentication からトークンを取得するだけです

  • LifecycleAwareSessionManager (Javadoc) : この SessionManager は、トークンが更新可能な場合にトークンの更新をスケジュールし、廃棄時にログイントークンを取り消します。更新は AsyncTaskExecutor で予定されています。AbstractVaultConfiguration を使用する場合、デフォルトで LifecycleAwareSessionManager が構成されます。

EnvironmentVaultConfiguration を使用する

Spring Vault includes EnvironmentVaultConfiguration (Javadoc) configure the Vault client from Spring’s Environment and a set of predefined property keys. EnvironmentVaultConfiguration (Javadoc) supports frequently applied configurations. Other configurations are supported by deriving from the most appropriate configuration class. Include EnvironmentVaultConfiguration (Javadoc) with @Import(EnvironmentVaultConfiguration.class) to existing Java-based configuration classes and supply configuration properties through any of Spring’s PropertySources.

例 3: プロパティファイルでの EnvironmentVaultConfiguration の使用
Java ベースの構成クラス
@PropertySource("vault.properties")
@Import(EnvironmentVaultConfiguration.class)
public class MyConfiguration{
}
vault.properties
vault.uri=https://localhost:8200
vault.token=00000000-0000-0000-0000-000000000000

プロパティキー

  • Vault URI: vault.uri

  • SSL 構成

    • キーストアリソース: vault.ssl.key-store (オプション)

    • 鍵ストアパスワード: vault.ssl.key-store-password (オプション)

    • 鍵ストアタイプ: vault.ssl.key-store-type (オプション (通常は jks) は pem もサポートします)

    • トラストストアリソース: vault.ssl.trust-store (オプション)

    • トラストストアのパスワード: vault.ssl.trust-store-password (オプション)

    • トラストストアの型: vault.ssl.trust-store-type (オプション (通常は jks) は pem もサポートします)

    • 有効な SSL/TLS プロトコル: vault.ssl.enabled-protocols (2.3.2 以降、オプション、カンマで区切られたプロトコル)

    • 有効化された SSL/TLS 暗号スイート: vault.ssl.enabled-cipher-suites (2.3.2 以降、オプション、カンマで区切られた暗号スイート)

  • 認証方式: vault.authentication (デフォルトは TOKEN、サポートされている認証方法は次のとおりです: TOKENAPPIDAPPROLEAWS_EC2AWS_IAMAZURECERTCUBBYHOLEKUBERNETES)

認証固有のプロパティキー

  • Vault トークン: vault.token

  • AppId パス: vault.app-id.app-id-path (デフォルトは app-id)

  • AppId: vault.app-id.app-id

  • ユーザー ID: vault.app-id.user-idMAC_ADDRESS および IP_ADDRESS は、それぞれ IpAddressUserId ユーザー ID メカニズムである MacAddressUserId を使用します。その他の値は StaticUserId で使用されます。

  • AppRole パス: vault.app-role.app-role-path (デフォルトは approle)

  • RoleId: vault.app-role.role-id

  • SecretId: vault.app-role.secret-id (オプション)

  • AWS EC2 パス: vault.aws-ec2.aws-ec2-path (デフォルトは aws-ec2)

  • ロール: vault.aws-ec2.role

  • RoleId: vault.aws-ec2.role-id ( 非推奨となりた : 代わりに vault.aws-ec2.role を使用してください)

  • 身分証明書の URL: vault.aws-ec2.identity-document (デフォルトは 169.254.169.254/latest/dynamic/instance-identity/pkcs7 (英語) )

  • ロール: vault.aws-iam.role

構成オプションはありません。

  • 初期 Vault トークン: vault.token

  • Kubernetes パス: vault.kubernetes.kubernetes-path (デフォルトは kubernetes)

  • ロール: vault.kubernetes.role

  • サービスアカウントトークンファイルへのパス: vault.kubernetes.service-account-token-file (デフォルトは /var/run/secrets/kubernetes.io/serviceaccount/token)

実行コールバック

すべての Spring テンプレートクラスに共通する設計上の特徴の 1 つは、すべての機能がテンプレートの実行コールバックメソッドの 1 つにルーティングされることです。これにより、例外や必要なリソース管理が一貫して実行されるようになります。これは、Vault の場合よりも JDBC や JMS の場合に非常に重要でしたが、それでもアクセスとログ記録を行うための単一の場所を提供します。そのため、実行コールバックを使用することは、VaultTemplate (Javadoc) のメソッドとして公開していない珍しい操作を実行するために Vault API にアクセスする推奨される方法です。

実行コールバックメソッドのリストを次に示します。

  • <T> T doWithVault (RestOperationsCallback<T> callback) 指定された RestOperationsCallback を実行し、セッションを必要とせずに RestOperations を使用して Vault と対話できるようにします。

  • <T> T doWithSession (RestOperationsCallback<T> callback) 指定された RestOperationsCallback を実行し、認証されたセッションで Vault と対話できるようにします。

以下は、ClientCallback を使用して Vault を初期化する例です。

vaultOperations.doWithVault(new RestOperationsCallback<VaultInitializationResponse>() {

  @Override
  public VaultInitializationResponse doWithRestOperations(RestOperations restOperations) {

    ResponseEntity<VaultInitializationResponse> exchange = restOperations
                       .exchange("sys/init", HttpMethod.PUT,
                                 new HttpEntity<Object>(request),
                                 VaultInitializationResponse.class);

    return exchange.getBody();
    }
});