Skip to content

Commit

Permalink
Switch from ActiveSupport to Dry::Credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
svoop committed Mar 7, 2024
1 parent 85e76a9 commit fa6703a
Show file tree
Hide file tree
Showing 21 changed files with 81 additions and 318 deletions.
1 change: 0 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ AllCops:
- LICENSE.txt
- README.md
- Rakefile
- bridgetown.automation.rb

- script/**/*
- vendor/**/*
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Main

Nothing so far
### Breaking Changes
* Switch from ActiveSupport to dry-credentials (see README)

## 0.2.0

Expand Down
91 changes: 40 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

This plugin adds Rails-like encrypted credentials to Bridgetown.

Credentials like passwords, access tokens and other secrets are often passed to sites each by it's own ENV variable. This is both uncool, non-atomic and therefore unreliable. Use this plugin to store your credentials in encrypted YAML files which you can safely commit to your source code repository. In order to use all of them in Bridgetown, you have to set or pass exactly one ENV variable holding the key to decrypt.
Credentials like passwords, access tokens and other secrets are often passed to sites each by its own ENV variable. This is both uncool, non-atomic and therefore unreliable. Use this plugin to store your credentials in encrypted YAML files which you can safely commit to your source code repository. In order to use all of them in Bridgetown, you have to set or pass exactly one ENV variable holding the key to decrypt.

* [Homepage](https://github.com/svoop/bridgetown_credentials)
* [API](https://www.rubydoc.info/gems/bridgetown_credentials)
Expand All @@ -34,12 +34,6 @@ Bundler.setup(:default, Bridgetown.env)
require "bridgetown_credentials"
```

For safety, you should exclude key files from the source code repository:

```shell
bin/bridgetown apply "$(bundle info --path bridgetown_credentials)/bridgetown.automation.rb"
```

### Secure Installation

This gem is [cryptographically signed](https://guides.rubygems.org/security/#using-gems) in order to assure it hasn't been tampered with.
Expand All @@ -51,6 +45,32 @@ gem cert --add <(curl -Ls https://raw.github.com/svoop/bridgetown_credentials/ma
bundle install --trust-policy MediumSecurity
```

## Update from 0.x.x to 1.x.x

From version 1.0.0 upwards, this gem uses [Dry::Credentials](https://rubygems.org/gems/dry-credentials) instead of ActiveSupport (which is planned to be ditched from Bridgetown at some point in the future). This requires you to take some additional steps:

1. Backup the decrypted credentials for every environment:<br>`bin/bridgetown credentials edit -e ENVIRONMENT`
2. Delete (or move elsewhere) your old encrypted credentials files:<br>`rm config/credentials/*`
3. Update this gem to a version >= 1:<br>`bundle update bridgetown_credentials`
4. Create new encrypted credentials files for every environment:<br>`bin/bridgetown credentials edit -e ENVIRONMENT`
5. Step 4 prints the new ENV variable which contains the private key required whenever you edit or query credentials. Example: For the development environment, the new ENV variable `DEVELOPMENT_CREDENTIALS_KEY` replaces the old ENV variable `BRIDGETOWN_DEVELOPMENT_KEY`.

Please note that Dry::Credentials does not support unified environments (one `config/credentials.yml.enc` for both development and production) anymore!

Also, nested credentials have to be queried differently now and thus you might have to update your Bridgetown site accordingly. Given the example credentials from the [Usage section](#usage) below:

```ruby
# Queries on version 0.x.x
Bridgetown.credentials.foo # => "bar"
Bridgetown.credentials.aws[:access_key_id] # => "awsXid"
Bridgetown.credentials.google.dig((:maps, :api_key) # => "goomXkey"

# Queries on version 1.x.x
Bridgetown.credentials.foo # => "bar"
Bridgetown.credentials.aws.access_key_id # => "awsXid"
Bridgetown.credentials.google.maps.api_key # => "goomXkey"
```

## Usage

### First Time
Expand All @@ -76,73 +96,42 @@ google:
api_key: goopXkey
```
After saving the file, the following new files have been created:
```
config/
└─ credentials/
├─ development.key
└─ development.yml.enc
```

⚠️ Move the `*.key` files to a safe place such as a password manager now! Never check them into the source code repository!
After saving, the private key required to encrypt/decrypt the credentials is printed this first time only. Make sure you store this information in a safe place, you will need it in the future.
The credentials you've edited above have been written to `development.yml.enc` and will be available when Bridgetown is in `development` mode.
The credentials you've edited above has been written to `config/credentials/development.yml.enc` and will be loaded when Bridgetown is in `development` mode.

To edit the credentials for `production` mode:

```shell
bin/bridgetown credentials edit -e production
```

To edit or use a credentials file from now on, you have to set the corresponding key as an ENV variable. The actual key is the content of the `*.key` file you should have tucked away above.
To edit or query credentials from now on, the corresponding ENV variable with the private key has to be set:

```shell
export BRIDGETOWN_DEVELOPMENT_KEY="10aabbccddeeff00112233445566778899"
export BRIDGETOWN_PRODUCTION_KEY="20aabbccddeeff00112233445566778899"
export DEVELOPMENT_CREDENTIALS_KEY="4c87...af93"
export PRODUCTION_CREDENTIALS_KEY="92bb...820f"
```

#### Unified Environments

If you prefer not to separate credentials between different environments:

```shell
rm config/credentials/production.*
mv config/credentials/development.yml config/credentials.yml
rmdir config/credentials
```
### Edit

This simplifies the files to:
The command is the same as the first time:

```
config/
└─ credentials.yml.enc
```

To edit or use this from now on, you have to set:


```shell
export BRIDGETOWN_CREDENTIALS_KEY="30aabbccddeeff00112233445566778899"
bin/bridgetown credentials edit
bin/bridgetown credentials edit -e production
```

⚠️ If `config/credentials.yml` is present, any other credentials files are ignored.

### Read
### Query

Throughout the Bridgetown stack, you can now use the credentials as follows:

```ruby
Bridgetown.credentials.foo # => "bar"
Bridgetown.credentials.aws[:access_key_id] # => "awsXid"
Bridgetown.credentials.google.dig((:maps, :api_key) # => "goomXkey"
Bridgetown.credentials.foo # => "bar"
Bridgetown.credentials.aws.access_key_id # => "awsXid"
Bridgetown.credentials.google.maps.api_key # => "goomXkey"
```

### Commands

* `bin/bridgetown credentials edit` – edit the credentials
* `bin/bridgetown credentials show` – dump the decrypted credentials to STDOUT

## Tests

* `bundle exec rake test` to run the test suite
Expand Down
7 changes: 0 additions & 7 deletions bridgetown.automation.rb

This file was deleted.

6 changes: 4 additions & 2 deletions bridgetown_credentials.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
'bug_tracker_uri' => 'https://github.com/svoop/bridgetown_credentials/issues'
}

spec.files = Dir['lib/**/*', '*.automation.rb']
spec.files = Dir['lib/**/*']
spec.test_files = Dir['spec/**/*']
spec.require_paths = %w(lib)

Expand All @@ -46,7 +46,7 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = ">= 3.0.0"

spec.add_runtime_dependency "bridgetown", ">= 1.2.0", "< 2.0"
spec.add_runtime_dependency "activesupport", "~> 7"
spec.add_runtime_dependency "dry-credentials", "~> 0", ">= 0.2.1"

spec.add_development_dependency 'debug'
spec.add_development_dependency 'rake'
Expand All @@ -56,4 +56,6 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'guard'
spec.add_development_dependency 'guard-minitest'
spec.add_development_dependency 'yard'

spec.post_install_message = "⚠️ Breaking change: bridgetown_credentials >= 1.0.0 no longer depends on ActiveSupport. Please read the update section in the README for how to migrate your Bridgetown site. Don't worry, it's a piece of cake!"
end
11 changes: 3 additions & 8 deletions lib/bridgetown_credentials.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
# frozen_string_literal: true

require "dry/credentials"
require "bridgetown"

require 'tempfile'
require 'yaml'
require "active_support/encrypted_configuration"

require_relative "bridgetown_credentials/version"
require_relative "bridgetown_credentials/credentials"
require_relative "bridgetown_credentials/commands"
require_relative "bridgetown_credentials/initializer"
require_relative "bridgetown_credentials/commands/credentials"
require_relative "bridgetown_credentials/bridgetown"

Bridgetown.initializer :bridgetown_credentials do
Bridgetown.extend BridgetownCredentials::Bridgetown
BridgetownCredentials.initializer
end
14 changes: 0 additions & 14 deletions lib/bridgetown_credentials/bridgetown.rb

This file was deleted.

24 changes: 0 additions & 24 deletions lib/bridgetown_credentials/commands.rb

This file was deleted.

15 changes: 4 additions & 11 deletions lib/bridgetown_credentials/commands/credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,15 @@ module BridgetownCredentials
class Commands
class Credentials < Thor
Bridgetown::Commands::Registrations.register do
desc "credentials <command>", "Work with Rails-like encrypted credentials"
desc "credentials <command>", "Work with encrypted credentials"
subcommand "credentials", Credentials
end

desc "edit", "Edit the credentials"
desc "edit", "Edit (or create) encrypted credentials"
option :environment, aliases: '-e'
def edit
ENV['BRIDGETOWN_ENV'] = options['environment'] if options['environment']
BridgetownCredentials::Commands.new.edit
end

desc "show", "Dump the decrypted credentials to STDOUT"
option :environment, aliases: '-e'
def show
ENV['BRIDGETOWN_ENV'] = options['environment'] if options['environment']
BridgetownCredentials::Commands.new.show
BridgetownCredentials.initializer
Bridgetown.credentials.edit! options['environment']
end
end
end
Expand Down
60 changes: 0 additions & 60 deletions lib/bridgetown_credentials/credentials.rb

This file was deleted.

15 changes: 15 additions & 0 deletions lib/bridgetown_credentials/initializer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module BridgetownCredentials
class << self
def initializer
Dry::Credentials::Extension.new.then do |credentials|
credentials[:env] = Bridgetown.env
credentials[:dir] = "#{Bridgetown.configuration.root_dir}/config/credentials"
Pathname(credentials[:dir]).mkpath
credentials.load!
Bridgetown.define_singleton_method(:credentials) { credentials }
end
end
end
end
2 changes: 1 addition & 1 deletion lib/bridgetown_credentials/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module BridgetownCredentials
VERSION = "0.2.0"
VERSION = "0.2.1"
end

This file was deleted.

This file was deleted.

1 change: 0 additions & 1 deletion spec/fixtures/unified/config/credentials.yml.enc

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit fa6703a

Please sign in to comment.