SopsConfigProvider
Decrypt secrets from sops file and set the config to your application on runtime.
Installation
The package can be installed
by adding sops_config_provider to your list of dependencies in mix.exs:
def deps do
[
{:sops_config_provider, "~> 0.1.0"}
]
endUsage
[ATTENTION] Please make sure that you have sops installed, and proper permission to encrypt and decrypt the file. See SOPS docs for sops intallation and setup
After the installation, you need to add the provider into def project section in
mix.exs.
releases: [
change_with_your_app_name: [
config_providers: [
{
SopsConfigProvider,
%{
app_name: :change_with_your_app_name,
secret_file_path: "priv/secrets.yml" # I'd recommend to put
# the secrets inside the priv directory, as it automatically get
# copied on release
}
}
]
]
]The config provider will decrypt the secrets and set the config like you do in runtime.exs
For example, if you have secrets config in yaml as below
# priv/secrets.yml
sentry:
dsn: "https://sentry.io"
It'll set the value below and app boot like on runtime.exs
config :sentry, dsn: "http://sentry.io"Options
Pass options as a map (second element of the tuple) in config_providers.
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
app_name | atom | yes | — |
Your app name. Used to resolve secret_file_path via Application.app_dir/2. |
secret_file_path | string | yes | — |
Path to the SOPS-encrypted file relative to the app dir. Supports .json, .yaml, .yml. |
sops_binary_path | string | no | "sops" |
Path to the sops binary. Override if sops is not on PATH. |
execution_dir | string | no | "./" |
Working directory used when running sops -d. Relevant when sops resolves key config (e.g., .sops.yaml) relative to cwd. |
env_variables | [{string, string}] | no | [] | Environment variables injected into the sops process. Useful for passing AWS/GCP credentials at runtime. |
mappings | map | no | %{} | Remap flat secret keys into nested module configs. See Mappings below. |
env_override | boolean | no | false | Allow OS env vars to override decrypted SOPS values. See Env Override below. |
config_env | atom | no | :prod | Config environment. |
Mappings
mappings lets you nest a secret key under a specific module within an app's config.
Structure:
%{
app_atom => %{
secret_key => {TargetModule, :nested_key}
}
}
Example — map :db_url in :my_app into {MyApp.Repo, :url}:
{
SopsConfigProvider,
%{
app_name: :my_app,
secret_file_path: "priv/secrets.yml",
mappings: %{
my_app: %{
db_url: {MyApp.Repo, :url}
}
}
}
}Given this secret file:
my_app:
db_url: "ecto://user:pass@localhost/mydb"
other_key: "value"Produces:
config :my_app, MyApp.Repo, url: "ecto://user:pass@localhost/mydb"
config :my_app, other_key: "value"Env Override
Set env_override: true to allow OS environment variables to override values from the SOPS file. Useful for emergency overrides or per-deploy flexibility without re-encrypting the secrets file.
Naming convention:APP_KEY — the app atom and config key joined with _, uppercased.
| YAML key | App | Derived env var |
|---|---|---|
api_key | stripity_stripe | STRIPITY_STRIPE_API_KEY |
dsn | sentry | SENTRY_DSN |
password | orca | ORCA_PASSWORD |
webhook | slack | SLACK_WEBHOOK |
Only flat atom keys are overridable. Nested module keys (set via mappings) are not derived and must be changed via the SOPS file.
An env var is ignored if it is not set or is an empty string — the SOPS value is used as-is.
{
SopsConfigProvider,
%{
app_name: :my_app,
secret_file_path: "priv/secrets.yml",
env_override: true,
mappings: %{
my_app: %{
database_url: {MyApp.Repo, :url}
}
}
}
}
With this config, setting SENTRY_DSN=https://new-dsn as an OS env var overrides the sentry > dsn value from the SOPS file at runtime. No re-encryption needed.
env_variables example
Pass AWS credentials when the runtime environment doesn't have them on the system:
{
SopsConfigProvider,
%{
app_name: :my_app,
secret_file_path: "priv/secrets.yml",
env_variables: [
{"AWS_ACCESS_KEY_ID", System.get_env("AWS_ACCESS_KEY_ID")},
{"AWS_SECRET_ACCESS_KEY", System.get_env("AWS_SECRET_ACCESS_KEY")}
]
}
}