Post

Managing Configurations and Secrets in Rails: A Comprehensive Guide

Managing Configurations and Secrets in Rails: A Comprehensive Guide

In the world of web development, properly managing configurations and secrets is crucial for maintaining security and ensuring smooth operations. Rails, being a popular web application framework, provides robust tools and best practices for handling sensitive information. This article will explore various methods to manage configurations and secrets in Rails applications, from built-in solutions to third-party tools.

1. Rails Credentials

Rails 5.2 introduced the credentials system, which provides a secure way to store sensitive information.

Key Features:

  • Uses credentials.yml.enc for storing encrypted credentials
  • Requires master.key for decryption
  • Supports environment-specific credentials

Best Practices:

  • Use Rails.credentials to access encrypted credentials
  • Never commit credentials.yml.enc or master.key to version control
  • Rotate secrets regularly and update the master.key periodically

Example Usage:

1
2
3
4
5
# Accessing a secret
secret_key = Rails.credentials.secret_key_base

# Accessing environment-specific secrets
production_api_key = Rails.credentials.production[:api_key]

2. Environment Variables

Environment variables are a common and flexible way to manage configuration settings across different environments.

Best Practices:

  • Use a .env file to store environment variables locally
  • Never commit .env files to version control
  • Use the dotenv gem to load environment variables in development

Example Usage:

1
2
3
4
5
# Gemfile
gem 'dotenv-rails', groups: [:development, :test]

# Accessing an environment variable
api_key = ENV['API_KEY']

3. 1Password CLI for Local Development

For teams using 1Password, the 1Password CLI can be a great tool to manage secrets in local development environments.

Setup:

  1. Install 1Password CLI
  2. Authenticate with your 1Password account
  3. Create a project-specific vault in 1Password

Best Practices:

  • Store development secrets in a dedicated 1Password vault
  • Use 1Password CLI to fetch secrets on demand
  • Integrate 1Password CLI with your development workflow

Example Usage:

1
2
3
4
5
# Fetch a secret and export it as an environment variable
export API_KEY=$(op item get "API Key" --fields label=secret)

# Use in your Rails application
api_key = ENV['API_KEY']

4. Cloud-based Secret Management

For production environments, cloud-based secret management services provide robust security features and easy integration with cloud infrastructure.

Options:

  • AWS Secrets Manager
  • Azure Key Vault
  • Google Cloud Secret Manager

Best Practices:

  • Use IAM roles and policies to control access
  • Enable automatic secret rotation
  • Monitor access logs for unusual activity

Example Usage with AWS Secrets Manager:

1
2
3
4
5
6
7
8
9
10
11
12
13
require 'aws-sdk-secretsmanager'

client = Aws::SecretsManager::Client.new(region: 'us-west-2')

begin
  get_secret_value_response = client.get_secret_value(secret_id: "MySecret")
rescue Aws::SecretsManager::Errors::DecryptionFailure => e
  # Handle decryption errors
rescue Aws::SecretsManager::Errors::InternalServiceError => e
  # Handle AWS service errors
end

secret = JSON.parse(get_secret_value_response.secret_string)

5. Vault by HashiCorp

HashiCorp Vault is a powerful tool for secret management that can be used across different environments and platforms.

Key Features:

  • Centralized secret management
  • Dynamic secrets
  • Encryption as a service

Best Practices:

  • Use Vault’s access control policies
  • Enable audit logging
  • Implement secret rotation

Example Usage with Ruby:

1
2
3
4
5
6
7
require 'vault'

Vault.address = "http://127.0.0.1:8200"
Vault.token   = "abcd-1234"

secret = Vault.logical.read("secret/my-secret")
api_key = secret.data[:api_key]

6. Config Servers

For microservices architectures or distributed systems, a dedicated config server can provide centralized configuration management.

Options:

  • Spring Cloud Config
  • Consul
  • etcd

Best Practices:

  • Secure the config server with authentication and authorization
  • Use encryption for sensitive configurations
  • Implement a robust update and rollback mechanism

Example Usage with Spring Cloud Config (for Rails apps using JRuby):

1
2
3
4
5
6
7
8
9
10
# config/application.rb
require 'jruby/java'
java_import 'org.springframework.cloud.config.client.ConfigServicePropertySourceLocator'

config = ConfigServicePropertySourceLocator.new
config.setUri(java.net.URI.new("http://config-server:8888"))
properties = config.locate(nil)

# Access configurations
database_url = properties.getProperty("database.url")

Conclusion

Managing configurations and secrets in Rails applications requires a thoughtful approach and the right tools. By leveraging Rails’ built-in credentials system, environment variables, cloud-based secret management services, or third-party tools like 1Password CLI and HashiCorp Vault, you can ensure that your sensitive information remains secure and easily manageable across different environments.

Remember to always follow security best practices, such as:

  • Never storing secrets in version control
  • Implementing least-privilege access controls
  • Regularly rotating secrets and credentials
  • Monitoring and auditing access to sensitive information

By adopting these practices and tools, you can build more secure and maintainable Rails applications that are ready to scale in today’s complex development landscapes.

This post is licensed under CC BY 4.0 by the author.