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 Encryption At Rest Laravel Package

paperscissorsandglue/laravel-encryption-at-rest

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package with Composer:

    composer require paperscissorsandglue/laravel-encryption-at-rest
    
  2. Publish the config and migrations:

    php artisan vendor:publish --tag=encryption-at-rest-config
    php artisan vendor:publish --tag=encryption-at-rest-migrations  # for email_index support
    
  3. Add encryption to your models:

    • For standard attributes: use Paperscissorsandglue\EncryptionAtRest\Encryptable;
    • For JSON fields: use Paperscissorsandglue\EncryptionAtRest\EncryptableJson;
    • For user models with encrypted email auth: use Paperscissorsandglue\EncryptionAtRest\HasEncryptedEmail;
  4. First use case: Encrypt a phone and address field on a User model:

    class User extends Model
    {
        use Encryptable;
    
        protected $encryptable = ['phone', 'address'];
    }
    

    Save data like normal — encryption happens automatically on persist.


Implementation Patterns

  • Trait-based adoption
    Apply Encryptable to existing models incrementally. Start with non-critical fields (e.g., phone) before moving to PII like ssn or bank_account.

  • JSON encryption in fragments
    When using $encryptableJson, encrypt only specific top-level keys inside JSON columns (e.g., preferences.notification_email). Keep non-sensitive keys (e.g., theme, language) unencrypted for querying.

  • Encrypted email authentication

    • Add email_index column (via migration).
    • Swap Authenticatable provider to 'driver' => 'encrypted-email'.
    • Run migration tooling to backfill email_index:
      php artisan encryption:encrypt-emails "App\Models\User"
      
  • Batch migration of legacy data
    For pre-existing records:

    php artisan encryption:encrypt-model "App\Models\Order" --filter="payment_status = 'pending'" --chunk=500
    
  • Direct service usage
    Use EncryptionService in non-Eloquent contexts (e.g., caching, queue payloads):

    $this->encryptionService->encrypt($creditCardToken);
    

Gotchas and Tips

  • Double encryption risk
    ⚠️ Critical: Since v0.2.0, encryption now occurs on assignment (not save). Avoid reassigning decrypted values (e.g., $user->email = $user->email;) as this can cause double encryption. Use getAttribute() or clone to prevent re-encryption.

  • Email uniqueness caveat
    email_index is deterministic (SHA256). Two users cannot share the same email, but the index itself is not a security risk — it’s a one-way hash. Still, ensure your email_index column is unique: true.

  • No WHERE on encrypted fields
    Standard Eloquent queries like User::where('phone', '555') will fail — only findByEmail() works for encrypted email. For other fields, store a searchable hash or use application-layer filtering.

  • Attribute casting conflicts
    Don’t define encrypted fields as casts => ['phone' => 'string'] — let the trait’s accessor/mutator handle type conversion.

  • Relationships & serialization
    Relationships work normally. However, when using toArray() or JSON responses, ensure no raw encrypted data leaks (it won’t — the trait re-decrypts on access).

  • CLI safety
    Always use --dry-run first with migration commands. Default backups are helpful but not foolproof — ensure external backups exist too.

  • Key management
    ENCRYPTION_AT_REST_KEY defaults to APP_KEY. Never rotate APP_KEY post-deployment — if you must, use EncryptionService + custom key rotation workflow to re-encrypt existing data.

  • Testing
    Use factories that set sensitive fields as plain text — e.g., ->state(['phone' => '+1-555-1234']). The trait handles encryption transparently during save().

  • Testing encrypted email login
    Test with Auth::attempt(['email' => 'test@example.com', 'password' => '...']) — the encrypted-email provider handles lookups via email_index. Ensure remember_token and sessions work after enabling.

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