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:


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


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)
  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