kidfund / laravault
Auto encrypt Eloquent models using Hashicorp Vault
Requires
- php: 5.5.9
- guzzlehttp/guzzle: ~5.3|~6.0
- illuminate/database: 5.*
- illuminate/support: 5.*
- kidfund/thin-transit-client: ^0.9.1
Requires (Dev)
- kidfund/monkey-patcher: ^0.9.1
- orchestra/testbench: ^3.2
- phpunit/phpunit: 4.*
This package is auto-updated.
Last update: 2024-11-11 14:41:50 UTC
README
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:
- The Vault Server
- The Vault Client
- 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.
- Leave the window where you started vault open
- 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) vault init
will give you the master key shards for your instance. Hold on to these- Also make note of the initial root token. Take it and run this:
export VAULT_TOKEN=[YOUR INITIAL ROOT TOKEN]
vault unseal
and put in 3 of the master key shards (keep running the command)vault mount transit
- Create the access policy that Laravel will use:
vault policy-write web ./vendor/kidfund/thin-transit-client/config/vault.policy.web.json
- Get an access token for Laravel:
vault token-create -orphan -policy="web"
- 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
- Model determines if encryption is needed and sends cleartext to Vault Client
- Vault client talks to Vault Server and gets ciphertext
- Vault client hands ciphertext to Laravel Model
- Laravel saves ciphertext in Laravel's data store
Decryption:
- Model retreives ciphertext from Laravel's database
- Model determines if decryption is needed and sends ciphertext to Vault Client
- Vault client talks to Vault Server and gets cleartext
- 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.