kidfund/laravault

Auto encrypt Eloquent models using Hashicorp Vault

dev-master 2019-10-10 20:51 UTC

This package is auto-updated.

Last update: 2024-05-11 13:36:34 UTC


README

Latest Version on Packagist Software License Build Status Total Downloads

LaraVault uses Hashicorp Vault to encrypt/decrypt specific fields on an Eloquent model, and store the encrypted values in your existing database

Install

Via Composer

$ composer require kidfund/laravault

Usage

Kidfund uses Hashicorp's Vault to encrypt user PII. There are 3 main aspects to this:

  1. The Vault Server
  2. The Vault Client
  3. The Laravel model trait that encrypts/decrypts attributes

The vault server can be run from the command line. If it is installed the server can be started with this command, from the root of the Kidfund project:

vault server -config ./vendor/kidfund/thin-transit-client/config/vault.hcl.example

Vault Setup

If running vault locally for the first time, it needs to be set up. This is only needed for the first time. After this, Laravel will interact with Vault for you. The only exception to this is unseal. You will need to unseal the vault each time it's started.

  1. Leave the window where you started vault open
  2. In a new window: export VAULT_ADDR=http://192.168.20.20:8200 (This is assuming a vagrant/homestead setup. You may be pointing to localhost)
  3. vault init will give you the master key shards for your instance. Hold on to these
  4. Also make note of the initial root token. Take it and run this: export VAULT_TOKEN=[YOUR INITIAL ROOT TOKEN]
  5. vault unseal and put in 3 of the master key shards (keep running the command)
  6. vault mount transit
  7. Create the access policy that Laravel will use: vault policy-write web ./vendor/kidfund/thin-transit-client/config/vault.policy.web.json
  8. Get an access token for Laravel: vault token-create -orphan -policy="web"
  9. Add this token to VAULT_TOKEN= in .env

Vault Process

If a Laravel Model is encrypting a field, these are the general steps taken using Vault's Transit backend

Encryption

  1. Model determines if encryption is needed and sends cleartext to Vault Client
  2. Vault client talks to Vault Server and gets ciphertext
  3. Vault client hands ciphertext to Laravel Model
  4. Laravel saves ciphertext in Laravel's data store

Decryption:

  1. Model retreives ciphertext from Laravel's database
  2. Model determines if decryption is needed and sends ciphertext to Vault Client
  3. Vault client talks to Vault Server and gets cleartext
  4. Vault client hands cleartext to Laravel Model

Laravel Trait

To enable encryption on a trait:

use Kidfund\LaraVault\LaraVault;

class User extends Authenticatable
{
    use LaraVault;

    protected $encrypts = [
		'phone_number',
    ];
}

Fields using Vault MUST be larger than normal:

The ciphertext is a lot longer than the cleartext

$table->string('phone_number', 255)

Notes

  • The master key is unknown to anyone except the operator
  • A different encryption key is used for each field that is encrypted. Each key is encrypted with the master key
  • Every row gets it's own context in Vault
  • Date/Times encrypted by LaraVault must be strings

Testing

Without a running vault instance

$ ./vendor/bin/phpunit --exclude-group EndToEnd

With a running vault instance

$ ./vendor/bin/phpunit

Contributing

Please see CONTRIBUTING and CONDUCT for details.

Security

If you discover any security related issues, please email timothy.broder@gmail.com instead of using the issue tracker.

Credits

License

The MIT License (MIT). Please see License File for more information.