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

Doctrine Encryption Bundle Laravel Package

kyzegs/doctrine-encryption-bundle

A Symfony bundle for Doctrine ORM that adds transparent field-level encryption for sensitive entity data, with configurable encryptors to help protect information at rest while keeping mappings and application code simple.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The flagged mismatch matters more than any individual PR: the artifact is doctrine-encryption-bundle — a Symfony bundle wrapping Doctrine ORM/DBAL, with a *Bundle DI extension and Symfony-style configuration. The request framed this as a Laravel/PHP package, and the two are not interchangeable. There is no Eloquent integration, no Laravel service provider, and no Laravel config surface in this release. The reusable core is the DBAL layer: the encrypted_text type (PR #4) and the blind index helper (PR #3) are Doctrine DBAL primitives and would work under laravel-doctrine/orm, but the bundle scaffolding, config tree, and upgrade command (PR #5) are Symfony-coupled. Assessment: fit is conditional — viable only if the team is already on Doctrine ORM via the Laravel-Doctrine bridge. If the data model is Eloquent, this package is the wrong primitive and we should be evaluating field-level encryption libraries or database-native options (e.g., pgcrypto / column-level KEK- DEK patterns) instead. Confirm the persistence layer before spending further evaluation budget.

Integration feasibility. For a Doctrine-backed Laravel app, integration is a bounded piece of work: register two custom DBAL types (type registration is supported in Laravel-Doctrine config), wire the blind index helper into the repository/query layer, and adopt the 2.0 migration tooling for any pre-existing ciphertext. The unknown is whether the 2.0 ciphertext envelope is byte-compatible with 1.x. PR #5's "dry runs read every value" wording implies the pre-2.0 dry run did not validate all rows — meaning prior rehearsal output is not trustworthy evidence of a clean migration. Treat migration effort as unestimated until the format-compatibility question is answered in writing.

Technical risk. Three concerns dominate, in order:

  1. The data-loss and ciphertext-integrity fix (PR #2) is the headline, and it reads as a defect remediation, not a feature. A v2.0 that fixes "data-loss" means data written under 1.x may be silently corrupt, truncated, or unauthenticated. Until we know whether the defect was write-time (existing rows are already damaged) or read-time (rows are intact, code failed to surface them), we cannot size remediation. This is the single highest-priority unknown and it gates everything else.
  2. Maintainer concentration. Every PR in the release, plus the "New Contributors" entry, is the same author (@Kyzegs), and the changelog spans v1.1.1 → v2.0.0. A security-critical crypto dependency with a one-person maintainership and no visible independent review is a supply-chain and continuity exposure, particularly for a package that now sits in the write path of regulated data.
  3. Crypto surface expansion. The blind index helper (PR #3) adds deterministic, searchable ciphertext. That is a deliberate trade: equality queries become possible, at the cost of leaking frequency and equality patterns to anyone with DB read access, plus a second secret (the index key) that must be managed and rotated in lockstep with the data key. This is a product/security decision, not a technical one, and should not be adopted by default just because it shipped.

Key questions.

  • Does a Laravel/Eloquent path exist, or is this strictly Doctrine ORM? If Eloquent, why are we evaluating this package at all?
  • What precisely did PR #2 fix — write-path corruption, or read-path integrity checking? Are existing 1.x rows recoverable, and is there a verification/re-encryption command?
  • Is 2.0's ciphertext format backward-compatible with 1.x reads, or is a full decrypt-and-rewrite mandatory?
  • What is the supported matrix for PHP, doctrine/dbal (3.x vs 4.x — DBAL 4 materially changed the Type API), and Doctrine ORM?
  • Was a CVE or security advisory issued for the integrity defect, and what is the disclosure timeline for 1.x users?
  • How are keys supplied — env, KMS, Vault? Are blind index keys separable and rotatable independently?
  • What is the package's license, download volume, and issue-tracker responsiveness? Is there any bus-factor mitigation (co-maintainers, org ownership)?
  • How does full-table decrypt perform at our largest encrypted table size (rows × average payload)?

Integration Approach

Stack fit. Do not proceed on the assumption that this is a Laravel package. First fork the decision: (a) if the service is Doctrine-backed (Laravel-Doctrine or Symfony), continue; (b) if Eloquent-backed, stop and re-scope — the encrypted_text DBAL type is not usable from Eloquent without a Doctrine bridge, and adopting one solely to obtain this package is a disproportionate architectural change for a crypto utility. Frame (b) explicitly to stakeholders as "wrong tool," not "tool failed evaluation."

Migration path. Assume a mandatory data migration until proven otherwise. The shape is: freeze writes or dual-write → decrypt every row with 1.x semantics → re-encrypt under 2.0 → verify with the new integrity checks → cut over reads. Because PR #5 makes dry runs read every value, the rehearsal now has real signal — but also real cost and real blast radius (full-table decrypt, plaintext transiently in application memory). Sequence: run the dry run against a production-sized snapshot, not a sample; require a row-count and checksum reconciliation report; require a tested rollback that restores from pre-migration backup rather than attempting reverse-encryption.

Compatibility. Two independent axes to verify before committing: ciphertext format (can 2.0 read 1.x rows mid-migration, enabling a rolling cutover?) and platform versions (PHP minimum, DBAL major, ORM major). A DBAL 4 requirement would be the common blocker, since DBAL 4 removed much of the custom-Type surface that 1.x-era code relied on — if our other packages pin DBAL 3, this becomes a dependency-graph negotiation rather than an install.

Sequencing.

  1. Confirming the persistence-layer question above (blocks everything).
  2. Read PR #2 and PR #5 in full — not the changelog — to establish defect nature and format compatibility. Assign to an engineer with crypto literacy, timeboxed to one day.
  3. Vendor-viability check: license, release cadence, issue responsiveness, whether we would be the only production user of 2.0.0.
  4. Pin to 2.0.x with a lockfile and a documented exception if we must ship on a .0 release; prefer waiting for 2.0.1 if the timeline allows, given a single-contributor release.
  5. Do not adopt the blind index helper in the same change as the 2.0 upgrade. It is a separate feature with a separate security review and a separate key-management story; bundling them makes rollback ambiguous.
  6. Pilot on one non-customer-facing table with a small row count before any production encrypted data is touched.

Operational Impact

Maintenance. We inherit a security-critical dependency with a single active contributor and a young major version. Budget for the possibility of forking: at this scale of package, "we will maintain our own patch set if upstream goes quiet" is a realistic line item, not a hypothetical. Track the package on a watchlist with an owner and a quarterly review — crypto libraries do not age quietly.

Support. Internal support burden is higher than a typical library because the failure signature is silent data corruption rather than exceptions. That means runbooks, not just docs: a documented procedure for "ciphertext fails integrity check in production," a defined escalation path to the security team, and a known-good backup retention window that exceeds our detection latency for corruption. Note also that PR #2's existence implies 1.x-era monitoring would not have caught the defect — we should assume our current alerting is blind to this class of failure until we add integrity verification.

Scaling. Two costs to model. Write path: encryption and blind-index computation add per-row CPU; for high-throughput ingest, measure before assuming it is negligible. Migration path: full-table decrypt-and-rewrite scales linearly with data volume and holds locks or requires dual-write plumbing; size the window against the largest encrypted table, not the average. Blind indexes also add index storage and write amplification, and they degrade the value of encryption at rest against an attacker with DB read access — that is a security trade, not a performance one, but it belongs in the same sizing conversation.

Failure modes. Ranked by consequence: (1) partial migration leaves a mixed-format table where some rows fail to decrypt and the failure surfaces as an application-level error on read, possibly days later; (2) lost or rotated-without-re-encryption key renders data unrecoverable — the highest-severity outcome and entirely a key-management problem, not a library problem; (3) blind index key divergence between app instances silently breaks equality search with no error, just wrong results; (4) dependency conflict on DBAL/ORM major during an unrelated upgrade forces an unplanned crypto migration. Note that (1) and (3) are both silent — plan detection, not just mitigation.

Ramp-up. Engineers need Doctrine DBAL custom-Type familiarity plus enough applied-crypto literacy to reason about envelope formats, IV/nonce handling, and what a blind index does and does not protect. Estimate a half-day of reading plus a supervised first change; the honest cost is not the API surface (which is small) but the review discipline — every change touching this package needs a second reviewer who understands the failure modes, and with a one-person upstream that reviewer has to come from inside.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource