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:



134
135
136
137
138
139
# File 'lib/chef/secret_fetcher/hashi_vault.rb', line 134

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



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
120
121
122
123
124
125
126
127
128
# File 'lib/chef/secret_fetcher/hashi_vault.rb', line 85

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