secvault 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 243d63e08d1e0efc90840322ebe46d547a6733829e4cde6f009dcaee457fb141
4
- data.tar.gz: 0c927adb97f3fdfa9e4680d59825b50b2741b11cb8131c1e61b0eca42dec75fb
3
+ metadata.gz: 18d7c81d380aa63a8092f4bd91a438ee3e02282695b6fcbe6841ffbb81a30a9b
4
+ data.tar.gz: 2dbe018b171e0840e9a6047027fcf8e60ef73ec60867e4f6f4f97240df74f126
5
5
  SHA512:
6
- metadata.gz: 0abb15b103100f8205b1ec4c7890d51b9ad8d8c0f55d8d96e1f55b0e85b6d0ade146c382c32e187bfb2c952d02a3fc940ee33b9c6f9beabe598b7773e9cf9fa9
7
- data.tar.gz: 12edf2aad07063edb1d4385bedcc8899d388eefef26499671cdddf2bc37c67bfeec39fc08729e09e19c63c04021f28642276f81354b1729a7e08940b5a47fcc9
6
+ metadata.gz: c864336bbb71f184bf09e9f3bc0c191cbd7f7d750ee5a9c541cc3711b0ddc0cc608103e574dffd940b64dc814b4d5b5f433940ef0adf6235e3d17caf9f5784ce
7
+ data.tar.gz: 6c62bb91d5a9a0ca1ac0a984f94c92d11c9815d8832e371b7b362d2d6142e1a5f6ea5b058ce8d7762708c271c4cfe848b753d8ea2c6c1dbf47ace950c6df16fd
data/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [2.3.0] - 2025-09-22
4
+
5
+ ### Changed
6
+
7
+ - **Better method naming**: Renamed `setup_rails_71_integration!` to `setup_backward_compatibility_with_older_rails!`
8
+ - **More generic approach**: New method name works for any older Rails version, not just 7.1
9
+ - **Updated documentation**: README now uses "Older Rails Integration" instead of "Rails 7.1 Integration"
10
+ - **Clearer version support**: Documentation now shows "Rails 7.1 and older" for better clarity
11
+
12
+ ### Backward Compatibility
13
+
14
+ - ✅ **Old method name still works**: `setup_rails_71_integration!` is aliased to the new method
15
+ - ✅ **No breaking changes**: All existing code continues to work
16
+ - ✅ **Updated test apps**: Rails 7.1 test app uses the new, cleaner method name
17
+
18
+ ### Benefits
19
+
20
+ - **Future-proof naming**: Works for Rails 7.1, 7.0, 6.x, or any version with native secrets
21
+ - **Clearer intent**: Method name clearly indicates it's for backward compatibility
22
+ - **Better documentation**: More generic approach in README and code comments
23
+ - **Maintained compatibility**: Existing users don't need to change anything
24
+
3
25
  ## [2.2.0] - 2025-09-22
4
26
 
5
27
  ### Added
data/README.md CHANGED
@@ -1,12 +1,22 @@
1
1
  # Secvault
2
2
 
3
- Restores the classic Rails `secrets.yml` functionality that was removed in Rails 7.2. Uses simple, plain YAML files for environment-specific secrets management.
3
+ Restores the classic Rails `secrets.yml` functionality that was removed in Rails 7.2. Uses simple, plain YAML files for environment-specific secrets management with powerful features like YAML defaults, ERB interpolation, and multi-file configurations.
4
4
 
5
5
  **Rails Version Support:**
6
- - **Rails 7.1**: Manual setup (see Rails 7.1 Integration below)
6
+ - **Rails 7.1 and older**: Manual setup (see Older Rails Integration below)
7
7
  - **Rails 7.2+**: Automatic setup
8
8
  - **Rails 8.0+**: Full compatibility
9
9
 
10
+ ## ✨ Key Features
11
+
12
+ - 🔗 **YAML Anchor/Alias Support**: Use `default: &default` for shared configuration
13
+ - 🌍 **ERB Interpolation**: Environment variables with type conversion (`ENV['VAR'].to_i`, boolean logic)
14
+ - 📁 **Multi-File Loading**: Merge multiple YAML files (e.g., base + OAuth + local overrides)
15
+ - 🔄 **Environment Switching**: Load different environments dynamically
16
+ - 🛠️ **Development Tools**: Hot-reload secrets without server restart
17
+ - 🔍 **Utility Methods**: `Secvault.active?` to check integration status
18
+ - 🏗️ **Flexible Organization**: Feature-based, environment-based, or namespace-based file structures
19
+
10
20
  ## Installation
11
21
 
12
22
  ```ruby
@@ -34,32 +44,91 @@ Rails.application.secrets.api_key
34
44
  Rails.application.secrets.database_password
35
45
  ```
36
46
 
37
- **Example secrets.yml:**
47
+ **Example secrets.yml with YAML defaults and ERB:**
38
48
  ```yaml
49
+ # YAML defaults - inherited by all environments
50
+ default: &default
51
+ app_name: "My Application"
52
+ database:
53
+ adapter: "postgresql"
54
+ pool: 5
55
+ timeout: 5000
56
+ api:
57
+ timeout: 30
58
+ retries: 3
59
+
39
60
  development:
40
- api_key: dev_key
41
- database_password: dev_password
61
+ <<: *default # Inherit defaults
62
+ api_key: "dev_api_key_123"
63
+ database:
64
+ host: "localhost"
65
+ name: "myapp_development"
66
+ api:
67
+ base_url: "http://localhost:3000" # Override default
42
68
 
43
69
  production:
70
+ <<: *default # Inherit defaults
44
71
  api_key: <%= ENV['API_KEY'] %>
45
- database_password: <%= ENV['DATABASE_PASSWORD'] %>
72
+ database:
73
+ host: <%= ENV['DATABASE_HOST'] %>
74
+ name: <%= ENV['DATABASE_NAME'] %>
75
+ pool: <%= ENV.fetch('DATABASE_POOL', '10').to_i %> # Type conversion
76
+ api:
77
+ base_url: <%= ENV['API_BASE_URL'] %>
78
+
79
+ # Boolean conversion
80
+ features:
81
+ new_ui: <%= ENV.fetch('FEATURE_NEW_UI', 'true') == 'true' %>
82
+
83
+ # Array conversion
84
+ oauth_scopes: <%= ENV.fetch('OAUTH_SCOPES', 'email,profile').split(',') %>
46
85
  ```
47
86
 
48
- **Production:** Use environment variables in your YAML:
49
- ```yaml
50
- production:
51
- api_key: <%= ENV['API_KEY'] %>
87
+ ## Multi-File Configuration
88
+
89
+ Organize secrets across multiple files for better maintainability:
90
+
91
+ ```ruby
92
+ # config/initializers/secvault.rb
93
+ require "secvault"
94
+ Secvault.setup_backward_compatibility_with_older_rails!
95
+
96
+ Rails.application.config.after_initialize do
97
+ # Load multiple files in order (later files override earlier ones)
98
+ secrets_files = [
99
+ Rails.root.join('config', 'secrets.yml'), # Base secrets
100
+ Rails.root.join('config', 'secrets.oauth.yml'), # OAuth & APIs
101
+ Rails.root.join('config', 'secrets.local.yml') # Local overrides
102
+ ]
103
+
104
+ existing_files = secrets_files.select(&:exist?)
105
+
106
+ if existing_files.any?
107
+ merged_secrets = Rails::Secrets.parse(existing_files, env: Rails.env)
108
+ secrets_object = ActiveSupport::OrderedOptions.new
109
+ secrets_object.merge!(merged_secrets)
110
+ Rails.application.define_singleton_method(:secrets) { secrets_object }
111
+ end
112
+ end
113
+ ```
114
+
115
+ **File organization example:**
116
+ ```
117
+ config/
118
+ ├── secrets.yml # Base application secrets
119
+ ├── secrets.oauth.yml # OAuth providers & external APIs
120
+ ├── secrets.local.yml # Local development overrides (gitignored)
52
121
  ```
53
122
 
54
123
  ## Advanced Usage
55
124
 
56
- **Multiple secrets files (merged in order):**
125
+ **Manual multi-file parsing:**
57
126
  ```ruby
58
127
  # Parse multiple files - later files override earlier ones
