Is there an equivalent to Rails 5.2 'Credentials' library?

I’m just wondering if anyone knows if there’s an equivalent approach / library in Elixir to credentials that came out in Rails 5.2

I dismissed it at first but since I’ve been battling with Ansible and setting tonnes of environment variables by using ansible-vault edit ... on a project I’ve realised it’s quite cool. It means I don’t really need the indirection and complexity that Ansible brings to just changing a few configuration variables.

If you’ve no idea what it is it’s just an encrypted yaml file. Your encrypted yaml can be checked into your repo as it’s encrypted, so deploying configs is suddenly easy.

You edit config/credentials.yml.enc with rails credentials:edit which decrypts the file and let’s you change the config vars and carry on. I like the idea of being able to do this in Elixir apps too. Is there anything out there or is this a terrible idea?

2 Likes

I like this idea. I think it shouldn’t be too difficult to implement with elixir … If you use distillery, you would probably copy the encrypted config into release’s priv/ and decrypt / read it into memory during application’s startup hooks. Then in each of your apps’ init callbacks you would have access to the decrypted config.

Cool. I like the sound of that. I might have a go at doing it when I get some free time.

2 Likes

Hello everyone :smile: Rails 5.2 introduced a new feature called Credentials and I think that is a good feature for Phoenix (or elixir) sometimes we have a build server and prod server in build server we need environment variables to build a project with Distillery, the point is that’s not easy to change environment variables to each project pipeline and usually we use (puppet, chef, etc) for that things. I’ll be very happy if have a possibility to add the project credentials together with the project (encrypted). To learn more about credentials.

rails/rails#30067

1 Like

Can you provide an example for those secret settings?

Config:

credentials :dev, 
  username: "dev_user",
  password: "user123"
  aws: [secret_access_key: "123467"]

credentials :prod, 
  username: "example"
  password: "hardpassword123"

API:

Credential.get(:username)
Credential.get(:password)
Credential.get([:aws, :secret_access_key])

You need your configs at the run-time, so you could use env variables for this.
I can recommend confex

config :credentials, 
  username: {:system, "USERNAME", "dev_user"},
  password: {:system, "PASSWORD", "dev_user"}.
  aws: [secret_access_key: {:system, "AWS_SECRET_KEY", "1234567"}]

At startup of you App, just do

defmodule MyApp do
  use Application

  def start(_type, _args) do
    # Replace Application environment with resolved values
    Confex.resolve_env!(:credentials)

    # ...
  end
end

This way you will be able to access your configs via the usual
Application.get_env(:credentials, :username)

2 Likes

Have we had the .secret files for a while? That seems mostly equivalent, except that it’s not supposed to go in your repo.

Doesn’t seem like it would take much to do an encrypt/decrypt on that file.

I didn’t know about confex, seems very useful.

1 Like

Hopping in this a little late, but I just created my first Elixir library and it handles encrypted secrets much like Rails! Let me know what you think: https://github.com/kieraneglin/encrypted_secrets_ex

10 Likes