module Jerakia::Encryption::Vault

Attributes

approle_token[R]
vault_ssl_cert[R]
vault_ssl_key[R]

Public Instance Methods

authenticate() click to toggle source
# File lib/jerakia/encryption/vault.rb, line 84
def authenticate
  unless token_configured?
    login if approle_token.nil?
  end
end
config() click to toggle source
# File lib/jerakia/encryption/vault.rb, line 19
def config
  {
    "vault_keyname" => "jerakia",
    "vault_addr" => "https://127.0.0.1:8200",
    "vault_use_ssl" => true,
    "vault_ssl_verify" => true,
    "vault_token" => ENV['VAULT_TOKEN'] || nil,
    "vault_api_version" => 1
 }.merge(self.class.config)
end
decrypt(string) click to toggle source
# File lib/jerakia/encryption/vault.rb, line 151
def decrypt(string)
  response = vault_post({ 'ciphertext' => string}, :decrypt)
  response_data=response['data']
  Base64.decode64(response_data['plaintext'])
end
encrypt(plain) click to toggle source
# File lib/jerakia/encryption/vault.rb, line 157
def encrypt(plain)
  encoded = Base64.encode64(plain)
  response = vault_post({ 'plaintext' => encoded}, :encrypt)
  response_data=response['data']
  response_data['ciphertext']
end
endpoint(action) click to toggle source
# File lib/jerakia/encryption/vault.rb, line 90
def endpoint(action)
  {
    :decrypt => "transit/decrypt/#{config['vault_keyname']}",
    :encrypt => "transit/encrypt/#{config['vault_keyname']}",
    :login   => "auth/approle/login"
  }[action]
end
login() click to toggle source
# File lib/jerakia/encryption/vault.rb, line 40
def login
  Jerakia.log.debug('Requesting new token from Vault server')
  role_id = config['vault_role_id']
  secret_id = config['vault_secret_id']

  login_data = { "role_id" => role_id }
  login_data['secret_id'] = secret_id unless secret_id.nil?

  response = vault_post(login_data, :login, false)
  @approle_token = response['auth']['client_token']
  Jerakia.log.debug("Recieved authentication token from vault server, ttl: #{response['auth']['lease_duration']}")
end
parse_response(response) click to toggle source
# File lib/jerakia/encryption/vault.rb, line 104
def parse_response(response)
  body = JSON.load(response.body)
  if response.code_type == Net::HTTPOK
    return body
  else
    if response.code == "403"
      raise Jerakia::Encryption::Vault::AuthenticationError, body
    end
    if body['errors'].is_a?(Array)
      message = body['errors'].join("\n")
    else
      message = "Failed to decrypt entry #{body}"
    end
    raise Jerakia::EncryptionError, "Error decrypting data from Vault: #{message}"
  end
end
read_file(file) click to toggle source
# File lib/jerakia/encryption/vault.rb, line 57
def read_file(file)
  raise Jerakia::EncryptionError, "Cannot read #{file}" unless File.exists?(file)
  File.read(file)
end
signiture() click to toggle source
# File lib/jerakia/encryption/vault.rb, line 15
def signiture
  /^vault:v[0-9]:[^ ]+$/
end
ssl?() click to toggle source
# File lib/jerakia/encryption/vault.rb, line 53
def ssl?
  config['vault_use_ssl']
end
ssl_cert() click to toggle source
# File lib/jerakia/encryption/vault.rb, line 68
def ssl_cert
  return nil if config['vault_ssl_cert'].nil?
  @vault_ssl_cert ||= read_file(config['vault_ssl_cert'])
  vault_ssl_cert
end
ssl_key() click to toggle source
# File lib/jerakia/encryption/vault.rb, line 62
def ssl_key
  return nil if config['vault_ssl_key'].nil?
  @vault_ssl_key ||= read_file(config['vault_ssl_key'])
  vault_ssl_key
end
token() click to toggle source
# File lib/jerakia/encryption/vault.rb, line 79
def token
  authenticate
  config['vault_token'] || approle_token
end
token_configured?() click to toggle source
# File lib/jerakia/encryption/vault.rb, line 75
def token_configured?
  not config['vault_token'].nil?
end
url_path(action) click to toggle source
# File lib/jerakia/encryption/vault.rb, line 98
def url_path(action)
  vault_url(endpoint(action))
end
vault_post(data, action, use_token=true, headers={}) click to toggle source
# File lib/jerakia/encryption/vault.rb, line 121
def vault_post(data, action, use_token=true, headers={})
  url = url_path(action)
  http_options = {}

  if ssl?
    http_options = {
      :ssl        => true,
      :ssl_verify => config['vault_ssl_verify'],
      :ssl_cert   => ssl_cert,
      :ssl_key    => ssl_key,
    }
  end

  Jerakia.log.debug("Connecting to vault at #{url}")
  tries = 0
  begin
    headers['X-Vault-Token'] = token if use_token
    tries += 1
    parse_response Jerakia::Util::Http.post(url, data, headers, http_options)
  rescue Jerakia::Encryption::Vault::AuthenticationError => e
    Jerakia.log.debug("Encountered Jerakia::Encryption::Vault::AuthenticationError, retrying with new token (#{tries})")

    login
    retry if tries < 2
    raise
  rescue Jerakia::HTTPError => e
    raise Jerakia::EncryptionError, "Error connecting to Vault service: #{e.message}"
  end
end
vault_url(endpoint) click to toggle source
# File lib/jerakia/encryption/vault.rb, line 32
def vault_url(endpoint)
  uri = []
  uri << config['vault_addr']
  uri << "v#{config['vault_api_version']}"
  uri << endpoint
  uri.flatten.join("/")
end