matt9mg/doctrine-encryption-bundle
Symfony bundle for transparent field-level encryption in Doctrine entities, letting you store sensitive data encrypted in the database while keeping normal entity usage through configurable encryptors and mappings.
Architecture fit — the headline risk is a framework mismatch. matt9mg/doctrine-encryption-bundle is a Symfony bundle built around Doctrine ORM event subscribers and DBAL custom types. It registers via Symfony's Kernel, services.yaml, and compiler passes. Laravel applications run on Eloquent (ActiveRecord) with service providers and model casts; there is no bundle/Kernel/DI-container-equivalent surface for this package to hook into. Even where Doctrine ORM is present in a Laravel app (via laravel-doctrine/orm), the bundle's Symfony wiring does not travel with it. This is not a package you install — it is a design you would port.
Integration feasibility: low, and it's a rewrite, not an integration. The reusable intellectual content is narrow: a subscriber that intercepts hydration/flush and a custom DBAL type that encrypts/decrypts on read/write. Reproducing that in Laravel means either (a) an Eloquent Cast implementing CastsAttributes, or (b) registering a Doctrine custom type plus a Laravel service provider if the org genuinely runs Doctrine. Either path is a few hundred lines of internal code plus a crypto review — work that would happen anyway and does not depend on this repo.
Technical risk: treat as unmaintained and unreviewed. 1 star, 0 dependents, composite health score 0.065. There is no evidence of external consumption, no meaningful issue/PR traffic to infer from, and no downstream projects to shake out defects. For a component whose only job is protecting regulated data, that is disqualifying on its own: field-level encryption bugs (IV reuse, unauthenticated ciphertext, truncated MACs, key derivation shortcuts) are silent — the application works perfectly while the protection is absent or forgeable, and you find out during a breach or an audit.
Key questions I would put to the maintainer before spending engineering time:
secretbox/AES-256-GCM vs. unauthenticated CBC)? Is the ciphertext authenticated?Stack fit. The Laravel-native answer already exists and is maintained by the framework: encrypted / encrypted:array / encrypted:collection Eloquent casts (Laravel 9+) backed by the Crypt facade, which provides authenticated AES-256-CBC with HMAC and first-class key rotation via APP_PREVIOUS_KEYS. Adopting this bundle instead would mean substituting a framework-maintained, widely audited primitive with a single-maintainer Symfony component we cannot even load.
Migration path. Use the repository strictly as a reference implementation at design time — read how it maps subscriber events to encrypt/decrypt boundaries, and mirror that shape into a Laravel cast (Eloquent) or a Doctrine custom type (if Doctrine is genuinely in the stack). Do not vendor, fork, or add it to composer.json.
Compatibility. Unverified across the board, which is itself the finding: no published Laravel support matrix (expected — it isn't a Laravel package), no confirmed Symfony version floor, no confirmed DBAL major version. Any Doctrine-in-Laravel scenario pins DBAL majors aggressively; a stale custom type against DBAL 3/4 is a breakage waiting for the next composer update.
Sequencing.
halogen/doctrine-encryption or an in-house DBAL type over libsodium), not this one.APP_PREVIOUS_KEYS/equivalent set up at day one — this is the part that actually fails audits.Maintenance. Effectively unowned. A single maintainer with no downstream dependents means no pressure to fix crypto defects and no signal if the project is abandoned mid-quarter. Budget for internal ownership of the ported code plus a documented security review — call it 1–2 engineer-weeks for implementation and review, before key management.
Support. No community, no integration documentation for our stack, no StackOverflow footprint, zero dependents to consult. Every question routes to an individual maintainer or to our own team. That is an unacceptable support posture for a compliance control.
Scaling. Per-field encryption adds CPU on every hydrate/flush and inflates storage (ciphertext + IV + MAC + base64 overhead typically 1.4–2× plaintext). Encrypted columns become unindexable — any query, sort, or unique constraint on a protected field breaks or needs a separately maintained blind index. Key rotation implies a full re-encryption sweep over the affected rows, which needs its own batched, resumable job.
Failure modes. The dangerous ones are quiet: wrong/rotated key produces decryption exceptions that surface as 500s on unrelated endpoints; lost key means permanent, unrecoverable data loss with no escrow; a column sized for plaintext silently truncates ciphertext on strict-mode-off databases; a ported subscriber that misses an update path leaves plaintext in the table with no alerting. Each of these needs an explicit detection control (decrypt-failure alarms, plaintext-presence scans, row-count reconciliation post-backfill) that this package does not ship.
Ramp-up. The team pays Symfony-DI literacy cost for knowledge that does not transfer to the codebase we actually operate. Prefer spending that budget on the team's Laravel encryption, KMS, and data-classification fluency — reusable across every future service.
TPM recommendation: no-go for adoption at any scale. Score 0.065 reflects a package with no adoption and no maintenance on a framework we do not run. Capture it in the build-vs-buy log as evaluated, rejected on framework fit and maintenance risk, and fund the Laravel-native path instead.
How can I help you explore Laravel packages today?