Class: Chef::SecretFetcher::HashiVault

Inherits:
Base
  • Object
show all
Defined in:
lib/chef/secret_fetcher/hashi_vault.rb

Direct Known Subclasses

AKeylessVault

Instance Attribute Summary

Attributes inherited from Base

#config, #run_context

Instance Method Summary collapse

Methods inherited from Base

#fetch, #initialize

Constructor Details

This class inherits a constructor from Chef::SecretFetcher::Base

Instance Method Details

#do_fetch(identifier, _version) ⇒ Hash

be the full path of that secret, eg ‘secret/example’

Parameters:

  • identifier (String)

    Identifier of the secret to be fetched, which should

  • _version (String)

    not used in this implementation

Returns:

  • (Hash)

    containing key/value pairs stored at the location given in ‘identifier’

Raises:

[View source]

125
126
127
128
129
130
# File 'lib/chef/secret_fetcher/hashi_vault.rb', line 125

def do_fetch(identifier, _version)
  result = Vault.logical.read(identifier)
  raise Chef::Exceptions::Secret::FetchFailed.new("No secret found at #{identifier}. Check to ensure that there is a secrets engine configured for that path") if result.nil?

  result.data
end

#validate!Object

Validate and authenticate the current session using the configured auth strategy and parameters

[View source]

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/chef/secret_fetcher/hashi_vault.rb', line 76

def validate!
  if config[:vault_addr].nil?
    raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide the Vault address in the configuration as :vault_addr")
  end

  Vault.address = config[:vault_addr]
  Vault.namespace = config[:namespace] unless config[:namespace].nil?

  case config[:auth_method]
  when :approle
    unless config[:approle_name] || config[:approle_id]
      raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide the :approle_name or :approle_id in the configuration with :auth_method set to :approle")
    end

    # When :approle_id and :approle_secret_id are both specified, all pieces are present which are needed to authenticate using an approle.
    #  If either is missing, we need to authenticate to Vault to get the missing pieces with the :approle_name and optionally :token.
    unless config[:approle_id] && config[:approle_secret_id]
      if config[:approle_name].nil?
        raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide the :approle_name in the configuration when :approle_id and :approle_secret_id are not both present with :auth_method set to :approle")
      end

      Vault.token = config[:token] unless config[:token].nil?
    end

    approle_id = config[:approle_id] || Vault.approle.role_id(config[:approle_name])
    approle_secret_id = config[:approle_secret_id] || Vault.approle.create_secret_id(config[:approle_name]).data[:secret_id]

    Vault.auth.approle(approle_id, approle_secret_id)
  when :token
    if config[:token].nil?
      raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide the token in the configuration as :token")
    end

    Vault.auth.token(config[:token])
  when :iam_role, nil
    if config[:role_name].nil?
      raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide the authenticating Vault role name in the configuration as :role_name")
    end

    Vault.auth.aws_iam(config[:role_name], Aws::InstanceProfileCredentials.new, Vault.address)
  else
    raise Chef::Exceptions::Secret::ConfigurationInvalid.new("Invalid :auth_method provided.  You gave #{config[:auth_method]}, expected one of :#{SUPPORTED_AUTH_TYPES.join(", :")} ")
  end
end