vault_env_secrets 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.standard.yml +3 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +68 -0
- data/LICENSE.txt +21 -0
- data/README.md +113 -0
- data/Rakefile +14 -0
- data/lib/vault_env_secrets/errors.rb +3 -0
- data/lib/vault_env_secrets/railtie.rb +26 -0
- data/lib/vault_env_secrets/version.rb +5 -0
- data/lib/vault_env_secrets.rb +68 -0
- data/sig/vault_env_secrets.rbs +4 -0
- metadata +59 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a239afd0a1d9d133166b8c3f88f15162d9b4537437b5eee5ac602f99246ba196
|
4
|
+
data.tar.gz: 07ad320f88de1b735c9f5be34a95be6b6897fe71ae8943e5e36cd8e141c685ee
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 10feaf9ceffbb1892c20702623cbcec3c07b62bfbdcef60e216d4b1b9063ce3e68e70afbe1ec28710d0640be1f412b59ab9025322c841fd149c4c625770916dc
|
7
|
+
data.tar.gz: 475a66ab45ef7e558a1c7c09f919af52207695ec1d9691918df9087b4efb3388d0c35e1e45b0a4d47fc52488bae233f45c4425b6a71d33afac1e9088f7ff7aa1
|
data/.standard.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
vault_env_secrets (1.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ast (2.4.2)
|
10
|
+
base64 (0.1.1)
|
11
|
+
json (2.6.3)
|
12
|
+
language_server-protocol (3.17.0.3)
|
13
|
+
lint_roller (1.1.0)
|
14
|
+
minitest (5.19.0)
|
15
|
+
parallel (1.23.0)
|
16
|
+
parser (3.2.2.3)
|
17
|
+
ast (~> 2.4.1)
|
18
|
+
racc
|
19
|
+
racc (1.7.1)
|
20
|
+
rainbow (3.1.1)
|
21
|
+
rake (13.0.6)
|
22
|
+
regexp_parser (2.8.1)
|
23
|
+
rexml (3.2.6)
|
24
|
+
rubocop (1.56.0)
|
25
|
+
base64 (~> 0.1.1)
|
26
|
+
json (~> 2.3)
|
27
|
+
language_server-protocol (>= 3.17.0)
|
28
|
+
parallel (~> 1.10)
|
29
|
+
parser (>= 3.2.2.3)
|
30
|
+
rainbow (>= 2.2.2, < 4.0)
|
31
|
+
regexp_parser (>= 1.8, < 3.0)
|
32
|
+
rexml (>= 3.2.5, < 4.0)
|
33
|
+
rubocop-ast (>= 1.28.1, < 2.0)
|
34
|
+
ruby-progressbar (~> 1.7)
|
35
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
36
|
+
rubocop-ast (1.29.0)
|
37
|
+
parser (>= 3.2.1.0)
|
38
|
+
rubocop-performance (1.19.0)
|
39
|
+
rubocop (>= 1.7.0, < 2.0)
|
40
|
+
rubocop-ast (>= 0.4.0)
|
41
|
+
ruby-progressbar (1.13.0)
|
42
|
+
standard (1.31.0)
|
43
|
+
language_server-protocol (~> 3.17.0.2)
|
44
|
+
lint_roller (~> 1.0)
|
45
|
+
rubocop (~> 1.56.0)
|
46
|
+
standard-custom (~> 1.0.0)
|
47
|
+
standard-performance (~> 1.2)
|
48
|
+
standard-custom (1.0.2)
|
49
|
+
lint_roller (~> 1.0)
|
50
|
+
rubocop (~> 1.50)
|
51
|
+
standard-performance (1.2.0)
|
52
|
+
lint_roller (~> 1.1)
|
53
|
+
rubocop-performance (~> 1.19.0)
|
54
|
+
unicode-display_width (2.4.2)
|
55
|
+
|
56
|
+
PLATFORMS
|
57
|
+
arm64-darwin-21
|
58
|
+
ruby
|
59
|
+
x86_64-linux
|
60
|
+
|
61
|
+
DEPENDENCIES
|
62
|
+
minitest (~> 5.0)
|
63
|
+
rake (~> 13.0)
|
64
|
+
standard (~> 1.3)
|
65
|
+
vault_env_secrets!
|
66
|
+
|
67
|
+
BUNDLED WITH
|
68
|
+
2.4.10
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2023 Nick Muerdter
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
# VaultEnvSecrets
|
2
|
+
|
3
|
+
A small gem to load secrets from [Vault](https://www.vaultproject.io) into environment variables by way of a [consul-template](https://github.com/hashicorp/consul-template) YAML template. Automatic integration with Rails is supported.
|
4
|
+
|
5
|
+
## Requirements/Assumptions
|
6
|
+
|
7
|
+
- By default, a `consul-template` config file needs to be present in `config/vault.hcl` that defines a `template` that will render secrets in a YAML output file to `tmp/vault/secrets.yml`.
|
8
|
+
- You must be authenticate to Vault in some fashion outside of this library (eg, `vault login` is used before startup and `~/.vault-token` is present, or `VAULT_TOKEN` is set, etc).
|
9
|
+
- For Rails integration, secrets will only be read once on application startup (so to pick up changes in development, you must restart the Rails server).
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Install the gem and add to the application's Gemfile by executing:
|
14
|
+
|
15
|
+
```sh
|
16
|
+
bundle add vault_env_secrets
|
17
|
+
```
|
18
|
+
|
19
|
+
If bundler is not being used to manage dependencies, install the gem by executing:
|
20
|
+
|
21
|
+
```sh
|
22
|
+
gem install vault_env_secrets
|
23
|
+
```
|
24
|
+
|
25
|
+
## Example Usage
|
26
|
+
|
27
|
+
This gem mostly defers to to [`consul-template`](https://github.com/hashicorp/consul-template), with the assumption that there will be a YAML output file that can be read in. There are a variety of ways to use this, but as an example:
|
28
|
+
|
29
|
+
1. Authenticate against Vault:
|
30
|
+
|
31
|
+
```sh
|
32
|
+
vault login
|
33
|
+
```
|
34
|
+
|
35
|
+
2. Define a `consul-template` [configuration file](https://github.com/hashicorp/consul-template/blob/main/docs/configuration.md#configuration-file) in the default `config/vault.hcl` location:
|
36
|
+
|
37
|
+
```hcl
|
38
|
+
vault {
|
39
|
+
address = "https://vault.example.com/"
|
40
|
+
renew_token = true
|
41
|
+
|
42
|
+
retry {
|
43
|
+
enabled = false
|
44
|
+
}
|
45
|
+
}
|
46
|
+
|
47
|
+
template {
|
48
|
+
source = "./config/vault/secrets.yml.ctmpl"
|
49
|
+
destination = "./tmp/vault/secrets.yml"
|
50
|
+
error_on_missing_key = true
|
51
|
+
perms = 0600
|
52
|
+
}
|
53
|
+
```
|
54
|
+
|
55
|
+
3. Define the template that the `config/vault.hcl` config file references (which should be configured to output to `tmp/vault/secrets.yml` by default). In this example the secret key base and database credentials are fetched from a `secret/my-app/<rails_env>/web` item:
|
56
|
+
|
57
|
+
```ctmpl
|
58
|
+
{{ $rails_env := (envOrDefault "RAILS_ENV" "development") }}
|
59
|
+
|
60
|
+
{{ with secret (printf "secret/my-app/%s/web" $deploy_env) }}
|
61
|
+
{{ scratch.MapSet "secrets" "SECRET_KEY_BASE" .Data.data.secret_key_base }}
|
62
|
+
{{ scratch.MapSet "secrets" "SECRET_DB_HOST" .Data.data.db_host }}
|
63
|
+
{{ scratch.MapSet "secrets" "SECRET_DB_NAME" .Data.data.db_name }}
|
64
|
+
{{ scratch.MapSet "secrets" "SECRET_DB_USERNAME" .Data.data.db_username }}
|
65
|
+
{{ scratch.MapSet "secrets" "SECRET_DB_PASSWORD" .Data.data.db_password }}
|
66
|
+
{{ end }}
|
67
|
+
|
68
|
+
{{ scratch.Get "secrets" | toYAML }}
|
69
|
+
```
|
70
|
+
|
71
|
+
4. With the gem installed, any variables defined in the output YAML from the `consul-template` template will be set as environment variables on Rails startup. The environment variable names will depend on the names in the YAML output. So in the above example, `ENV["SECRET_KEY_BASE"]`, `ENV["SECRET_DB_HOST"]`, `ENV["SECRET_DB_PASSWORD"]`, etc would all be available to the app.
|
72
|
+
|
73
|
+
## Configuration
|
74
|
+
|
75
|
+
You may adjust VaultEnvSecrets configuration by adding a `config/initializers/vault_env_secrets.rb` file with setting changes. Note that the initializer must exist at this path and filename to be properly loaded (this ensures that VaultEnvSecrets is available early on in the Rails load process, so other parts of Rails and other gems can integrate with it).
|
76
|
+
|
77
|
+
#### `VaultEnvSecrets.enabled`
|
78
|
+
|
79
|
+
Optionally disable loading VaultEnvSecrets (for example, if this gem only needs to be active in certain Rails environments).
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
VaultEnvSecrets.enabled = false # Defaults to `true`
|
83
|
+
```
|
84
|
+
|
85
|
+
#### `VaultEnvSecrets.consul_template_config`
|
86
|
+
|
87
|
+
Set a custom path to the `consul-template` config file.
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
VaultEnvSecrets.consul_template_config = "config/my_config.hcl" # Defaults to `config/vault.hcl`
|
91
|
+
```
|
92
|
+
|
93
|
+
#### `VaultEnvSecrets.consul_template_output`
|
94
|
+
|
95
|
+
Set a custom path to the YAML output file generated from the `consul-template` template.
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
VaultEnvSecrets.consul_template_output = "tmp/my_secrets.yml" # Defaults to `tmp/vault/secrets.yml`
|
99
|
+
```
|
100
|
+
|
101
|
+
## Development
|
102
|
+
|
103
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
104
|
+
|
105
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
106
|
+
|
107
|
+
## Contributing
|
108
|
+
|
109
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/GUI/vault_env_secrets.
|
110
|
+
|
111
|
+
## License
|
112
|
+
|
113
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.test_files = FileList["test/**/test_*.rb"]
|
10
|
+
end
|
11
|
+
|
12
|
+
require "standard/rake"
|
13
|
+
|
14
|
+
task default: %i[test standard]
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "rails/railtie"
|
2
|
+
|
3
|
+
module VaultEnvSecrets
|
4
|
+
class Railtie < ::Rails::Railtie
|
5
|
+
# Load the secret keys as early as possible, so it can be used in other
|
6
|
+
# parts of the Rails configuration, like database.yml files.
|
7
|
+
config.before_configuration do
|
8
|
+
# Load the optional initializer manually (since this before_configuration
|
9
|
+
# phase is before when initializers are usually loaded), so that any
|
10
|
+
# customizations can be read in.
|
11
|
+
initializer = ::Rails.root.join("config", "initializers", "vault_env_secrets.rb")
|
12
|
+
require initializer if File.exist?(initializer)
|
13
|
+
|
14
|
+
VaultEnvSecrets.load
|
15
|
+
end
|
16
|
+
|
17
|
+
# Try to ensure our own "before_configuration" hook gets loaded before any
|
18
|
+
# others that have already been loaded, so that these secrets can be used
|
19
|
+
# as part of other gem's own before_configuration hooks (eg, in the
|
20
|
+
# "config" gem's settings.yml files).
|
21
|
+
load_hooks = ActiveSupport.instance_variable_get(:@load_hooks)
|
22
|
+
if load_hooks && load_hooks[:before_configuration]
|
23
|
+
load_hooks[:before_configuration] = load_hooks[:before_configuration].rotate(-1)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pathname"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
require_relative "vault_env_secrets/errors"
|
7
|
+
require_relative "vault_env_secrets/version"
|
8
|
+
|
9
|
+
module VaultEnvSecrets
|
10
|
+
@enabled = true
|
11
|
+
@consul_template_config = "config/vault.hcl"
|
12
|
+
@consul_template_output = "tmp/vault/secrets.yml"
|
13
|
+
|
14
|
+
class << self
|
15
|
+
attr_accessor :enabled
|
16
|
+
attr_accessor :consul_template_config
|
17
|
+
attr_accessor :consul_template_output
|
18
|
+
|
19
|
+
def load(env: {})
|
20
|
+
if enabled
|
21
|
+
# Check that the expected consul-template config file exists.
|
22
|
+
config_path = Pathname.new(consul_template_config)
|
23
|
+
if defined?(::Rails) && config_path.relative?
|
24
|
+
config_path = Rails.root.join(consul_template_config)
|
25
|
+
end
|
26
|
+
unless config_path.exist?
|
27
|
+
raise Error.new("consul-template config path (#{config_path.to_s.inspect}) does not exist")
|
28
|
+
end
|
29
|
+
|
30
|
+
# Run consul-template to render any template files.
|
31
|
+
system(env, "consul-template", "-config", config_path.to_s, "-once", exception: true)
|
32
|
+
|
33
|
+
# Check that the expected output file exists.
|
34
|
+
output_path = Pathname.new(consul_template_output)
|
35
|
+
if defined?(::Rails) && output_path.relative?
|
36
|
+
output_path = Rails.root.join(consul_template_output)
|
37
|
+
end
|
38
|
+
unless output_path.exist?
|
39
|
+
raise Error.new("consul-template rendered output path (#{output_path.to_s.inspect}) does not exist")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Read the output YAML file and set any of the variables as environment
|
43
|
+
# variables.
|
44
|
+
secrets = YAML.safe_load_file(output_path)
|
45
|
+
if secrets
|
46
|
+
# Make sure the YAML output is an expected hash.
|
47
|
+
unless secrets.is_a?(Hash)
|
48
|
+
raise Error.new("YAML in consul-template output file does not of expected Hash type (#{output_path.to_s.inspect})")
|
49
|
+
end
|
50
|
+
|
51
|
+
secrets.each do |key, value|
|
52
|
+
# Reject nested values that can't be set as simple string values
|
53
|
+
# for environment variable purposes.
|
54
|
+
if value.is_a?(Array) || value.is_a?(Hash)
|
55
|
+
raise Error.new("YAML in consul-template output file has nested data that cannot be set as environment variables (#{output_path.to_s.inspect}: #{key.inspect} type #{value.class.name})")
|
56
|
+
end
|
57
|
+
|
58
|
+
ENV[key] = value.to_s
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
if defined?(::Rails)
|
67
|
+
require_relative "vault_env_secrets/railtie"
|
68
|
+
end
|
metadata
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vault_env_secrets
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nick Muerdter
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-08-19 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- 12112+GUI@users.noreply.github.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".standard.yml"
|
21
|
+
- CHANGELOG.md
|
22
|
+
- Gemfile
|
23
|
+
- Gemfile.lock
|
24
|
+
- LICENSE.txt
|
25
|
+
- README.md
|
26
|
+
- Rakefile
|
27
|
+
- lib/vault_env_secrets.rb
|
28
|
+
- lib/vault_env_secrets/errors.rb
|
29
|
+
- lib/vault_env_secrets/railtie.rb
|
30
|
+
- lib/vault_env_secrets/version.rb
|
31
|
+
- sig/vault_env_secrets.rbs
|
32
|
+
homepage: https://github.com/GUI/vault_env_secrets
|
33
|
+
licenses:
|
34
|
+
- MIT
|
35
|
+
metadata:
|
36
|
+
homepage_uri: https://github.com/GUI/vault_env_secrets
|
37
|
+
source_code_uri: https://github.com/GUI/vault_env_secrets/tree/v1.0.0
|
38
|
+
changelog_uri: https://github.com/GUI/vault_env_secrets/blob/v1.0.0/CHANGELOG.md
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options: []
|
41
|
+
require_paths:
|
42
|
+
- lib
|
43
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 2.6.0
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
requirements: []
|
54
|
+
rubygems_version: 3.4.10
|
55
|
+
signing_key:
|
56
|
+
specification_version: 4
|
57
|
+
summary: Load secrets from Vault into environment variables (via consul-template config
|
58
|
+
and with Rails integration)
|
59
|
+
test_files: []
|