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

Doctrine Encrypt Bundle Laravel Package

coka/doctrine-encrypt-bundle

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Use Case Alignment: The package provides encrypted Doctrine field types (e.g., EncryptedString, EncryptedText, EncryptedInteger), which aligns with Laravel applications requiring PII/GDPR-compliant data storage (e.g., passwords, credit cards, health records) or multi-tenant isolation without application-layer encryption.
  • Laravel Compatibility: While designed for Symfony’s Doctrine ORM, it can be adapted for Laravel via Doctrine DBAL (used by Eloquent) or custom field types. Laravel’s native encryption (e.g., encrypt() helper) is simpler for basic use cases, but this package offers database-level encryption with OpenSSL, reducing application overhead.
  • Performance Trade-offs:
    • Pros: Encryption/decryption happens at the database layer, reducing application-side logic.
    • Cons: OpenSSL operations add ~5–10ms per field (benchmark-dependent). May impact bulk operations (e.g., Model::all()).

Integration Feasibility

  • Doctrine DBAL Bridge: Laravel’s Eloquent uses Doctrine DBAL under the hood, so the bundle can be integrated via:
    • Custom Accessors: Override Eloquent getters/setters to use the encrypted types.
    • Query Builder Hooks: Intercept queries to decrypt results (e.g., via Model::boot()).
  • Schema Migrations: Existing encrypted fields would require column updates (e.g., ALTER TABLE users MODIFY credit_card VARCHAR(255)), risking downtime in production.
  • Caching: Encrypted data cannot be cached in Redis/Memcached without decryption, limiting performance gains.

Technical Risk

  • OpenSSL Dependencies:
    • Key Management: No built-in key rotation or secure key storage (risk of hardcoded keys in config.php).
    • Algorithm Limitations: Uses OpenSSL’s AES-256-CBC by default (vulnerable to padding oracle attacks if not configured with OPENSSL_RAW_DATA).
  • Laravel-Specific Gaps:
    • No native support for Laravel’s serialization (e.g., encrypted:array fields).
    • Potential conflicts with Laravel’s query caching or model events.
  • Testing Overhead:
    • Encrypted fields complicate unit tests (mocking OpenSSL) and database snapshots (encrypted data won’t match plaintext).
    • CI/CD: Requires OpenSSL extensions in test environments.

Key Questions

  1. Why not Laravel’s encrypt() helper?
    • Does the team need database-level encryption (e.g., for compliance audits) or is application-layer encryption sufficient?
  2. Key Management Strategy:
    • How will encryption keys be stored/rotated? (e.g., AWS KMS, environment variables, HashiCorp Vault).
  3. Performance Baseline:
    • What’s the acceptable latency for encrypted fields? (Benchmark with microtime(true).)
  4. Migration Path:
    • Can new fields use this bundle, or must existing encrypted data be backfilled?
  5. Multi-Environment Sync:
    • How will keys be synchronized across dev/staging/prod?

Integration Approach

Stack Fit

  • Laravel + Doctrine DBAL:
    • Recommended: Use the bundle via custom Eloquent attributes or a Doctrine DBAL listener to decrypt data before it reaches the application.
    • Example:
      // app/Models/User.php
      use Doctrine\DBAL\Types\Types;
      use Doctrine\DBAL\Platforms\AbstractPlatform;
      
      class User extends Model {
          protected $casts = [
              'credit_card' => 'encrypted_string',
          ];
      
          public function getAttribute($key) {
              if ($key === 'credit_card' && $this->isEncrypted($key)) {
                  return $this->decryptAttribute($key);
              }
              return parent::getAttribute($key);
          }
      }
      
  • Alternatives:
    • Laravel Encryption: For simple use cases, prefer Str::of($value)->encrypt() (no DBAL overhead).
    • Trait-Based: Create a reusable Encryptable trait for models needing encrypted fields.

