towerops/lib/towerops/vault.ex

58 lines
1.4 KiB
Elixir

defmodule Towerops.Vault do
@moduledoc """
Encryption vault for sensitive data using Cloak.
Encrypts data using AES-256-GCM encryption. The encryption key is loaded
from the CLOAK_KEY environment variable (base64-encoded).
## Usage
Fields that use this vault are automatically encrypted/decrypted by Ecto.
See `Towerops.Encrypted.Binary` for the custom Ecto type.
## Key Generation
Generate a new encryption key:
openssl rand -base64 32
Store this key securely in 1Password and set it as the CLOAK_KEY
environment variable in production.
"""
use Cloak.Vault, otp_app: :towerops
@impl GenServer
def init(config) do
# In dev/test, the key is already configured in config files
# In production (runtime.exs), we override with env var
config =
if System.get_env("CLOAK_KEY") do
Keyword.put(config, :ciphers,
default: {
Cloak.Ciphers.AES.GCM,
tag: "AES.GCM.V1", key: decode_env!("CLOAK_KEY")
}
)
else
# Use the key from config (dev/test)
config
end
{:ok, config}
end
defp decode_env!(var) do
var
|> System.get_env()
|> case do
nil ->
raise """
Environment variable #{var} is missing.
Generate a key with: openssl rand -base64 32
"""
value ->
Base.decode64!(value)
end
end
end