59
128
  secrets = Rails::Secrets.parse([
60
129
  'config/secrets.yml',
61
- 'config/secrets.local.yml',
62
- 'config/secrets.production.yml'
130
+ 'config/secrets.oauth.yml',
131
+ 'config/secrets.local.yml'
63
132
  ], env: Rails.env)
64
133
  ```
65
134
 
@@ -72,25 +141,58 @@ production_secrets = Rails::Secrets.load(env: 'production')
72
141
  dev_secrets = Rails::Secrets.load(env: 'development')
73
142
  ```
74
143
 
75
- **Custom files:**
144
+ **Environment-specific loading:**
76
145
  ```ruby
77
- # Parse a custom secrets file
78
- custom_secrets = Rails::Secrets.parse(['config/custom.yml'], env: Rails.env)
146
+ # Load production secrets in any environment
147
+ production_secrets = Rails::Secrets.load(env: 'production')
79
148
 
80
- # Parse from different paths
81
- all_secrets = Rails::Secrets.parse([
82
- Rails.root.join('config', 'secrets.yml'),
83
- Rails.root.join('config', 'deploy', 'secrets.yml')
84
- ], env: Rails.env)
149
+ # Load development secrets
150
+ dev_secrets = Rails::Secrets.load(env: 'development')
85
151
  ```
86
152
 
87
- ## Rails 7.1 Integration
153
+ ## ERB Features & Type Conversion
88
154
 
89
- Test Secvault in Rails 7.1 before upgrading to 7.2+:
155
+ Secvault supports powerful ERB templating with automatic type conversion:
156
+
157
+ ```yaml
158
+ production:
159
+ # String interpolation
160
+ api_key: <%= ENV['API_KEY'] %>
161
+
162
+ # Integer conversion
163
+ database_pool: <%= ENV.fetch('DB_POOL', '10').to_i %>
164
+
165
+ # Boolean conversion
166
+ debug_enabled: <%= ENV.fetch('DEBUG', 'false') == 'true' %>
167
+
168
+ # Array conversion
169
+ allowed_hosts: <%= ENV.fetch('HOSTS', 'localhost,127.0.0.1').split(',') %>
170
+
171
+ # Fallback values
172
+ timeout: <%= ENV.fetch('TIMEOUT', '30').to_i %>
173
+ adapter: <%= ENV.fetch('DB_ADAPTER', 'postgresql') %>
174
+ ```
175
+
176
+ ## Development Tools
177
+
178
+ **Hot-reload secrets (development only):**
179
+ ```ruby
180
+ # In Rails console or code
181
+ reload_secrets! # Reloads all secrets files without server restart
182
+ ```
183
+
184
+ **Check integration status:**
185
+ ```ruby
186
+ Secvault.active? # Returns true if Secvault is managing secrets
187
+ ```
188
+
189
+ ## Older Rails Integration
190
+
191
+ For Rails versions with existing secrets functionality (like Rails 7.1), use Secvault to test before upgrading:
90
192
 
91
193
  ```ruby
92
194
  # config/initializers/secvault.rb
93
- Secvault.setup_rails_71_integration!
195
+ Secvault.setup_backward_compatibility_with_older_rails!
94
196
  ```
95
197
 
96
198
  This replaces Rails.application.secrets with Secvault functionality. Your existing Rails 7.1 code works unchanged:
@@ -102,12 +204,68 @@ Rails::Secrets.load # ✅ Load default config/secrets.yml
102
204
  Rails::Secrets.parse(['custom.yml'], env: Rails.env) # ✅ Parse custom files
