このバージョンはまだ開発中であり、まだ安定しているとは見なされていません。最新の安定バージョンについては、Spring Vault 4.0.2 を使用してください!

Vault クライアントアクセス

Spring/Vault フレームワークが提供する価値は、以下の表に概説されている一連のアクションによって最もよく示されるでしょう。この表は、特定のクライアントオプションを選択する際に Spring がどの機能を処理するかを示しています。

クライアント HTTP リクエスト 認証 Vault オペレーション エラー処理

RestClient

URI、ヘッダー、メッセージ変換を完全に制御できる低レベルの HTTP リクエストアクセス。リクエストを手動で構築し、レスポンスを処理します。VaultEndpoint (Javadoc) は、相対パスの使用を可能にする UriBuilderFactory を介して設定できます。

組み込みの認証サポートはありません。トークンとヘッダーを自分で管理する必要があります。

Vault ドメインへの直接的な操作はできません。Vault エンドポイントへのリクエストは手動で作成する必要があります。

4xx/5xx status translated to HttpServerErrorException respective HttpClientErrorException, onStatus lets you register custom handlers

VaultClient

Vault-specific fluent HTTP client built on top of RestClient. Provides methods for common HTTP verbs and request construction along with VaultEndpoint (Javadoc) support to decouple access to functionality through relative paths from actual Vault server configuration.

Convenience methods for setting tokens (token(…)) and namespaces (namespace(…)); easier to manage authentication headers and can be used with ClientAuthentication (Javadoc) implementations to log into Vault.

Path-based request methods; Allows consuming Vault responses as VaultResponse (Javadoc) through ResponseSpec.body() and ResponseSpec.toEntity() methods; supports response wrapping directly.

4xx/5xx status translated to VaultClientResponseException, onStatus lets you register custom handlers

VaultTemplate

High-level abstraction for Vault operations. HTTP requests can be issued through client callbacks.

Support for simple ClientAuthentication (Javadoc) and SessionManager (Javadoc) implementations that handle token renewal and authentication.

Java API for several Vault domain operations (read, write, delete, list) supporting various secret backends (KV, Cubbyhole, PKI, Transit, etc.).

Built on top of VaultClient, translates HTTP errors into Spring Vault exceptions (e.g., VaultException).

Client Examples

RestClient
  • Java

  • Kotlin

RestClient client = RestClient.create();

VaultResponse response = client.get()
	.uri("https://vault.example.com/v1/secret/my-secret")
	.header("X-Vault-Token", "…")
	.header("X-Vault-Namespace", "…")
	.retrieve()
	.body(VaultResponse.class);
val client = RestClient.create()

val response = client.get()
	.uri("https://vault.example.com/v1/secret/my-secret")
	.header("X-Vault-Token", "…")
	.header("X-Vault-Namespace", "…")
	.retrieve()
	.body<VaultResponse>()
VaultClient
  • Java

  • Kotlin

VaultClient client = VaultClient.create(VaultEndpoint.create("vault.example.com", 8200));

VaultResponse response = client.get()
	.path("secret/my-secret")
	.token(VaultToken.of(…))
	.namespace(…)
	.retrieve()
	.requiredBody();
val client = VaultClient.create(VaultEndpoint.create("vault.example.com", 8200))

val response = client.get()
	.path("secret/my-secret")
	.token(VaultToken.of(…))
	.namespace(…)
	.retrieve()
	.requiredBody()
VaultTemplate
  • Java

  • Kotlin

VaultTemplate vaultOperations = new VaultTemplate(vaultClient, sessionManager);
VaultResponse response = vaultOperations.read("secret/my-secret");
// or
Object value = vaultOperations.readRequired("secret/my-secret").getRequiredData().get("value");
val vaultOperations = VaultTemplate(vaultClient, sessionManager)
val response = vaultOperations.read("secret/my-secret")
// or
val value = vaultOperations.readRequired("secret/my-secret").getRequiredData()["value"]

Recommendations

If you need the most flexibility and full control over the HTTP client (connection pooling, custom TLS keystore at the JVM level, wire logging for diagnostics), start with a properly configured RestClient or request factory. This is the right choice for framework-level code or libraries that must adapt to many environments.

For most application code that uses Vault, VaultClient strikes the right balance: It provides a readable, fluent API along with easy request/response handling that resembles RestClient look-and-feel. Its safe defaults such as endpoint scoping and token helpers avoid common pitfalls.

Choose VaultTemplate when you prefer working with Vault at a higher level of abstraction. It reduces boilerplate and integrates with Spring’s conversion and exception-translation patterns. Use it when your application performs secret CRUD operations and you want concise, intention-revealing code that provides a Java API for Vault.

VaultClient and ReactiveVaultClient

Spring Vault provides the following choices for making calls to Vault endpoints:

  • VaultClient — synchronous client with a fluent API based on Spring Framework’s RestClient

  • ReactiveVaultClient — non-blocking, reactive client with fluent API based on Spring Framework’s WebClient

VaultClient is a synchronous HTTP client that provides a fluent API to perform requests. It’s reactive variant ReactiveVaultClient mirrors VaultClient's design for non-blocking access. Going forward, the documentation shows VaultClient. Except for the reactive aspects, ReactiveVaultClient works the same way. It serves as an abstraction over HTTP libraries, and handles conversion of HTTP request and response content to and from higher level Java objects build on top of RestClient respective WebClient for its reactive variant.

Create a VaultClient

VaultClient has static create shortcut methods. It also exposes a builder() with further options:

  • select the HTTP library to use, see Client Request Factories

  • set a VaultEndpoint or VaultEndpointProvider to enable relative path usage and limit requests to the configured Vault server

  • set default request headers

  • customize the underlying RestClient (or WebClient for ReactiveVaultClient)

Once created, a VaultClient is safe to use in multiple threads.

You can register VaultClientCustomizer (Javadoc) or its reactive variant ReactiveVaultClientCustomizer (Javadoc) when using Spring Vault’s configuration infrastructure to customize the VaultClient or ReactiveVaultClient instances created by Spring Vault.

The following example shows how to create or build a VaultClient:

  • Java

  • Kotlin

VaultClient defaultClient = VaultClient.create();

VaultClient customClient = VaultClient.builder()
	.endpoint(VaultEndpoint.create("vault.acme.com", 8200))
	.requestFactory(new HttpComponentsClientHttpRequestFactory())
	.defaultHeader("My-Header", "Foo")
	.configureRestClient(builder -> … )
	.build();
val defaultClient = VaultClient.create()

val customClient = VaultClient.builder()
	.endpoint(VaultEndpoint.create("vault.acme.com", 8200))
	.requestFactory(HttpComponentsClientHttpRequestFactory())
	.defaultHeader("My-Header", "Foo")
	.configureRestClient{ … }
	.build()

Use the VaultClient

To perform a Vault request, first specify the HTTP method to use. Use the convenience methods like get(), post(), delete(), and others, or method(HttpMethod).

Request Path

Next, specify the request path with the path methods. The path is typically specified as a String, with optional URI template variables. The following shows how to perform a request:

  • Java

  • Kotlin

int id = 42;
vaultClient.get()
	.path("secret/{id}", id)
	// ...
val id = 42
vaultClient.get()
	.path("secret/{id}", id)
	// ...

String URLs are encoded by default, but this can be changed by building a client with a custom uriBuilderFactory. The URL can also be provided with a function or as a java.net.URI, both of which are not encoded. Using a URI allows accessing external servers.

Request headers and body

If necessary, the Vault request can be manipulated by adding request headers with header(String, String) or token(VaultToken) and so on.

The request body itself can be set by body(Object), which internally uses HTTP Message conversion. Alternatively, the request body can be set using a ParameterizedTypeReference, allowing you to use generics.

Retrieving the response

Once the request has been set up, it can be sent by chaining method calls after retrieve(). For example, the response body can be accessed by using retrieve().body(Class) or retrieve().body(ParameterizedTypeReference) for parameterized types like lists. A convenience method retrieve().body() retuns the body using Vault’s default response type VaultResponse (Javadoc) . The body method converts the response contents into various types – for instance, bytes can be converted into a String, JSON can be converted into objects using Jackson.

The response can also be converted into a ResponseEntity, giving access to the response headers as well as the body, with retrieve().toEntity(Class)

retrieve() を単独で呼び出しても何も実行されず、ResponseSpec が返されます。副作用が発生するには、アプリケーションは ResponseSpec でターミナル操作を呼び出す必要があります。レスポンスの消費がユースケースに関係ない場合は、retrieve().toBodilessEntity() を使用できます。

このサンプルは、VaultClient を使用して単純な GET リクエストを実行する方法を示します。

  • Java

  • Kotlin

VaultResponse result = vaultClient.get() (1)
	.path("secret/my-secret")            (2)
	.retrieve()                          (3)
	.requiredBody();                     (4)

System.out.println(result);              (5)
1GET リクエストを設定する
2Vault サーバー上のパスを指定してください
3 レスポンスを取得する
4 レスポンスを VaultResponse に変換します
5 結果を出力する
val result = vaultClient.get()   (1)
	.path("secret/my-secret")   (2)
	.retrieve()                 (3)
	.requiredBody()             (4)

println(result)                 (5)
1GET リクエストを設定する
2Vault サーバー上のパスを指定してください
3 レスポンスを取得する
4 レスポンスを VaultResponse に変換します
5 結果を出力する

レスポンスステータスコードとヘッダーへのアクセスは、ResponseEntity を通じて提供されます。

  • Java

  • Kotlin

ResponseEntity<VaultResponse> result = vaultClient.get() (1)
	.path("secret/my-secret") (1)
	.retrieve()
	.toEntity(); (2)

System.out.println("Response status: " + result.getStatusCode()); (3)
System.out.println("Response headers: " + result.getHeaders()); (3)
System.out.println("Contents: " + result.getBody()); (3)
1 指定された URL に対する GET リクエストを設定します
2 レスポンスを ResponseEntity に変換します
3 結果を出力する
val result = vaultClient.get() (1)
	.path("secret/my-secret") (1)
	.retrieve()
	.toEntity<String>() (2)

println("Response status: " + result.statusCode) (3)
println("Response headers: " + result.headers) (3)
println("Contents: " + result.body) (3)
1 指定された URL に対する GET リクエストを設定します
2 レスポンスを ResponseEntity に変換します
3 結果を出力する

エラー処理

デフォルトでは、VaultClient は 4xx または 5xx ステータスコードを含むレスポンスを取得するときに VaultClientResponseException のサブクラスをスローします。この動作は onStatus を使用してオーバーライドできます。

  • Java

  • Kotlin

String result = vaultClient.get()
	.path("secret/this-path-does-not-exist") (1)
	.retrieve()
	.onStatus(HttpStatusCode::is4xxClientError, (request, response) -> { (2)
		throw new MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()); (3)
	})
	.body(String.class);
1404 ステータスコードを返す URL の GET リクエストを作成する
2 すべての 4xx ステータスコードのステータスハンドラーをセットアップする
3 カスタム例外をスローする
val result = vaultClient.get()
	.path("secret/this-path-does-not-exist") (1)
	.retrieve()
	.onStatus(HttpStatusCode::is4xxClientError) { _, response -> (2)
		throw MyCustomRuntimeException(response.getStatusCode(), response.getHeaders()) } (3)
	.body<String>()
1404 ステータスコードを返す URL の GET リクエストを作成する
2 すべての 4xx ステータスコードのステータスハンドラーをセットアップする
3 カスタム例外をスローする