README.md in lockbox-0.6.8 vs README.md in lockbox-1.0.0

- old
+ new

@@ -70,27 +70,25 @@ ## Active Record Create a migration with: ```ruby -class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.1] +class AddEmailCiphertextToUsers < ActiveRecord::Migration[7.0] def change add_column :users, :email_ciphertext, :text end end ``` Add to your model: ```ruby class User < ApplicationRecord - encrypts :email + has_encrypted :email end ``` -**Note:** With Rails 7, use `lockbox_encrypts` instead of `encrypts` - You can use `email` just like any other attribute. ```ruby User.create!(email: "hi@example.org") ``` @@ -101,31 +99,31 @@ You can specify multiple fields in single line. ```ruby class User < ApplicationRecord - encrypts :email, :phone, :city + has_encrypted :email, :phone, :city end ``` #### Types Fields are strings by default. Specify the type of a field with: ```ruby class User < ApplicationRecord - encrypts :born_on, type: :date - encrypts :signed_at, type: :datetime - encrypts :opens_at, type: :time - encrypts :active, type: :boolean - encrypts :salary, type: :integer - encrypts :latitude, type: :float - encrypts :video, type: :binary - encrypts :properties, type: :json - encrypts :settings, type: :hash - encrypts :messages, type: :array - encrypts :ip, type: :inet + has_encrypted :birthday, type: :date + has_encrypted :signed_at, type: :datetime + has_encrypted :opens_at, type: :time + has_encrypted :active, type: :boolean + has_encrypted :salary, type: :integer + has_encrypted :latitude, type: :float + has_encrypted :video, type: :binary + has_encrypted :properties, type: :json + has_encrypted :settings, type: :hash + has_encrypted :messages, type: :array + has_encrypted :ip, type: :inet end ``` **Note:** Use a `text` column for the ciphertext in migrations, regardless of the type @@ -135,19 +133,19 @@ class User < ApplicationRecord serialize :properties, JSON store :settings, accessors: [:color, :homepage] attribute :configuration, CustomType.new - encrypts :properties, :settings, :configuration + has_encrypted :properties, :settings, :configuration end ``` For [StoreModel](https://github.com/DmitryTsepelev/store_model), use: ```ruby class User < ApplicationRecord - encrypts :configuration, type: Configuration.to_type + has_encrypted :configuration, type: Configuration.to_type after_initialize do self.configuration ||= {} end end @@ -174,11 +172,11 @@ Add a new column for the ciphertext, then add to your model: ```ruby class User < ApplicationRecord - encrypts :email, migrating: true + has_encrypted :email, migrating: true end ``` Backfill the data in the Rails console: @@ -188,11 +186,11 @@ Then update the model to the desired state: ```ruby class User < ApplicationRecord - encrypts :email + has_encrypted :email # remove this line after dropping email column self.ignored_columns = ["email"] end ``` @@ -248,11 +246,11 @@ **Note:** Action Text uses direct uploads for files, which cannot be encrypted with application-level encryption like Lockbox. This only encrypts the database field. Create a migration with: ```ruby -class AddBodyCiphertextToRichTexts < ActiveRecord::Migration[6.1] +class AddBodyCiphertextToRichTexts < ActiveRecord::Migration[7.0] def change add_column :action_text_rich_texts, :body_ciphertext, :text end end ``` @@ -287,11 +285,11 @@ ```ruby class User field :email_ciphertext, type: String - encrypts :email + has_encrypted :email end ``` You can use `email` just like any other attribute. @@ -379,11 +377,11 @@ Encryption is applied to all versions after processing. You can mount the uploader [as normal](https://github.com/carrierwaveuploader/carrierwave#activerecord). With Active Record, this involves creating a migration: ```ruby -class AddLicenseToUsers < ActiveRecord::Migration[6.1] +class AddLicenseToUsers < ActiveRecord::Migration[7.0] def change add_column :users, :license, :string end end ``` @@ -572,11 +570,11 @@ Update your model: ```ruby class User < ApplicationRecord - encrypts :email, previous_versions: [{master_key: previous_key}] + has_encrypted :email, previous_versions: [{master_key: previous_key}] end ``` To rotate existing records, use: @@ -708,28 +706,34 @@ **For users who do a lot of encryptions:** You should rotate an individual key after 2 billion encryptions to minimize the chance of a [nonce collision](https://www.cryptologie.net/article/402/is-symmetric-security-solved/), which will expose the authentication key. Each database field and file uploader use a different key (derived from the master key) to extend this window. ### XSalsa20 -You can also use XSalsa20, which uses an extended nonce so you don’t have to worry about nonce collisions. First, [install Libsodium](https://github.com/crypto-rb/rbnacl/wiki/Installing-libsodium). For Homebrew, use: +You can also use XSalsa20, which uses an extended nonce so you don’t have to worry about nonce collisions. First, [install Libsodium](https://github.com/crypto-rb/rbnacl/wiki/Installing-libsodium). It comes preinstalled on [Heroku](https://devcenter.heroku.com/articles/stack-packages). For Homebrew, use: ```sh brew install libsodium ``` -And add to your Gemfile: +And for Ubuntu, use: +```sh +sudo apt-get install libsodium23 +``` + +Then add to your Gemfile: + ```ruby gem "rbnacl" ``` -Then add to your model: +And add to your model: ```ruby class User < ApplicationRecord - encrypts :email, algorithm: "xsalsa20" + has_encrypted :email, algorithm: "xsalsa20" end ``` Make it the default with: @@ -737,76 +741,10 @@ Lockbox.default_options = {algorithm: "xsalsa20"} ``` You can also pass an algorithm to `previous_versions` for key rotation. -#### XSalsa20 Deployment - -##### Heroku - -Heroku [comes with libsodium](https://devcenter.heroku.com/articles/stack-packages) preinstalled. - -##### Ubuntu - -For Ubuntu 20.04 and 18.04, use: - -```sh -sudo apt-get install libsodium23 -``` - -For Ubuntu 16.04, use: - -```sh -sudo apt-get install libsodium18 -``` - -##### GitHub Actions - -For Ubuntu 20.04 and 18.04, use: - -```yml - - name: Install Libsodium - run: sudo apt-get update && sudo apt-get install libsodium23 -``` - -For Ubuntu 16.04, use: - -```yml - - name: Install Libsodium - run: sudo apt-get update && sudo apt-get install libsodium18 -``` - -##### Travis CI - -On Bionic, add to `.travis.yml`: - -```yml -addons: - apt: - packages: - - libsodium23 -``` - -On Xenial, add to `.travis.yml`: - -```yml -addons: - apt: - packages: - - libsodium18 -``` - -##### CircleCI - -Add a step to `.circleci/config.yml`: - -```yml -- run: - name: install Libsodium - command: sudo apt-get install -y libsodium18 -``` - ## Hybrid Cryptography [Hybrid cryptography](https://en.wikipedia.org/wiki/Hybrid_cryptosystem) allows servers to encrypt data without being able to decrypt it. Follow the instructions above for installing Libsodium and including `rbnacl` in your Gemfile. @@ -819,11 +757,11 @@ Store the keys with your other secrets. Then use: ```ruby class User < ApplicationRecord - encrypts :email, algorithm: "hybrid", encryption_key: encryption_key, decryption_key: decryption_key + has_encrypted :email, algorithm: "hybrid", encryption_key: encryption_key, decryption_key: decryption_key end ``` Make sure `decryption_key` is `nil` on servers that shouldn’t decrypt. @@ -849,55 +787,55 @@ To rename a table with encrypted columns/uploaders, use: ```ruby class User < ApplicationRecord - encrypts :email, key_table: "original_table" + has_encrypted :email, key_table: "original_table" end ``` To rename an encrypted column itself, use: ```ruby class User < ApplicationRecord - encrypts :email, key_attribute: "original_column" + has_encrypted :email, key_attribute: "original_column" end ``` ### Per Field/Uploader To set a key for an individual field/uploader, use a string: ```ruby class User < ApplicationRecord - encrypts :email, key: ENV["USER_EMAIL_ENCRYPTION_KEY"] + has_encrypted :email, key: ENV["USER_EMAIL_ENCRYPTION_KEY"] end ``` Or a proc: ```ruby class User < ApplicationRecord - encrypts :email, key: -> { code } + has_encrypted :email, key: -> { code } end ``` ### Per Record To use a different key for each record, use a symbol: ```ruby class User < ApplicationRecord - encrypts :email, key: :some_method + has_encrypted :email, key: :some_method end ``` Or a proc: ```ruby class User < ApplicationRecord - encrypts :email, key: -> { some_method } + has_encrypted :email, key: -> { some_method } end ``` ## Key Management @@ -905,11 +843,11 @@ For Active Record and Mongoid, use: ```ruby class User < ApplicationRecord - encrypts :email, key: :kms_key + has_encrypted :email, key: :kms_key end ``` For Action Text, use: @@ -993,22 +931,22 @@ ## Binary Columns You can use `binary` columns for the ciphertext instead of `text` columns. ```ruby -class AddEmailCiphertextToUsers < ActiveRecord::Migration[6.1] +class AddEmailCiphertextToUsers < ActiveRecord::Migration[7.0] def change add_column :users, :email_ciphertext, :binary end end ``` Disable Base64 encoding to save space. ```ruby class User < ApplicationRecord - encrypts :email, encode: false + has_encrypted :email, encode: false end ``` ## Compatibility @@ -1038,23 +976,23 @@ ``` Create a migration with: ```ruby -class MigrateToLockbox < ActiveRecord::Migration[6.1] +class MigrateToLockbox < ActiveRecord::Migration[7.0] def change add_column :users, :name_ciphertext, :text add_column :users, :email_ciphertext, :text end end ``` -And add `encrypts` to your model with the `migrating` option: +And add `has_encrypted` to your model with the `migrating` option: ```ruby class User < ApplicationRecord - encrypts :name, :email, migrating: true + has_encrypted :name, :email, migrating: true end ``` Then run: @@ -1064,27 +1002,37 @@ Once all records are migrated, remove the `migrating` option and the previous model code (the `attr_encrypted` methods in this example). ```ruby class User < ApplicationRecord - encrypts :name, :email + has_encrypted :name, :email end ``` Then remove the previous gem from your Gemfile and drop its columns. ```ruby -class RemovePreviousEncryptedColumns < ActiveRecord::Migration[6.1] +class RemovePreviousEncryptedColumns < ActiveRecord::Migration[7.0] def change remove_column :users, :encrypted_name, :text remove_column :users, :encrypted_name_iv, :text remove_column :users, :encrypted_email, :text remove_column :users, :encrypted_email_iv, :text end end ``` ## Upgrading + +### 1.0.0 + +`encrypts` is now deprecated in favor of `has_encrypted` to avoid conflicting with Active Record encryption. + +```ruby +class User < ApplicationRecord + has_encrypted :email +end +``` ### 0.6.0 0.6.0 adds `encrypted: true` to Active Storage metadata for new files. This field is informational, but if you prefer to add it to existing files, use: