Weave 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' => '[email protected]', '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.
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen
seampact/hooks
seampact/ir
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table