Skip to content

Instantly share code, notes, and snippets.

@mikehale
Last active August 5, 2024 21:29
Show Gist options
  • Save mikehale/0d91eb86af13f4e51994027cf29145d2 to your computer and use it in GitHub Desktop.
Save mikehale/0d91eb86af13f4e51994027cf29145d2 to your computer and use it in GitHub Desktop.
Support rails master key rotation. Tries an array of keys from named environment variables.
config.before_initialize do |app|
class CompositeEncryptedConfiguration
def initialize(config:, env_keys:)
configs = env_keys.map do |key|
ActiveSupport::EncryptedConfiguration.new(
config_path: Rails.root.join(config.credentials.content_path),
key_path: Rails.root.join(config.credentials.key_path),
env_key: key,
raise_if_missing_key: true
)
end
# Find the first config we can read/decrypt.
# If there are none then raise the last error encountered.
@config = configs.detect.with_index do |config, index|
config.read
rescue ActiveSupport::MessageEncryptor::InvalidMessage, ArgumentError => e
raise e if env_keys.size == index + 1
end
end
# Delegate method calls to the decrypted config object.
def method_missing(name, ...)
@config.send(name, ...)
end
def respond_to_missing?(name, include_private = false)
@config.respond_to?(name, include_private)
end
end
# Try to read the encrypted credentials using any of the keys found in the
# provided environment variables.
app.credentials = CompositeEncryptedConfiguration.new(
config: config,
env_keys: %w[RAILS_MASTER_KEY RAILS_MASTER_KEY2]
)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment