spatie/laravel-ciphersweet
Laravel wrapper for Paragonie CipherSweet that adds searchable field-level encryption to Eloquent models. Encrypt/decrypt sensitive attributes and generate blind indexes so you can query encrypted data securely without exposing readable values in your database.
Installation:
composer require spatie/laravel-ciphersweet
php artisan vendor:publish --provider="Spatie\CipherSweet\CipherSweetServiceProvider"
config/ciphersweet.php) and migrations (if using database-backed keys).Configuration:
key (base64-encoded) or key_path (file path) in config/ciphersweet.php.config/ciphersweet.php under rules:
'rules' => [
'users' => [
'email' => ['encrypt'],
'ssn' => ['encrypt', 'searchable'],
],
],
First Use Case:
use Spatie\CipherSweet\Eloquent\Concerns\EncryptsAttributes;
class User extends Model
{
use Encerns\EncryptsAttributes;
}
email and ssn (from config) when saved.Model Integration:
EncryptsAttributes trait for Eloquent models.class User extends Model
{
use Encerns\EncryptsAttributes;
protected $encryptable = ['custom_field'];
}
Querying Encrypted Data:
User::where('email', $value)).search() for partial matches:
User::where('ssn', 'search', '123')->get();
Manual Encryption/Decryption:
CipherSweet facade:
use Spatie\CipherSweet\Facades\CipherSweet;
$encrypted = CipherSweet::encrypt('sensitive_data');
$decrypted = CipherSweet::decrypt($encrypted);
Database Migrations:
php artisan migrate
php artisan cipher:sweet:migrate.API Responses:
spatie/laravel-scout-ciphersweet for encrypted search in Scout.encrypted rule in Form Requests:
use Illuminate\Validation\Rule;
$request->validate([
'email' => ['required', Rule::encrypted()],
]);
php artisan cipher:sweet:rotate-keys to rotate keys periodically.Key Management:
Performance:
search()) are slower than exact matches. Avoid overusing on large datasets.Database Schema:
TEXT or BLOB columns for encrypted data. Avoid VARCHAR with fixed lengths.Query Limitations:
LIKE, >, <, etc., on encrypted fields unless using searchable rules.CipherSweet::query() for raw database queries to handle encryption/decryption.Testing:
CipherSweet::setKey() in tests to avoid hardcoding keys.Decryption Failures:
config/ciphersweet.php.Query Issues:
config/ciphersweet.php:
'log_queries' => env('CIPHERSWEET_LOG_QUERIES', false),
CipherSweet entries.Migration Errors:
php artisan cipher:sweet:install if migrations fail due to missing setup.Custom Rules:
Spatie\CipherSweet\Rules\Rule to create custom encryption behaviors:
class CustomRule extends Rule
{
public function encrypt($value)
{
return 'custom_encrypted_' . $value;
}
}
'rules' => [
'users' => [
'custom_field' => ['custom_rule'],
],
],
Key Providers:
Spatie\CipherSweet\KeyProviderInterface for dynamic key loading (e.g., from AWS KMS):
class AwsKmsKeyProvider implements KeyProviderInterface
{
public function getKey(): string
{
return aws_kms_get_key();
}
}
AppServiceProvider:
CipherSweet::useKeyProvider(new AwsKmsKeyProvider());
Event Listeners:
CipherSweet\Events\Encrypted and CipherSweet\Events\Decrypted to log or audit encryption/decryption:
Event::listen(CipherSweetEvents::ENCRYPTED, function ($event) {
Log::info('Encrypted field', ['field' => $event->field, 'value' => $event->value]);
});
Policy Integration:
public function decrypt(User $user, $attribute)
{
return $user->hasPermission('decrypt_' . $attribute);
}
How can I help you explore Laravel packages today?