kreiling.io

kreiling.io

Manually Load an Elixir Config File at Runtime

I’d like to discuss how to manually load Elixir configuration files at runtime.

Macro Intent

I want to load an elixir config file (something that looks like, for example, config/config.exs) at runtime, and load that into the application configuration.

Micro Intent

Ultimately, I want to write a Config.Provider implementation which fetches the contents of a secret stored in AWS secrets manager. I’d like for those contents to be an Elixir script with import Config at the top, followed by configuration defined the same way you would in a project’s config/config.exs file. I then want to load that configuration into the current (running!) application’s configuration.

Questions & Discussion

  • Let’s assume that I can load the secret configuration file from anywhere into a binary with an arbitrary Config.Provider implementation (ignore SecretsManager for now). How would I go about compiling it and loading it into the application configuration?
  • What do you think of this approach to secret management, at least in theory?
  • What (at least roughly) do you do for secret management in your Elixir and/or Phoenix applications?

My Take

Let’s consider an alternative Config.Provider implementation: instead load a YAML file, parse it, and translate it into a keyword list to merge into the current config. In my eyes that has a few downsides that I dislike:

  1. Added dependency on a YAML parser
  2. Designing how that YAML is structured is not a trivial task
  3. It’s a roundabout way to get to what I ultimately want, which is just to load configuration from a remote location into the current node’s application configuration.

These are my thoughts. Let me know yours!

Most Liked

factoryd

factoryd

We run in ECS and use param store for our secrets. You can simply set environment variables in your task definition under secrets.

"containerDefinitions": [
      "secrets": [
        {
          "valueFrom": "/param/path",
          "name": "VARIABLE_NAME"
        }
]

from there I put them in prod.exs as configuration.

I know valueFrom supports secret manager too.

EDIT: Pass sensitive data to an Amazon ECS container - Amazon Elastic Container Service

factoryd

factoryd

Oh I’m willing to brainstorm. I’m completely isolated and bored just like you! :stuck_out_tongue:

I do run as a release.

I actually just created a toy app to investigate possibilities right now.

kreiling.io

kreiling.io

So I’ve thought about it some more and looked at some docs in the Code module and there’s a warning about evaluating code coming from the network. Dang, seems like loading data from SecretsManager would be a bad idea from a security perspective…

Still - could there be another way??

I want to see if it’s possible. My current solution would be to have the config provider do:

defmodule MyConfigProvider do
  alias ExAws.SecretsManager, as: Secrets

  def init(secret_id) when is_binary(secret_id), do: secret_id

  def load(config, secret_id) do
    %{"SecretValue" => raw_elixir_code} = Secrets.get_secret_value(secret_id) |> ExAws.request!()
    {config_to_merge, _} = Code.eval_string(raw_elixir_code)
    Config.Reader.merge(config, config_to_merge)
  end
end

Last Post!

doma_dev

doma_dev

If you check that the code you get from your secret manager is signed with a non-revoked key and you have reasonable degree of assurance in your intrusion detection, evaluating signed code is perfectly fine. World runs on evaluating signed code.

It’s all about threat model, right? If your threat model is “my secret storage got compromised”, odds are, arbitrary code execution on your production servers has already happened by then.

But yeah, awesome thread, we were getting secrets one by one on bootstrap, and are currently moving to evaluating one signed secret instead.

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 44265 214
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New

We're in Beta

About us Mission Statement