Vaultx.Sys.Init (Vaultx v0.7.0)

View Source

HashiCorp Vault initialization operations.

This module provides initialization capabilities for Vault, allowing you to initialize a new Vault server and generate the initial root token and unseal keys. Vault must be initialized before it can be unsealed and used.

Initialization Operations

Core Functionality

  • Initialize Vault: Set up a new Vault server with root token and unseal keys
  • Check Status: Determine if Vault has been initialized
  • Shamir Secret Sharing: Configure threshold-based unsealing
  • PGP Encryption: Encrypt unseal keys and root token with PGP keys

Initialization Process

  • One-time Operation: Can only be performed once per Vault server
  • Root Token Generation: Creates the initial root token for administration
  • Unseal Key Generation: Creates key shares for unsealing Vault
  • Threshold Configuration: Sets minimum number of keys required to unseal

Important Security Notes

Critical Security Considerations

  • Initialization is a one-time operation that cannot be repeated
  • Root token has unlimited privileges and should be secured immediately
  • Unseal keys should be distributed among trusted operators
  • Consider using PGP encryption for key protection

Key Management

  • Store unseal keys securely and separately
  • Distribute keys among multiple trusted operators
  • Consider using auto-unseal mechanisms for production
  • Revoke and regenerate root token after initial setup

API Compliance

Fully implements HashiCorp Vault Init API:

Usage Examples

Basic Initialization

{:ok, init_result} = Vaultx.Sys.Init.initialize(%{
  secret_shares: 5,
  secret_threshold: 3
})

# Store these securely!
root_token = init_result.root_token
unseal_keys = init_result.keys

PGP-Encrypted Initialization

pgp_keys = [
  "-----BEGIN PGP PUBLIC KEY BLOCK-----...",
  "-----BEGIN PGP PUBLIC KEY BLOCK-----..."
]

{:ok, init_result} = Vaultx.Sys.Init.initialize(%{
  secret_shares: 3,
  secret_threshold: 2,
  pgp_keys: pgp_keys,
  root_token_pgp_key: "-----BEGIN PGP PUBLIC KEY BLOCK-----..."
})

Check Initialization Status

case Vaultx.Sys.Init.status() do
  {:ok, %{initialized: true}} ->
    IO.puts("Vault is already initialized")
  {:ok, %{initialized: false}} ->
    IO.puts("Vault needs to be initialized")
  {:error, error} ->
    IO.puts("Error checking status: #{error.message}")
end

Initialization Response

The initialization operation returns:

  • keys: Array of unseal key shares (encrypted if PGP keys provided)
  • keys_base64: Base64-encoded unseal keys
  • root_token: Initial root token (encrypted if PGP key provided)
  • recovery_keys: Recovery keys (for auto-unseal configurations)
  • recovery_keys_base64: Base64-encoded recovery keys

Security Best Practices

Immediate Actions After Initialization

  1. Securely store the root token and unseal keys
  2. Distribute unseal keys among trusted operators
  3. Unseal Vault using the required threshold of keys
  4. Create initial policies and authentication methods
  5. Revoke the initial root token and use policy-based access

Production Considerations

  • Use auto-unseal mechanisms (Cloud KMS, HSM) when possible
  • Implement proper key rotation procedures
  • Monitor and audit all initialization activities
  • Use PGP encryption for additional key protection

Summary

Types

Initialization options.

Initialization result.

Initialization status.

Functions

Initialize a new Vault server.

Check the initialization status of Vault.

Types

init_opts()

@type init_opts() :: %{
  :secret_shares => pos_integer(),
  :secret_threshold => pos_integer(),
  optional(:pgp_keys) => [String.t()],
  optional(:root_token_pgp_key) => String.t(),
  optional(:stored_shares) => pos_integer(),
  optional(:recovery_shares) => pos_integer(),
  optional(:recovery_threshold) => pos_integer(),
  optional(:recovery_pgp_keys) => [String.t()]
}

Initialization options.

init_result()

@type init_result() :: %{
  :keys => [String.t()],
  :keys_base64 => [String.t()],
  :root_token => String.t(),
  optional(:recovery_keys) => [String.t()],
  optional(:recovery_keys_base64) => [String.t()]
}

Initialization result.

init_status()

@type init_status() :: %{initialized: boolean()}

Initialization status.

Functions

initialize(opts, request_opts \\ [])

@spec initialize(init_opts(), Vaultx.Types.options()) ::
  {:ok, init_result()} | {:error, Vaultx.Base.Error.t()}

Initialize a new Vault server.

This endpoint initializes a new Vault. The Vault must not have been previously initialized. The recovery options, as well as the stored shares option, are only available when using Vault Enterprise.

Parameters

  • opts - Initialization options
    • :secret_shares - Number of shares to split the root key into (required)
    • :secret_threshold - Number of shares required to reconstruct the root key (required)
    • :pgp_keys - Array of PGP public keys to encrypt the unseal keys
    • :root_token_pgp_key - PGP public key to encrypt the root token
    • :stored_shares - Number of shares that should be encrypted and stored (Enterprise)
    • :recovery_shares - Number of recovery shares (Enterprise)
    • :recovery_threshold - Number of recovery shares required (Enterprise)
    • :recovery_pgp_keys - PGP keys for recovery shares (Enterprise)

Returns

Returns {:ok, init_result()} with initialization data, or {:error, Error.t()} on failure.

Examples

# Basic initialization
{:ok, result} = Vaultx.Sys.Init.initialize(%{
  secret_shares: 5,
  secret_threshold: 3
})

# With PGP encryption
{:ok, result} = Vaultx.Sys.Init.initialize(%{
  secret_shares: 3,
  secret_threshold: 2,
  pgp_keys: ["-----BEGIN PGP PUBLIC KEY BLOCK-----..."],
  root_token_pgp_key: "-----BEGIN PGP PUBLIC KEY BLOCK-----..."
})

Important Notes

  • This operation can only be performed once per Vault server
  • Store the returned keys and root token securely
  • Distribute unseal keys among trusted operators
  • Consider using PGP encryption for additional security

status(opts \\ [])

@spec status(Vaultx.Types.options()) ::
  {:ok, init_status()} | {:error, Vaultx.Base.Error.t()}

Check the initialization status of Vault.

This endpoint returns the initialization status of Vault. It returns a 200 response if Vault is initialized and a 200 response if Vault is not initialized.

Parameters

  • opts - Request options (optional)

Returns

Returns {:ok, init_status()} with initialization status, or {:error, Error.t()} on failure.

Examples

{:ok, status} = Vaultx.Sys.Init.status()

if status.initialized do
  IO.puts("Vault is initialized")
else
  IO.puts("Vault needs initialization")
end