

:lock: Vaultex — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

:lock: Vaultex

==============

[![Hex.pm](https://img.shields.io/hexpm/v/vaultex.svg)](https://hex.pm/packages/vaultex)

[![Hex.pm](https://img.shields.io/hexpm/dt/vaultex.svg)](https://hex.pm/packages/vaultex)

A very simple elixir client that authenticates, reads, writes, and deletes

secrets from HashiCorp's Vault. As listed on [Vault

Libraries](https://www.vaultproject.io/api/libraries.html#elixir).

 Installation

---------------

The package can be installed as:

1) Add `vaultex` to your list of dependencies in `mix.exs`:

```

def deps do

 [{:vaultex, "~> 0.8"}]

end

```

2) Ensure `vaultex` is started before your application:

```

def application do

 [applications: [:vaultex]]

end

```

 Configuration

----------------

You can configure your vault endpoint with a single environment variable:

* `VAULT_ADDR`

Or a single application variable:

* `:vaultex, :vault_addr`

An example value for `VAULT_ADDR` is `http://127.0.0.1:8200`.

Alternatively the vault endpoint can be specified with environment variables:

* `VAULT_HOST`

* `VAULT_PORT`

* `VAULT_SCHEME`

Or application variables:

* `:vaultex, :host`

* `:vaultex, :port`

* `:vaultex, :scheme`

These default to `localhost`, `8200`, `http` respectively.

You can skip SSL certificate verification with `:vaultex, vault_ssl_verify: true` option or `VAULT_SSL_VERIFY=true` environment variable.

If you do want to use SSL verification, set the `VAULT_CACERT` environment

variable to the SSL certificate location. (See the [Vault

documentaion](https://www.vaultproject.io/docs/commands/#vault_cacert) for more

details.)

 Usages

---------

To read a secret you must provide the path to the secret and the authentication

backend and credentials you will use to login. See the

[Vaultex.Client.auth/2](https://hexdocs.pm/vaultex/Vaultex.Client.html#auth/2)

docs for supported auth backends.

Authenticate to different authentication backends.

```

iex> Vaultex.Client.auth(:app\_id, {app\_id, user\_id})

iex> Vaultex.Client.auth(:userpass, {username, password})

iex> Vaultex.Client.auth(:ldap, {username, password})

iex> Vaultex.Client.auth(:github, {github\_token})

iex> Vaultex.Client.auth(:approle, {role\_id, secret\_id})

iex> Vaultex.Client.auth(:token, {token})

iex> Vaultex.Client.auth(:kubernetes, %{jwt: "jwt", role: "role"})

iex> Vaultex.Client.auth(:radius, %{username: "user", password: "password"})

iex> Vaultex.Client.auth(:aws\_iam, {role, server})

```

Reading secret from authenticated backends.

```

iex> Vaultex.Client.read "secret/bar", :github, {github\_token}

{:ok, %{"value" => bar"}}

iex> Vaultex.Client.read\_dynamic "secret/dynamic/bar", :github, {github\_token}

{:ok,

 %{

 "data" => %{"value" => "bar"},

 "lease\_duration" => 60,

 "lease\_id" => "secret/dynamic/foo/b4z",

 "renewable" => true

}}

```

Additional actions on the secret.

```

iex> Vaultex.Client.renew\_lease("secret/dynamic/foo/b4z", 100, :github, {github\_token})

{:ok,

 %{

 "lease\_id" => "secret/dynamic/foo/b4z",

 "lease\_duration" => 160,

 "renewable" => true

}}

iex> Vaultex.Client.write "secret/foo", %{"value" => "bar"}, :app\_id, {app\_id, user\_id}

iex> Vaultex.Client.delete "secret/foo", :app\_id, {app\_id, user\_id}

```

 Notes for `aws_iam` method

-----------------------------

The AWS IAM authentication method requires you to have

[ExAws](https://github.com/ex-aws/ex_aws) installed as a dependency and

correctly configured. No additional ExAws modules are required. For more

details see the [Vault AWS

docs](https://www.vaultproject.io/docs/auth/aws.html).

* If `role` id set to `nil` Vault will try to infer the vault role to use.

* `server` may be set to `nil` or to the value to pass in the

`X-Vault-AWS-IAM-Server-ID` header.

 Releasing

------------

To release you need to bump the version and add some changes to the change log,

you can do this with:

```

mix eliver.bump

```





Vaultex — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex.ex#L1 "View Source")

========================================================================================================================

Interface with Hashicorp's vault.

 

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[start(type, args)](#start/2)

Callback implementation for [`Application.start/2`](https://hexdocs.pm/elixir/Application.html#c:start/2).

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#start/2 "Link to this function")

start(type, args)

=================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex.ex#L9 "View Source")

Callback implementation for [`Application.start/2`](https://hexdocs.pm/elixir/Application.html#c:start/2).

 





Vaultex.Auth — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex.Auth [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/auth.ex#L1 "View Source")

==================================================================================================================================

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[handle(method, credentials, state)](#handle/3)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#handle/3 "Link to this function")

handle(method, credentials, state)

==================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/auth.ex#L2 "View Source")





Vaultex.Auth.AWSIAM — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex.Auth.AWSIAM [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/aws_iam.ex#L1 "View Source")

============================================================================================================================================

Helper functions for AWS IAM instance metadata role authentication

 

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[credentials(role, server)](#credentials/2)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#credentials/2 "Link to this function")

credentials(role, server)

=========================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/aws_iam.ex#L9 "View Source")





Vaultex.Client — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex.Client [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L1 "View Source")

======================================================================================================================================

Provides a functionality to authenticate and read from a vault endpoint.

 

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[auth(method, credentials, timeout \\ 5000)](#auth/3)

Authenticates with vault using a tuple. This can be executed before attempting to read secrets from vault.

[child\_spec(init\_arg)](#child_spec/1)

Returns a specification to start this module under a supervisor.

[delete(key, auth\_method, credentials, timeout \\ 5000)](#delete/4)

Deletes a secret in Vault given a path.

[init(state)](#init/1)

Callback implementation for [`GenServer.init/1`](https://hexdocs.pm/elixir/GenServer.html#c:init/1).

[read(key, auth\_method, credentials, timeout \\ 5000)](#read/4)

Reads a secret from vault given a path.

[read\_dynamic(key, auth\_method, credentials, timeout \\ 5000)](#read_dynamic/4)

Reads a dynamic secret from vault given a path and returns the secret along with lease information.

[renew\_lease(lease\_id, increment, auth\_method, credentials, timeout \\ 5000)](#renew_lease/5)

Renews a lease for a dynamic secret

[start\_link()](#start_link/0)

[write(key, value, auth\_method, credentials, timeout \\ 5000)](#write/5)

Writes a secret to Vault given a path.

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#auth/3 "Link to this function")

auth(method, credentials, timeout \\ 5000)

==========================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L54 "View Source")

Specs

-----

```

auth(

  method :: :approle,

  credentials :: {role_id :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)(), secret_id :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()},

  timeout :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)() | nil

) :: {:ok | :error, [any](https://hexdocs.pm/elixir/typespecs.html#basic-types)()}

```

```

auth(

  method :: :app_id,

  credentials :: {app_id :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)(), user_id :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()},

  timeout :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)() | nil

) :: {:ok | :error, [any](https://hexdocs.pm/elixir/typespecs.html#basic-types)()}

```

```

auth(

  method :: :userpass,

  credentials :: {username :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)(), password :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()},

  timeout :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)() | nil

) :: {:ok | :error, [any](https://hexdocs.pm/elixir/typespecs.html#basic-types)()}

```

```

auth(

  method :: :github,

  credentials :: {github_token :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()},

  timeout :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)() | nil

) :: {:ok | :error, [any](https://hexdocs.pm/elixir/typespecs.html#basic-types)()}

```

```

auth(

  method :: :token,

  credentials :: {token :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)()},

  timeout :: [String.t](https://hexdocs.pm/elixir/String.html#t:t/0)() | nil

) :: {:ok, :authenticated}

```

Authenticates with vault using a tuple. This can be executed before attempting to read secrets from vault.

 Parameters

-------------

* method: Auth backend to use for authenticating, can be one of `:approle, :app_id, :userpass, :github, :token`

* credentials: A tuple or map used for authentication depending on the method, `{role_id, secret_id}` for `:approle`, `{app_id, user_id}` for `:app_id`, `{username, password}` for `:userpass`, `{github_token}` for `:github`, `{token}` for `:token`, or json-encodable map for unhandled methods, i.e. `%{jwt: "jwt", role: "role"}` for `:kubernetes`

* timeout: A integer greater than zero which specifies how many milliseconds to wait for a reply

 Examples

-----------

```

iex> Vaultex.Client.auth(:approle, {role\_id, secret\_id}, 5000)

{:ok, :authenticated}

iex> Vaultex.Client.auth(:app\_id, {app\_id, user\_id})

{:ok, :authenticated}

iex> Vaultex.Client.auth(:userpass, {username, password})

{:error, ["Something didn't work"]}

iex> Vaultex.Client.auth(:github, {github\_token})

{:ok, :authenticated}

iex> Vaultex.Client.auth(:jwt, %{jwt: jwt, role: role})

{:ok, :authenticated}

```

 

[Link to this function](#child_spec/1 "Link to this function")

child\_spec(init\_arg)

======================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L6 "View Source")

Returns a specification to start this module under a supervisor.

See [`Supervisor`](https://hexdocs.pm/elixir/Supervisor.html).

 

[Link to this function](#delete/4 "Link to this function")

delete(key, auth\_method, credentials, timeout \\ 5000)

=======================================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L216 "View Source")

Deletes a secret in Vault given a path.

 Parameters

-------------

* key: A String path where the secret will be deleted.

* auth\_method and credentials: See Vaultex.Client.auth

* timeout: A integer greater than zero which specifies how many milliseconds to wait for a reply

 Examples

-----------

```

iex> Vaultex.Client.delete("secret/foo", :app\_role, {role\_id, secret\_id}, 5000)

:ok

iex> Vaultex.Client.delete("secret/foo", :app\_id, {app\_id, user\_id})

:ok

```

 

[Link to this function](#init/1 "Link to this function")

init(state)

===========

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L18 "View Source")

Callback implementation for [`GenServer.init/1`](https://hexdocs.pm/elixir/GenServer.html#c:init/1).

 

[Link to this function](#read/4 "Link to this function")

read(key, auth\_method, credentials, timeout \\ 5000)

=====================================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L84 "View Source")

Reads a secret from vault given a path.

 Parameters

-------------

* key: A String path to be used for querying vault.

* auth\_method and credentials: See Vaultex.Client.auth

* timeout: A integer greater than zero which specifies how many milliseconds to wait for a reply

 Examples

-----------

```

iex> Vaultex.Client.read("secret/foobar", :approle, {role\_id, secret\_id}, 5000)

{:ok, %{"value" => "bar"}}

iex> Vaultex.Client.read("secret/foo", :app\_id, {app\_id, user\_id})

{:ok, %{"value" => "bar"}}

iex> Vaultex.Client.read("secret/baz", :userpass, {username, password})

{:error, ["Key not found"]}

iex> Vaultex.Client.read("secret/bar", :github, {github\_token})

{:ok, %{"value" => "bar"}}

iex> Vaultex.Client.read("secret/bar", :plugin\_defined\_auth, credentials)

{:ok, %{"value" => "bar"}}

```

 

[Link to this function](#read_dynamic/4 "Link to this function")

read\_dynamic(key, auth\_method, credentials, timeout \\ 5000)

==============================================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L117 "View Source")

Reads a dynamic secret from vault given a path and returns the secret along with lease information.

 Parameters

-------------

* key: A String path to be used for querying vault.

* auth\_method and credentials: See Vaultex.Client.auth

* timeout: A integer greater than zero which specifies how many milliseconds to wait for a reply

 Examples

-----------

```

iex> Vaultex.Client.read\_dynamic("secret/dynamic/foobar", :approle, {role\_id, secret\_id}, 5000)

{:ok, %{"data" => %{"value" => "bar"}, "lease\_duration" => 60, "lease\_id" => "secret/dynamic/foo/b4z", "renewable" => true}}

iex> Vaultex.Client.read\_dynamic("secret/dynamic/foo", :app\_id, {app\_id, user\_id})

{:ok, %{"data" => %{"value" => "bar"}, "lease\_duration" => 60, "lease\_id" => "secret/dynamic/foo/b4z", "renewable" => true}}

iex> Vaultex.Client.read\_dynamic("secret/dynamic/baz", :userpass, {username, password})

{:error, ["Key not found"]}

iex> Vaultex.Client.read\_dynamic("secret/dynamic/bar", :github, {github\_token})

{:ok, %{"data" => %{"value" => "bar"}, "lease\_duration" => 60, "lease\_id" => "secret/dynamic/foo/b4z", "renewable" => true}}

iex> Vaultex.Client.read\_dynamic("secret/dynamic/bar", :plugin\_defined\_auth, credentials)

{:ok, %{"data" => %{"value" => "bar"}, "lease\_duration" => 60, "lease\_id" => "secret/dynamic/foo/b4z", "renewable" => true}}

```

 

[Link to this function](#renew_lease/5 "Link to this function")

renew\_lease(lease\_id, increment, auth\_method, credentials, timeout \\ 5000)

==============================================================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L152 "View Source")

Renews a lease for a dynamic secret

 Parameters

-------------

* lease\_id: A String that is the lease ID returned when reading a dynamic secret

* increment: An Integer that represents the time in seconds to extend the lease by

* auth\_method and credentials: See Vaultex.Client.auth

* timeout: A integer greater than zero which specifies how many milliseconds to wait for a reply

 Examples

-----------

```

iex> Vaultex.Client.renew\_lease("secret/dynamic/foo/b4z", 100, :app\_role, {role\_id, secret\_id}, 5000)

{:ok, %{"lease\_id" => "secret/dynamic/foo/b4z", "lease\_duration" => 160, "renewable" => true}}

```

 

[Link to this function](#start_link/0 "Link to this function")

start\_link()

=============

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L14 "View Source")

[Link to this function](#write/5 "Link to this function")

write(key, value, auth\_method, credentials, timeout \\ 5000)

=============================================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/client.ex#L184 "View Source")

Writes a secret to Vault given a path.

 Parameters

-------------

* key: A String path where the secret will be written.

* value: A String => String map that will be stored in Vault

* auth\_method and credentials: See Vaultex.Client.auth

* timeout: A integer greater than zero which specifies how many milliseconds to wait for a reply

 Examples

-----------

```

iex> Vaultex.Client.write("secret/foo", %{"value" => "bar"}, :app\_role, {role\_id, secret\_id}, 5000)

:ok

iex> Vaultex.Client.write("secret/foo", %{"value" => "bar"}, :app\_id, {app\_id, user\_id})

:ok

```

 





Vaultex.Delete — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex.Delete [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/delete.ex#L1 "View Source")

======================================================================================================================================

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[handle(key, state)](#handle/2)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#handle/2 "Link to this function")

handle(key, state)

==================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/delete.ex#L2 "View Source")





Vaultex.Leases — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex.Leases [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/leases.ex#L1 "View Source")

======================================================================================================================================

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[handle(atom, lease, increment, state)](#handle/4)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#handle/4 "Link to this function")

handle(atom, lease, increment, state)

=====================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/leases.ex#L2 "View Source")





Vaultex.Read — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex.Read [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/read.ex#L1 "View Source")

==================================================================================================================================

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[handle(key, state)](#handle/2)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#handle/2 "Link to this function")

handle(key, state)

==================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/read.ex#L2 "View Source")





Vaultex.RedirectableRequests — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex.RedirectableRequests [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/redirectable_requests.ex#L1 "View Source")

===================================================================================================================================================================

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[request(method, url, params, headers, options \\ [])](#request/5)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#request/5 "Link to this function")

request(method, url, params, headers, options \\ [])

====================================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/redirectable_requests.ex#L6 "View Source")





Vaultex.Test.TestDoubles.MockHTTPoison — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex.Test.TestDoubles.MockHTTPoison [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/test_doubles/mock_httpoison.ex#L1 "View Source")

===========================================================================================================================================================================

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[request(atom, url, params, arg4, arg5)](#request/5)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#request/5 "Link to this function")

request(atom, url, params, arg4, arg5)

======================================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/test_doubles/mock_httpoison.ex#L3 "View Source")





Vaultex.Write — vaultex v1.0.1

try { if(localStorage.getItem('night-mode') === 'true') document.body.className += ' night-mode'; } catch (e) { }

vaultex v1.0.1

Vaultex.Write [View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/write.ex#L1 "View Source")

====================================================================================================================================

[Link to this section](#summary)

 Summary

==========================================

[Functions](#functions)

------------------------

[handle(key, value, state)](#handle/3)

[Link to this section](#functions)

Functions

=============================================

[Link to this function](#handle/3 "Link to this function")

handle(key, value, state)

=========================

[View Source](https://github.com/findmypast/vaultex/blob/v1.0.1/lib/vaultex/write.ex#L2 "View Source")

