Ptolemy is an application environment manager for your Elixir projects. It provides a simple interface to authenticate and interact (via CRUD operations) with a remote backend that stores secrets and sensitive information. As well as providing these functionality Ptolemy also features a dynamic application environment variable loader that loads secrets from a remote backend such as Hashicorp's Vault and handle its lifecycle by refreshing the secret when they are about to expire.
- Application environment management.
- Authentication through Google's Cloud IAP
- Hashicorp Vault integration (tested against Vault v0.11.5 but will support v0.10.4 and later):
- Supported authentication methods:
- GCP
- Approle
- Supported secret engines:
- Key-Value Version 2 (KV2)
- Public Key Infrastructure (PKI)
- Google Cloud Platform (GCP)
- Supported authentication methods:
Ptolemy is available on hex you can install it by following these steps:
- Add ptolemy to your
deps
def deps do
[
{:ptolemy, "~> 0.2.0"}
]
end
- Run
mix deps.get && mix deps.compile
Within examples/
we provide an example repository called Simple app. The configuration file in the project shall be served as an example for key values and PKI engine. More configuration specifications can be found in the Configuration section below.
Follow the README.md
found in examples/
instructions to get started.
You will need to configure the application to point to remote backend. Edit the config.exs
to point to remote backend.
Start iex with Ptolemy's modules loaded by entering:
bash-3.2$ cd ptolemy/ && iex -S mix
Erlang/OTP 21 [erts-10.1.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Interactive Elixir (1.7.4) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> {:ok, server} = Ptolemy.start(:server1, :production)
iex(2)> Ptolemy.read(server, :kv_engine1, [:ptolemy, true])
{:ok, %{"test" => "foo"}}
There are two configuration blocks that exist in ptolemy as of version 0.2
. Both are independent of one another and do not have to be used at the same time.
:vaults
configuration is responsible for holding the Vault server configurations:loader
configuration manages the dynamic loading of secrets from providers, e.g. Vault, System Environment
In order to get the most of the library, we recommend to configrure both blocks. Example configuration files can be found in config/test.exs
, examples/config/config.exs
.
The :vaults
key configures ptolemy various backend providers (Hashicorp vault is the only backend currently supported). Each key within the :vaults
block represents a specific server in which ptolemy can query to retrieve values such as application secrets currently stored in vault.
config :ptolemy, vaults: [
server2: %{
vault_url: "https://test-vault.com",
engines: [
kv_engine1: %{
engine_type: :KV,
engine_path: "secret/",
secrets: %{
test_secret: "/test_secret"
}
},
gcp_engine1: %{
engine_type: :GCP,
engine_path: "gcp/"
},
pki_engine1: %{
engine_type: :PKI,
engine_path: "pki/",
roles: %{
test_role1: "/role1"
}
}
],
auth: %{
method: :Approle,
credentials: %{
role_id: "test",
secret_id: "test"
},
auto_renew: true,
opts: []
}
}
]
Additional details about usage within the :vaults
configuration block can be found in Ptolemy
's module docs.
If Ptolemy.Loader
is being used to dynamically manage application environment variables, then an extra configuration block should also be added:
Specifying this block will allow Ptolemy.Loader
to populate the application specific env vars at runtime.
config :ptolemy, loader: [
env: [
{{:app_name, :secret_key}, {Ptolemy.Providers.SystemEnv, "PATH"}},
{{:app_name, :another_secret_key}, {Ptolemy.Providers.Vault, [:engine_name, [opt1, opt2], [key1, key2]]}},
# ...
]
]
Additional details about usage the keys within the :loader
configuration block can be found in Ptolemy.Loader
's module doc.
Running a local dev environment of ptolemy requires:
- JQ
- Docker and docker-compose
Before developing you must issue these commands:
- Start up the dockerized version of vault via docker-compose
$ docker-compose up
- In a different terminal issue:
$ . ./vault_init.sh
This will setup a local vault server accessible at http://localhost:8200
along with setting up a the docker-composed vault server with a testing approle, the credentials for the role will be exported to your environment variable of the current shell used SECRET_ID
and ROLE_ID
.
What do I do if I get Authentication Failed
with error role requires that JWTs must expire within X seconds
for GCP authentication?
There is something wrong with your system time, please make sure that you are using a reputable Network Time Protocol (NTP) server as your time provider or force an update for you system type.