Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Ciphersweet Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-ciphersweet
    php artisan vendor:publish --provider="Spatie\CipherSweet\CipherSweetServiceProvider"
    
    • Publishes config (config/ciphersweet.php) and migrations (if using database-backed keys).
  2. Configuration:

    • Set key (base64-encoded) or key_path (file path) in config/ciphersweet.php.
    • Define encryption rules in config/ciphersweet.php under rules:
      'rules' => [
          'users' => [
              'email' => ['encrypt'],
              'ssn' => ['encrypt', 'searchable'],
          ],
      ],
      
  3. First Use Case:

    • Encrypt a field in a model:
      use Spatie\CipherSweet\Eloquent\Concerns\EncryptsAttributes;
      
      class User extends Model
      {
          use Encerns\EncryptsAttributes;
      }
      
    • Automatically encrypts email and ssn (from config) when saved.

Implementation Patterns

Workflows

  1. Model Integration:

    • Use EncryptsAttributes trait for Eloquent models.
    • Define rules in config or per-model:
      class User extends Model
      {
          use Encerns\EncryptsAttributes;
      
          protected $encryptable = ['custom_field'];
      }
      
  2. Querying Encrypted Data:

    • Exact Matches: Works out-of-the-box (e.g., User::where('email', $value)).
    • Searchable Fields: Use search() for partial matches:
      User::where('ssn', 'search', '123')->get();
      
  3. Manual Encryption/Decryption:

    • Use the CipherSweet facade:
      use Spatie\CipherSweet\Facades\CipherSweet;
      
      $encrypted = CipherSweet::encrypt('sensitive_data');
      $decrypted = CipherSweet::decrypt($encrypted);
      
  4. Database Migrations:

    • Run migrations to update existing tables:
      php artisan migrate
      
    • For existing data, use php artisan cipher:sweet:migrate.
  5. API Responses:

    • Automatically decrypts fields when serializing (e.g., with Laravel API resources).

Integration Tips

  • Laravel Scout: Combine with spatie/laravel-scout-ciphersweet for encrypted search in Scout.
  • Validation: Use encrypted rule in Form Requests:
    use Illuminate\Validation\Rule;
    
    $request->validate([
        'email' => ['required', Rule::encrypted()],
    ]);
    
  • Caching: Cache decrypted values in memory (e.g., Redis) for performance-critical paths.
  • Key Rotation: Use php artisan cipher:sweet:rotate-keys to rotate keys periodically.

Gotchas and Tips

Pitfalls

  1. Key Management:

    • Never commit keys to version control. Use environment variables or secure storage.
    • Key Rotation: Test thoroughly after rotating keys; old keys must remain valid for decryption until all data is re-encrypted.
  2. Performance:

    • Searchable Fields: Partial searches (search()) are slower than exact matches. Avoid overusing on large datasets.
    • Indexing: Ensure encrypted columns are indexed in the database for query performance.
  3. Database Schema:

    • Column Types: CipherSweet requires TEXT or BLOB columns for encrypted data. Avoid VARCHAR with fixed lengths.
    • Migration Conflicts: If manually altering tables, ensure column types match CipherSweet’s expectations.
  4. Query Limitations:

    • Unsupported Operators: Avoid LIKE, >, <, etc., on encrypted fields unless using searchable rules.
    • Raw Queries: Use CipherSweet::query() for raw database queries to handle encryption/decryption.
  5. Testing:

    • Mock Keys: Use CipherSweet::setKey() in tests to avoid hardcoding keys.
    • Test Searches: Verify search functionality with edge cases (e.g., empty strings, special characters).

Debugging

  1. Decryption Failures:

    • Check if the key is correctly set in config/ciphersweet.php.
    • Verify the encrypted data isn’t corrupted (e.g., truncated or malformed).
  2. Query Issues:

    • Enable CipherSweet logging in config/ciphersweet.php:
      'log_queries' => env('CIPHERSWEET_LOG_QUERIES', false),
      
    • Check Laravel logs for CipherSweet entries.
  3. Migration Errors:

    • Run php artisan cipher:sweet:install if migrations fail due to missing setup.

Extension Points

  1. Custom Rules:

    • Extend Spatie\CipherSweet\Rules\Rule to create custom encryption behaviors:
      class CustomRule extends Rule
      {
          public function encrypt($value)
          {
              return 'custom_encrypted_' . $value;
          }
      }
      
    • Register in config:
      'rules' => [
          'users' => [
              'custom_field' => ['custom_rule'],
          ],
      ],
      
  2. Key Providers:

    • Implement 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();
          }
      }
      
    • Bind in AppServiceProvider:
      CipherSweet::useKeyProvider(new AwsKmsKeyProvider());
      
  3. Event Listeners:

    • Listen for 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]);
      });
      
  4. Policy Integration:

    • Use policies to restrict decryption to authorized users:
      public function decrypt(User $user, $attribute)
      {
          return $user->hasPermission('decrypt_' . $attribute);
      }
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport