Module: Secvault
- Extended by:
- Secvault
- Included in:
- Secvault
- Defined in:
- lib/secvault.rb,
lib/secvault/railtie.rb,
lib/secvault/secrets.rb,
lib/secvault/version.rb,
lib/secvault/rails_secrets.rb
Overview
Secvault - Simple secrets management for Rails
Secvault restores the classic Rails secrets.yml functionality using simple, plain YAML files for environment-specific secrets management. Works consistently across all Rails versions.
Rails Version Support:
- Rails 7.1+: Full compatibility with automatic setup
- Rails 7.2+: Drop-in replacement for removed functionality
- Rails 8.0+: Full compatibility
Quick Start:
Add this to an initializer:
# config/initializers/secvault.rb
Secvault.start!
Usage:
Rails.application.secrets.api_key
Rails.application.secrets.oauth_settings[:google_client_id]
Secvault.secrets.your_key # Direct access
Rails::Secrets.load(env: 'development') # Load default config/secrets.yml
Rails::Secrets.parse(['custom.yml'], env: Rails.env) # Parse custom files
Getting Started:
1. Create config/secrets.yml with your secrets
2. Call Secvault.start! in an initializer
3. Use Rails.application.secrets.your_secret in your app
4. For production, use environment variables with ERB syntax
Defined Under Namespace
Classes: EarlyLoader, Error, RailsSecrets, Railtie, Secrets
Constant Summary collapse
- VERSION =
"3.4.0"- @@loaded_secrets =
Internal storage for loaded secrets
nil
Instance Method Summary collapse
-
#active? ⇒ Boolean
Check if Secvault is currently active (started).
- #install! ⇒ Object
-
#rails_integrated? ⇒ Boolean
Check if Secvault is integrated with Rails.application.secrets.
-
#secrets ⇒ Object
Access to loaded secrets without Rails integration.
-
#setup_early_application_secrets!(files: nil, application_class: nil) ⇒ Object
(also: #setup_early_secrets!)
Early setup method for use in config/application.rb before other configuration This ensures Rails.application has secrets available during application class definition.
-
#start!(files: [], integrate_with_rails: false, set_secret_key_base: true, hot_reload: (defined?(Rails) && Rails.env.respond_to?(:development?)) ? Rails.env.development? : false), logger: (defined?(Rails) && Rails.env.respond_to?(:production?)) ? !Rails.env.production? : true)) ⇒ Object
Start Secvault with simplified, unified API This is the main entry point for all Secvault functionality.
Instance Method Details
#active? ⇒ Boolean
Check if Secvault is currently active (started)
59 60 61 |
# File 'lib/secvault.rb', line 59 def active? @@loaded_secrets != nil end |
#install! ⇒ Object
129 130 131 132 133 134 |
# File 'lib/secvault.rb', line 129 def install! return if defined?(Rails::Railtie).nil? require "secvault/railtie" require "secvault/rails_secrets" end |
#rails_integrated? ⇒ Boolean
Check if Secvault is integrated with Rails.application.secrets
64 65 66 |
# File 'lib/secvault.rb', line 64 def rails_integrated? defined?(Rails) && Rails::Secrets == Secvault::RailsSecrets end |
#secrets ⇒ Object
Access to loaded secrets without Rails integration
54 55 56 |
# File 'lib/secvault.rb', line 54 def secrets @@loaded_secrets || ActiveSupport::OrderedOptions.new end |
#setup_early_application_secrets!(files: nil, application_class: nil) ⇒ Object Also known as: setup_early_secrets!
Early setup method for use in config/application.rb before other configuration This ensures Rails.application has secrets available during application class definition
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/secvault.rb', line 70 def setup_early_application_secrets!(files: nil, application_class: nil) return false unless defined?(Rails) # Default files if not provided files ||= begin default_files = ["config/secrets.yml"] # Add neeto-commons-backend file if available if defined?(NeetoCommonsBackend) && NeetoCommonsBackend.respond_to?(:shared_secrets_file) default_files.unshift(NeetoCommonsBackend.shared_secrets_file) end default_files end # Create a temporary Rails.application if it doesn't exist unless Rails.respond_to?(:application) && Rails.application # Create a temporary application-like object with secrets temp_app = Object.new # Add lazy secrets loading temp_app.define_singleton_method(:secrets) do @secrets ||= begin # Convert to full paths and filter existing files file_paths = files.map do |file| file.is_a?(Pathname) ? file : Rails.root.join(file) end.select(&:exist?) if file_paths.any? # Load secrets using Secvault all_secrets = Secvault::Secrets.parse(file_paths, env: Rails.env) current_secrets = ActiveSupport::OrderedOptions.new current_secrets.merge!(all_secrets) current_secrets else # Return empty secrets if no files found but include encryption structure secrets = ActiveSupport::OrderedOptions.new secrets.encryption = ActiveSupport::OrderedOptions.new secrets.encryption.primary_key = nil secrets.encryption.deterministic_key = nil secrets.encryption.key_derivation_salt = nil secrets end end end # Set up Rails.application to point to this temporary object Rails.define_singleton_method(:application) { temp_app } end true rescue => e warn "[Secvault] Early application secrets setup failed: #{e.}" false end |
#start!(files: [], integrate_with_rails: false, set_secret_key_base: true, hot_reload: (defined?(Rails) && Rails.env.respond_to?(:development?)) ? Rails.env.development? : false), logger: (defined?(Rails) && Rails.env.respond_to?(:production?)) ? !Rails.env.production? : true)) ⇒ Object
Start Secvault with simplified, unified API This is the main entry point for all Secvault functionality
Usage examples:
Secvault.start! # Simple: config/secrets.yml + Rails integration
Secvault.start!(files: ['custom.yml']) # Custom single file
Secvault.start!(files: ['base.yml', 'local.yml']) # Multiple files
Secvault.start!(integrate_with_rails: false) # Load only, no Rails integration
Secvault.start!(hot_reload: true) # Enable hot reload in development
Access secrets:
Rails.application.secrets.your_key # When integrate_rails: true (default)
Secvault.secrets.your_key # Direct access (always available)
Options:
- files: Array of file paths (String or Pathname). Defaults to ['config/secrets.yml']
- integrate_with_rails: Integrate with Rails.application.secrets (default: false)
- set_secret_key_base: Set Rails.application.config.secret_key_base from secrets (default: true)
- hot_reload: Add reload_secrets! methods for development (default: true in development)
- logger: Enable logging (default: true except production)
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/secvault.rb', line 156 def start!(files: [], integrate_with_rails: false, set_secret_key_base: true, hot_reload: ((defined?(Rails) && Rails.env.respond_to?(:development?)) ? Rails.env.development? : false), logger: ((defined?(Rails) && Rails.env.respond_to?(:production?)) ? !Rails.env.production? : true)) # Default to config/secrets.yml if no files specified files_to_load = files.empty? ? ["config/secrets.yml"] : Array(files) # Convert to Pathname objects and resolve relative to Rails.root file_paths = files_to_load.map do |file| file.is_a?(Pathname) ? file : Rails.root.join(file) end # Load secrets into Secvault.secrets load_secrets!(file_paths, logger: logger) # Integrate with Rails if requested if integrate_with_rails setup_rails_integration!(file_paths, set_secret_key_base: set_secret_key_base, logger: logger) end # Add hot reload functionality if requested if hot_reload add_hot_reload!(file_paths) end true rescue => e Rails.logger&.error "[Secvault] Failed to start: #{e.}" if defined?(Rails) && logger false end |