dotenv-vault-rails 0.8.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -1
- data/Gemfile.lock +6 -6
- data/README.md +50 -7
- data/dotenv-vault-rails.gemspec +2 -2
- data/dotenv-vault.gemspec +2 -2
- data/lib/dotenv-vault/version.rb +1 -1
- data/lib/dotenv-vault.rb +67 -25
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f612aee9f093299bc8f9ffc6d62927f5a90146982add8cf9c5efd9f58c16f13
|
4
|
+
data.tar.gz: 06ccf7aa83cd740991576ff3c2a0bdacf1668b3a706feb2014b8d7a59c91208e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9680ab3bb4852d5ac11107c19c90b5ff05b7c5c7218c04134c3005fd4de8421ca4b0b5ef84b348c041749892be1cbc1750bde365bf78034cfef0be907b4c009c
|
7
|
+
data.tar.gz: cdf203edcce1452dc5d4666849de31cfb35621cc167d1a7d70e86c083be987119f8f06c65ebac4e10f54e791f0bf15015b345013fe85a65e54a2b2de96c580cd
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,19 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
4
4
|
|
5
|
-
## [Unreleased](https://github.com/dotenv-org/dotenv-vault-ruby/compare/v0.
|
5
|
+
## [Unreleased](https://github.com/dotenv-org/dotenv-vault-ruby/compare/v0.9.0...master)
|
6
|
+
|
7
|
+
## 0.10.0
|
8
|
+
|
9
|
+
### Added
|
10
|
+
|
11
|
+
- Support key rotation. Added comma separated capability to `DOTENV_KEY`. Add multiple keys to your DOTENV_KEY for use with decryption. Separate with a comma. [#2](https://github.com/dotenv-org/dotenv-vault-ruby/pull/2)
|
12
|
+
|
13
|
+
## 0.9.0
|
14
|
+
|
15
|
+
### Changed
|
16
|
+
|
17
|
+
- Do not raise stacktrace error if missing .env.vault file [#1](https://github.com/dotenv-org/dotenv-vault-ruby/pull/1)
|
6
18
|
|
7
19
|
## 0.8.0
|
8
20
|
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
dotenv-vault (0.
|
4
|
+
dotenv-vault (0.10.0)
|
5
5
|
dotenv
|
6
6
|
lockbox
|
7
|
-
dotenv-vault-rails (0.
|
7
|
+
dotenv-vault-rails (0.10.0)
|
8
8
|
dotenv-rails
|
9
|
-
dotenv-vault (= 0.
|
9
|
+
dotenv-vault (= 0.10.0)
|
10
10
|
|
11
11
|
GEM
|
12
12
|
remote: https://rubygems.org/
|
@@ -41,14 +41,14 @@ GEM
|
|
41
41
|
erubi (1.11.0)
|
42
42
|
i18n (1.12.0)
|
43
43
|
concurrent-ruby (~> 1.0)
|
44
|
-
lockbox (1.
|
44
|
+
lockbox (1.1.0)
|
45
45
|
loofah (2.19.0)
|
46
46
|
crass (~> 1.0.2)
|
47
47
|
nokogiri (>= 1.5.9)
|
48
48
|
method_source (1.0.0)
|
49
49
|
mini_portile2 (2.8.0)
|
50
50
|
minitest (5.16.3)
|
51
|
-
nokogiri (1.13.
|
51
|
+
nokogiri (1.13.9)
|
52
52
|
mini_portile2 (~> 2.8.0)
|
53
53
|
racc (~> 1.4)
|
54
54
|
racc (1.6.0)
|
@@ -85,7 +85,7 @@ GEM
|
|
85
85
|
thor (1.2.1)
|
86
86
|
tzinfo (2.0.5)
|
87
87
|
concurrent-ruby (~> 1.0)
|
88
|
-
zeitwerk (2.6.
|
88
|
+
zeitwerk (2.6.1)
|
89
89
|
|
90
90
|
PLATFORMS
|
91
91
|
ruby
|
data/README.md
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
<img src="https://raw.githubusercontent.com/motdotla/dotenv/master/dotenv.svg" alt="dotenv-vault" align="right" width="200" />
|
4
4
|
|
5
|
-
|
5
|
+
Extends the proven & trusted foundation of [dotenv](https://github.com/bkeepers/dotenv), with a `.env.vault` file.
|
6
6
|
|
7
|
-
|
7
|
+
The extended standard lets you sync your `.env` files – quickly & securely. Stop sharing them over insecure channels like Slack and email, and never lose an important `.env` file again.
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
@@ -22,11 +22,29 @@ And then execute:
|
|
22
22
|
$ bundle
|
23
23
|
```
|
24
24
|
|
25
|
+
### Sinatra or Plain ol' Ruby
|
26
|
+
|
27
|
+
Install the gem:
|
28
|
+
|
29
|
+
```shell
|
30
|
+
$ gem install dotenv-vault
|
31
|
+
```
|
32
|
+
|
33
|
+
As early as possible in your application bootstrap process, load `.env`:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
require 'dotenv-vault/load'
|
37
|
+
|
38
|
+
# or
|
39
|
+
require 'dotenv-vault'
|
40
|
+
DotenvVault.load
|
41
|
+
```
|
42
|
+
|
25
43
|
## Usage
|
26
44
|
|
27
45
|
### `.env`
|
28
46
|
|
29
|
-
Basic usage
|
47
|
+
Basic usage works just like [dotenv](https://github.com/bkeepers/dotenv).
|
30
48
|
|
31
49
|
Add your application configuration to your `.env` file in the root of your project:
|
32
50
|
|
@@ -35,7 +53,7 @@ S3_BUCKET=YOURS3BUCKET
|
|
35
53
|
SECRET_KEY=YOURSECRETKEYGOESHERE
|
36
54
|
```
|
37
55
|
|
38
|
-
|
56
|
+
When your application loads, these variables will be available in `ENV`:
|
39
57
|
|
40
58
|
```ruby
|
41
59
|
config.fog_directory = ENV['S3_BUCKET']
|
@@ -43,10 +61,12 @@ config.fog_directory = ENV['S3_BUCKET']
|
|
43
61
|
|
44
62
|
### `.env.vault`
|
45
63
|
|
64
|
+
The `.env.vault` extends `.env`. It facilitates syncing your `.env` file across machines, team members, and environments.
|
65
|
+
|
46
66
|
Usage is similar to git. In the same directory as your `.env` file, run the command:
|
47
67
|
|
48
68
|
```shell
|
49
|
-
npx dotenv-vault new
|
69
|
+
$ npx dotenv-vault new
|
50
70
|
```
|
51
71
|
|
52
72
|
Follow those instructions and then run:
|
@@ -66,6 +86,8 @@ That's it!
|
|
66
86
|
|
67
87
|
You just synced your `.env` file. Commit your `.env.vault` file to code, and tell your teammates to run `npx dotenv-vault pull`.
|
68
88
|
|
89
|
+
[Learn more](https://www.dotenv.org/docs/tutorials/sync)
|
90
|
+
|
69
91
|
## Multiple Environments
|
70
92
|
|
71
93
|
Run the command:
|
@@ -76,7 +98,9 @@ $ npx dotenv-vault open production
|
|
76
98
|
|
77
99
|
It will open up an interface to manage your production environment variables.
|
78
100
|
|
79
|
-
|
101
|
+
[Learn more](https://www.dotenv.org/docs/tutorials/environments)
|
102
|
+
|
103
|
+
## Integrate Anywhere™
|
80
104
|
|
81
105
|
Build your encrypted `.env.vault`:
|
82
106
|
|
@@ -105,6 +129,25 @@ $ heroku config:set DOTENV_KEY="dotenv://:key_1234@dotenv.org/vault/.env.vault?e
|
|
105
129
|
|
106
130
|
All set! When your app boots, it will recognize a `DOTENV_KEY` is set, decrypt the `.env.vault` file, and load the variables to `ENV`.
|
107
131
|
|
132
|
+
Made a change to your production envs? Run `npx dotenv-vault build`, commit that safely to code, and deploy. It's simple and safe like that.
|
133
|
+
|
134
|
+
[Learn more](https://www.dotenv.org/docs/tutorials/integrations)
|
135
|
+
|
136
|
+
## Dotenv.org
|
137
|
+
|
138
|
+
You need a [Dotenv Account](https://dotenv.org) to use Dotenv Vault. It is free to use with premium features.
|
139
|
+
|
140
|
+
![](https://api.checklyhq.com/v1/badges/checks/c2fee99a-38e7-414e-89b8-9766ceeb1927?style=flat&theme=dark&responseTime=true)
|
141
|
+
![](https://api.checklyhq.com/v1/badges/checks/4f557967-1ed1-486a-b762-39a63781d752?style=flat&theme=dark&responseTime=true)
|
142
|
+
<br>
|
143
|
+
![](https://api.checklyhq.com/v1/badges/checks/804eb6fa-6599-4688-a649-7ff3c39a64b9?style=flat&theme=dark&responseTime=true)
|
144
|
+
![](https://api.checklyhq.com/v1/badges/checks/6a94504e-e936-4f07-bc0b-e08fee2734b3?style=flat&theme=dark&responseTime=true)
|
145
|
+
<br>
|
146
|
+
![](https://api.checklyhq.com/v1/badges/checks/06ac4f4e-3e0e-4501-9987-580b4d2a6b06?style=flat&theme=dark&responseTime=true)
|
147
|
+
![](https://api.checklyhq.com/v1/badges/checks/0ffc1e55-7ef0-4c2c-8acc-b6311871f41c?style=flat&theme=dark&responseTime=true)
|
148
|
+
|
149
|
+
Visit [health.dotenv.org](https://health.dotenv.org) for more information.
|
150
|
+
|
108
151
|
## FAQ
|
109
152
|
|
110
153
|
#### What happens if `DOTENV_KEY` is not set?
|
@@ -117,7 +160,7 @@ No. We **strongly** recommend against committing your `.env` file to version con
|
|
117
160
|
|
118
161
|
#### Should I commit my `.env.vault` file?
|
119
162
|
|
120
|
-
Yes. It is safe and recommended to do so. It contains your
|
163
|
+
Yes. It is safe and recommended to do so. It contains your encrypted envs, and your vault identifier.
|
121
164
|
|
122
165
|
#### Can I share the `DOTENV_KEY`?
|
123
166
|
|
data/dotenv-vault-rails.gemspec
CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new "dotenv-vault-rails" do |spec|
|
|
6
6
|
spec.authors = ["motdotla"]
|
7
7
|
spec.email = ["mot@mot.la"]
|
8
8
|
|
9
|
-
spec.summary = %q{
|
10
|
-
spec.description = %q{
|
9
|
+
spec.summary = %q{Decrypt .env.vault file.}
|
10
|
+
spec.description = %q{Decrypt .env.vault file.}
|
11
11
|
spec.homepage = "https://github.com/dotenv-org/dotenv-vault-ruby"
|
12
12
|
spec.license = "MIT"
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
data/dotenv-vault.gemspec
CHANGED
@@ -6,8 +6,8 @@ Gem::Specification.new "dotenv-vault" do |spec|
|
|
6
6
|
spec.authors = ["motdotla"]
|
7
7
|
spec.email = ["mot@mot.la"]
|
8
8
|
|
9
|
-
spec.summary = %q{
|
10
|
-
spec.description = %q{
|
9
|
+
spec.summary = %q{Decrypt .env.vault file.}
|
10
|
+
spec.description = %q{Decrypt .env.vault file.}
|
11
11
|
spec.homepage = "https://github.com/dotenv-org/dotenv-vault-ruby"
|
12
12
|
spec.license = "MIT"
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
data/lib/dotenv-vault/version.rb
CHANGED
data/lib/dotenv-vault.rb
CHANGED
@@ -117,42 +117,60 @@ module DotenvVault
|
|
117
117
|
def parse_vault(*filenames)
|
118
118
|
# DOTENV_KEY=development/key_1234
|
119
119
|
#
|
120
|
-
# Warn the developer unless
|
121
|
-
raise NotFoundDotenvKey, "NOT_FOUND_DOTENV_KEY: Cannot find ENV['DOTENV_KEY']" unless present?(
|
120
|
+
# Warn the developer unless present
|
121
|
+
raise NotFoundDotenvKey, "NOT_FOUND_DOTENV_KEY: Cannot find ENV['DOTENV_KEY']" unless present?(dotenv_key)
|
122
122
|
|
123
|
-
# Parse
|
124
|
-
|
125
|
-
|
126
|
-
# Get decrypt key
|
127
|
-
key = uri.password
|
128
|
-
raise InvalidDotenvKey, "INVALID_DOTENV_KEY: Missing key part" unless present?(key)
|
123
|
+
# Parse .env.vault
|
124
|
+
parsed = Dotenv.parse(vault_path)
|
129
125
|
|
130
|
-
#
|
131
|
-
|
132
|
-
|
133
|
-
raise InvalidDotenvKey, "INVALID_DOTENV_KEY: Missing environment part" unless present?(environment)
|
126
|
+
# handle scenario for comma separated keys - for use with key rotation
|
127
|
+
# example: DOTENV_KEY="dotenv://:key_1234@dotenv.org/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenv.org/vault/.env.vault?environment=prod"
|
128
|
+
keys = dotenv_key.split(',')
|
134
129
|
|
135
|
-
|
136
|
-
|
137
|
-
|
130
|
+
decrypted = nil
|
131
|
+
keys.each_with_index do |split_dotenv_key, index|
|
132
|
+
begin
|
133
|
+
# Get full key
|
134
|
+
key = split_dotenv_key.strip
|
138
135
|
|
139
|
-
|
140
|
-
|
136
|
+
# Get instructions for decrypt
|
137
|
+
attrs = instructions(parsed, key)
|
141
138
|
|
142
|
-
|
143
|
-
|
144
|
-
ciphertext = parsed[environment_key] # DOTENV_VAULT_PRODUCTION
|
145
|
-
raise NotFoundDotenvEnvironment, "NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate #{environment_key} in .env.vault" unless ciphertext
|
139
|
+
# Decrypt
|
140
|
+
decrypted = decrypt(attrs[:ciphertext], attrs[:key])
|
146
141
|
|
147
|
-
|
148
|
-
|
142
|
+
break
|
143
|
+
rescue => error
|
144
|
+
# last key
|
145
|
+
raise error if index >= keys.length - 1
|
146
|
+
# try next key
|
147
|
+
end
|
148
|
+
end
|
149
149
|
|
150
150
|
# Parse decrypted .env string
|
151
151
|
Dotenv::Parser.call(decrypted, true)
|
152
152
|
end
|
153
153
|
|
154
154
|
def using_vault?
|
155
|
-
|
155
|
+
dotenv_key_present? && dotenv_vault_present?
|
156
|
+
end
|
157
|
+
|
158
|
+
def dotenv_key_present?
|
159
|
+
present?(dotenv_key) && dotenv_vault_present?
|
160
|
+
end
|
161
|
+
|
162
|
+
def dotenv_key
|
163
|
+
return ENV["DOTENV_KEY"] if present?(ENV["DOTENV_KEY"])
|
164
|
+
|
165
|
+
""
|
166
|
+
end
|
167
|
+
|
168
|
+
def dotenv_vault_present?
|
169
|
+
File.file?(vault_path)
|
170
|
+
end
|
171
|
+
|
172
|
+
def vault_path
|
173
|
+
".env.vault"
|
156
174
|
end
|
157
175
|
|
158
176
|
def present?(str)
|
@@ -162,7 +180,7 @@ module DotenvVault
|
|
162
180
|
def decrypt(ciphertext, key)
|
163
181
|
key = key[-64..-1] # last 64 characters. allows for passing keys with preface like key_*****
|
164
182
|
|
165
|
-
raise InvalidDotenvKey, "INVALID_DOTENV_KEY: Key part must be 64 characters long (or more)" unless key.bytesize == 64
|
183
|
+
raise InvalidDotenvKey, "INVALID_DOTENV_KEY: Key part must be 64 characters long (or more)" unless key && key.bytesize == 64
|
166
184
|
|
167
185
|
lockbox = Lockbox.new(key: key, encode: true)
|
168
186
|
begin
|
@@ -171,4 +189,28 @@ module DotenvVault
|
|
171
189
|
raise DecryptionFailed, "DECRYPTION_FAILED: Please check your DOTENV_KEY"
|
172
190
|
end
|
173
191
|
end
|
192
|
+
|
193
|
+
def instructions(parsed, split_dotenv_key)
|
194
|
+
# Parse DOTENV_KEY. Format is a URI
|
195
|
+
uri = URI.parse(split_dotenv_key) # dotenv://:key_1234@dotenv.org/vault/.env.vault?environment=production
|
196
|
+
|
197
|
+
# Get decrypt key
|
198
|
+
key = uri.password
|
199
|
+
raise InvalidDotenvKey, "INVALID_DOTENV_KEY: Missing key part" unless present?(key)
|
200
|
+
|
201
|
+
# Get environment
|
202
|
+
params = Hash[URI::decode_www_form(uri.query.to_s)]
|
203
|
+
environment = params["environment"]
|
204
|
+
raise InvalidDotenvKey, "INVALID_DOTENV_KEY: Missing environment part" unless present?(environment)
|
205
|
+
|
206
|
+
# Get ciphertext payload
|
207
|
+
environment_key = "DOTENV_VAULT_#{environment.upcase}"
|
208
|
+
ciphertext = parsed[environment_key] # DOTENV_VAULT_PRODUCTION
|
209
|
+
raise NotFoundDotenvEnvironment, "NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate #{environment_key} in .env.vault" unless ciphertext
|
210
|
+
|
211
|
+
{
|
212
|
+
ciphertext: ciphertext,
|
213
|
+
key: key
|
214
|
+
}
|
215
|
+
end
|
174
216
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dotenv-vault-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- motdotla
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dotenv-rails
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.10.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.10.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: spring
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
-
description:
|
69
|
+
description: Decrypt .env.vault file.
|
70
70
|
email:
|
71
71
|
- mot@mot.la
|
72
72
|
executables: []
|
@@ -117,5 +117,5 @@ requirements: []
|
|
117
117
|
rubygems_version: 3.1.6
|
118
118
|
signing_key:
|
119
119
|
specification_version: 4
|
120
|
-
summary:
|
120
|
+
summary: Decrypt .env.vault file.
|
121
121
|
test_files: []
|