Migration Path

  1. Phase 1: New Fields Only
    • Add encrypted fields to new models/tables without altering existing data.
    • Use Doctrine Event Listeners to decrypt only when accessed.
  2. Phase 2: Backfill Existing Data
    • Write a data migration to encrypt sensitive columns (e.g., using doctrine:query).
    • Example:
      php artisan doctrine:query "UPDATE users SET credit_card = ENCRYPT(credit_card, 'key')"
      
  3. Phase 3: Full Integration
    • Replace all encrypt() calls with the bundle’s types.
    • Update queries to avoid decrypting unnecessary fields (e.g., SELECT id, name FROM users).

Compatibility

  • Doctrine DBAL: Works with Laravel 8+ (Doctrine DBAL v3.1+).
  • PHP Extensions: Requires openssl and pdo extensions.
  • Database: Tested with MySQL/PostgreSQL (no SQL Server support).
  • Caveats:
    • Full-Text Search: Encrypted fields cannot be indexed.
    • Sorting: Encrypted strings cannot be sorted alphabetically without decryption.

Sequencing

  1. Spike: Benchmark OpenSSL overhead vs. Laravel’s encrypt().
  2. Pilot: Test with a non-critical model (e.g., User::api_token).
  3. Rollout:
    • Start with read-heavy fields (e.g., PII in profiles).
    • Avoid write-heavy fields (e.g., logs, audit trails) due to encryption latency.
  4. Monitor: Track:
    • Query execution time (DB::enableQueryLog()).
    • Decryption failures (e.g., corrupted keys).

Operational Impact

Maintenance

  • Key Rotation:
    • Process: Requires re-encrypting all data with new keys (use a migration script).
    • Downtime: Minimize by using double encryption during transition.
  • Dependency Updates:
    • Bundle is unmaintained (last commit: [YYYY-MM-DD]). Fork or monitor for security patches.
  • Debugging:
    • Encrypted data in logs/errors reduces observability. Use sensitive data redaction (e.g., Laravel’s App\Exceptions\Handler).

Support

  • Troubleshooting:
    • Common Issues:
      • OpenSSL errors if keys are malformed or missing.
      • Silent failures if decryption fails (wrap in try-catch).
    • Tools:
      • Add a debug:decrypt Artisan command to test encrypted values.
      • Log decryption attempts (without exposing keys).
  • Documentation:
    • Create internal runbooks for:
      • Key recovery procedures.
      • Handling corrupted encrypted data.

Scaling

  • Horizontal Scaling:
    • Stateless: Keys must be shared across all instances (use consul/etcd or environment variables).
    • Caching: Avoid caching encrypted data (e.g., Redis) unless decrypted first.
  • Database Load:
    • Encryption adds CPU load to the database server. Monitor openssl usage in top/htop.
  • Sharding:
    • Each shard needs its own key management (complexity increases linearly).

Failure Modes

Failure Scenario Impact Mitigation
Lost encryption key Permanent data loss Backup keys in HSM or KMS.
OpenSSL misconfiguration Data corruption Use OPENSSL_RAW_DATA flag.
Database corruption Unreadable encrypted fields Regular backups + CHECKSUM validation.
Key rotation failure Data becomes unreadable Test rotation in staging first.
High query latency Poor user experience Cache decrypted data (short TTL).

Ramp-Up

  • Onboarding:
    • Developers:
      • Train on custom accessors and Doctrine events.
      • Document where to use encrypted fields (e.g., not for searchable data).
    • DevOps:
      • Ensure OpenSSL is enabled in Docker/PaaS (e.g., RUN docker-php-ext-install openssl).
  • Training:
    • Workshop on:
      • Key management best practices.
      • Performance tuning (e.g., batch decryption).
  • Checklist for New Features:
    • Is this field PII? → Encrypt.
    • Will this field be searched/sorted? → Avoid encryption.
    • Does this require multi-region compliance? → Use HSM-backed keys.
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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours