プロパティソース

Vault はさまざまな方法で使用できます。特定の使用例の 1 つは、暗号化されたプロパティを格納するために Vault を使用することです。Spring Vault は、Spring の PropertySource の抽象化を使用して構成プロパティを取得するためのプロパティソースとして Vault をサポートします。

他のプロパティソースの Vault 内に格納されたプロパティを参照したり、@Value(…) で値の挿入を使用したりできます。Vault 内に格納されたデータを必要とする Bean をブートストラップするときは、特別な注意が必要です。Vault からプロパティを取得するには、その時点で VaultPropertySource を初期化する必要があります。
Spring Boot/Spring Cloud ユーザーは、アプリケーションの起動時にさまざまなプロパティソースを初期化する Spring Cloud Vault [GitHub] (英語) の構成統合の恩恵を受けることができます。

VaultPropertySource の登録

Spring Vault は、プロパティを取得するために Vault と共に使用される VaultPropertySource を提供します。ネストされた data 要素を使用して、Vault に格納および暗号化されたプロパティを公開します。

ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new VaultPropertySource(vaultTemplate, "secret/my-application"));

上記のコードでは、VaultPropertySource が検索で最高の優先順位で追加されています。"foo" プロパティが含まれている場合は、他の PropertySource の foo プロパティよりも先に検出されて返されます。MutablePropertySources は、一連のプロパティソースの正確な操作を可能にする多数のメソッドを公開します。

@VaultPropertySource

@VaultPropertySource アノテーションは、PropertySource を Spring の Environment に追加して @Configuration クラスと組み合わせて使用するための便利で宣言的なメカニズムを提供します。

@VaultPropertySource は secret/my-application などの Vault パスを使用し、ノードに格納されているデータを PropertySource に公開します。@VaultPropertySource は、リースに関連付けられたシークレット (つまり、mysql バックエンドからの資格情報) のリース更新と、ターミナルリースの有効期限が切れたときの資格情報のローテーションをサポートします。デフォルトでは、リースの更新は無効になっています。

例 1: Vault に格納されるプロパティ
{
  // …

  "data": {
    "database": {
      "password": ...
    },
    "user.name": ...,
  }

  // …
}
例 2: @VaultPropertySource の宣言
@Configuration
@VaultPropertySource("secret/my-application")
public class AppConfig {

    @Autowired Environment env;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setUser(env.getProperty("user.name"));
        testBean.setPassword(env.getProperty("database.password"));
        return testBean;
    }
}
例 3: クレデンシャルローテーションとプレフィックスを使用した @VaultPropertySource の宣言
@Configuration
@VaultPropertySource(value = "aws/creds/s3-access",
                     propertyNamePrefix = "aws.",
                     renewal = Renewal.ROTATE)
public class AppConfig {
  // provides aws.access_key and aws.secret_key properties
}
generic シークレットバックエンドから取得したシークレットは、TTL (refresh_interval) に関連付けられていますが、リース ID には関連付けられていません。Spring Vault の PropertySource は、TTL に達すると汎用シークレットをローテーションします。
@VaultPropertySource を使用して、バージョン管理された Key-Value バックエンドから最新のシークレットバージョンを取得できます。パスに data/ セグメントを含めないようにしてください。

次の例に示すように、@VaultPropertySource パスに存在する ${ …​ } プレースホルダーは、環境に対してすでに登録されている一連のプロパティソースに対して解決されます。

例 4: プレースホルダーを使用した @VaultPropertySource パスの宣言
@Configuration
@VaultPropertySource(value = "aws/creds/${my.placeholder:fallback/value}",
                     propertyNamePrefix = "aws.",
                     renewal = Renewal.ROTATE)
public class AppConfig {
}

my.placeholder がすでに登録されているプロパティソース(システムプロパティや環境変数など)のいずれかに存在すると仮定すると、プレースホルダーは対応する値に解決されます。そうでない場合は、fallback/value がデフォルトとして使用されます。デフォルトが指定されておらず、プロパティを解決できない場合、IllegalArgumentException がスローされます。

特定の状況では、@VaultPropertySource アノテーションを使用するときに、プロパティソースの順序を厳密に制御することが不可能または実際的でない場合があります。例: 上記の @Configuration クラスがコンポーネントスキャンによって登録された場合、順序を予測することは困難です。このような場合、オーバーライドが重要な場合は、プログラムによる PropertySource API の使用に戻すことをお勧めします。詳細については、ConfigurableEnvironment (Javadoc) および MutablePropertySources (Javadoc) を参照してください。