103
205
  ```
104
206
 
207
+ **Check if Secvault is active:**
208
+ ```ruby
209
+ if Secvault.active?
210
+ puts "Using Secvault for secrets management"
211
+ else
212
+ puts "Using default Rails secrets functionality"
213
+ end
214
+ ```
215
+
216
+ ## Usage Examples
217
+
218
+ **Basic usage:**
219
+ ```ruby
220
+ # Access secrets
221
+ Rails.application.secrets.api_key
222
+ Rails.application.secrets.database.host
223
+ Rails.application.secrets.oauth.google.client_id
224
+
225
+ # With YAML defaults, you get deep merging:
226
+ Rails.application.secrets.database.adapter # "postgresql" (from default)
227
+ Rails.application.secrets.database.host # "localhost" (from environment)
228
+ ```
229
+
230
+ **Multi-file merging:**
231
+ ```ruby
232
+ # Files loaded in order: base → oauth → local
233
+ # Later files override earlier ones for the same keys
234
+ # Hash values are deep merged, scalars are replaced
235
+
236
+ Rails.application.secrets.api_key # Could be from base or local file
237
+ Rails.application.secrets.oauth.google # From oauth file
238
+ Rails.application.secrets.features.debug # From local file override
239
+ ```
240
+
241
+ ## Security Best Practices
242
+
243
+ ### ⚠️ Production Security
244
+ - **Never commit production secrets** to version control
245
+ - **Use environment variables** in production with ERB: `<%= ENV['SECRET'] %>`
246
+ - **Use ENV.fetch()** with fallbacks: `<%= ENV.fetch('SECRET', 'default') %>`
105
247
 
106
- ## Security
248
+ ### 📝 File Management
249
+ - **Add sensitive files** to `.gitignore`:
250
+ ```gitignore
251
+ config/secrets.yml # If contains sensitive data
252
+ config/secrets.local.yml # Local development overrides
253
+ config/secrets.production.yml # If used
254
+ ```
107
255
 
108
- ⚠️ Never commit production secrets to version control
109
- ✅ Use environment variables for production secrets with ERB syntax: `<%= ENV['SECRET'] %>`
110
- Add `config/secrets.yml` to `.gitignore` if it contains sensitive data
256
+ ### 🔑 Recommended Structure
257
+ ```yaml
258
+ # GOOD: Base file with safe defaults
259
+ development:
260
+ api_key: "safe_dev_key_for_team"
261
+
262
+ production:
263
+ api_key: <%= ENV['API_KEY'] %> # ✅ From environment
264
+
265
+ # ❌ BAD: Secrets hardcoded in base file
266
+ production:
267
+ api_key: "super_secret_production_key" # ❌ Never do this
268
+ ```
111
269
 
112
270
  ## License
113
271
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Secvault
4
- VERSION = "2.2.0"
4
+ VERSION = "2.4.0"
5
5
  end
data/lib/secvault.rb CHANGED
@@ -58,6 +58,11 @@ module Secvault
58
58
 
59
59
  extend self
60
60
 
61
+ # Check if Secvault is currently active in the Rails application
62
+ def active?
63
+ defined?(Rails) && Rails::Secrets == Secvault::RailsSecrets
64
+ end
65
+
61
66
  def install!
62
67
  return if defined?(Rails::Railtie).nil?
63
68
 
@@ -65,18 +70,18 @@ module Secvault
65
70
  require "secvault/rails_secrets"
66
71
  end
67
72
 
68
- # Helper method to set up Secvault for Rails 7.1 applications
69
- # This provides an easy way to integrate Secvault into Rails 7.1 apps
70
- # that still have native Rails::Secrets functionality.
73
+ # Helper method to set up Secvault for older Rails versions
74
+ # This provides an easy way to integrate Secvault into older Rails apps
75
+ # that still have native Rails::Secrets functionality (like Rails 7.1).
71
76
  #
72
77
  # Usage in an initializer:
73
- # Secvault.setup_rails_71_integration!
78
+ # Secvault.setup_backward_compatibility_with_older_rails!
74
79
  #
75
80
  # This will:
76
81
  # 1. Override native Rails::Secrets with Secvault implementation
77
82
  # 2. Replace Rails.application.secrets with Secvault-powered functionality
78
83
  # 3. Load secrets from config/secrets.yml automatically
79
- def setup_rails_71_integration!
84
+ def setup_backward_compatibility_with_older_rails!
80
85
  # Override native Rails::Secrets
81
86
  if defined?(Rails::Secrets)
82
87
  Rails.send(:remove_const, :Secrets)
@@ -109,6 +114,9 @@ module Secvault
109
114
  end
110
115
  end
111
116
  end
117
+
118
+ # Backward compatibility alias
119
+ alias_method :setup_rails_71_integration!, :setup_backward_compatibility_with_older_rails!
112
120
  end
113
121
 
114
122
  Secvault.install! if defined?(Rails)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: secvault
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Unnikrishnan KP