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

Encrypted Fields Bundle Laravel Package

dwgebler/encrypted-fields-bundle

Symfony bundle that encrypts and decrypts Doctrine entity fields via a simple attribute, using a master key to generate secure per-row encryption keys stored in a separate table. Supports key rotation, UUID and composite primary keys.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Feature prioritization and compliance roadmap. Field-level encryption of sensitive Doctrine entity columns (PII, payment fragments, health data, internal notes) is a checkbox against GDPR/HIPAA/PCI-style requirements. This package turns that from a multi-sprint build into an attribute annotation plus config, so compliance-driven epics can be scheduled realistically rather than deferred.
  • Build vs. buy. It replaces hand-rolled crypto (key generation, per-row key storage, cipher selection, rotation) that a team would otherwise maintain and audit forever. The MIT license and small surface area keep the exit door open — a managed KMS or spatie/laravel-encryption-style replacement can be swapped in later without rewriting domain logic.
  • Architecture-scoping decision, not just a feature decision. This is a Symfony bundle, not a Laravel package: it is configured through Symfony Flex, Symfony YAML, and Symfony console commands, and it hooks Doctrine ORM lifecycle events. "Adopt this" therefore really means "adopt Doctrine ORM in our Laravel app (via laravel-doctrine/orm), then hand-wire a Symfony bundle." That is an architecture change, so the decision belongs at the platform/tech-lead level, not inside a single feature.
  • Search and queryability trade-off. AES-256-GCM with random IVs produces non-deterministic ciphertext, so WHERE, ORDER BY, LIKE, GROUP BY, uniqueness constraints, and reporting/export on encrypted columns stop working at the DB layer. Any feature that filters or sorts on a candidate field needs a blind index or a separate search store. Scope this before committing — it is routinely 5–10x the effort of the encryption work itself.
  • Phased roadmap:
    • Phase 0 — Feasibility: confirm Doctrine is acceptable in the target service; inventory every field, query, and export that touches candidate columns. No code.
    • Phase 1 — Pilot: encrypt one low-risk-but-sensitive field, with a working backfill path and a widened column.
    • Phase 2 — Expand: core PII, once key rotation and secrets-manager storage are proven and monitored.
    • Phase 3 — Mature or migrate: audit logging on the encryption_key table, and a plan to move to a managed KMS if scale or regulatory pressure demands it.
  • Use cases: Symfony/Doctrine services needing per-field encryption without full-database TDE; legacy systems retrofitted with Doctrine; multi-tenant SaaS isolating per-tenant sensitive data. In a pure Eloquent Laravel codebase, the realistic value is near zero — treat this as "no, unless we are already adopting Doctrine."

When to Consider This Package

Adopt if:

  • Your application already runs Symfony with Doctrine ORM, or you have made a committed, funded decision to adopt Doctrine in Laravel. Doctrine is a prerequisite, not a detail.
  • You need field-level, per-row encryption with a real key hierarchy — a master key wrapping a unique per-row data key stored in a dedicated encryption_key table. Key rotation becomes a re-wrap of small rows rather than a re-encryption of the entire dataset, which is a genuinely better posture than "one key for everything."
  • You can run AES-256-GCM via OpenSSL and store the master key in a secrets manager, not a plaintext env file.
  • You have reviewed every query, index, unique constraint, and export that touches a candidate column and accepted or re-architected each one.
  • You have a backfill and mixed-state read strategy for existing plaintext rows. The README describes none. A fallback that "treats undecryptable as plaintext" silently undermines the entire control — do not ship that.
  • You have widened columns and migrated types. Ciphertext (IV + tag + base64) is materially larger than plaintext; VARCHAR(255) and typed columns (int, date, bool) need attention.
  • You have a path to cover write paths that bypass Doctrine listeners — bulk DQL UPDATE/DELETE, raw SQL, DBAL-level writes, partial hydration. Silent plaintext in a column the team believes is encrypted is the worst possible failure mode, and this package cannot see those writes.
  • You can tolerate low maturity: ~7 GitHub stars, one maintainer, zero dependents, a short release history, and a 2.0 that fixed a silent data-loss bug present throughout 1.x. That last point is the honest headline for any risk review — upgrade and pin deliberately.

Look elsewhere if:

  • You are Eloquent-only or on a non-Doctrine ORM. The integration cost dominates any benefit.
  • You need HSM-backed keys, FIPS 140-2 validation, or managed rotation at scale.
  • Your data is already encrypted at rest via database TDE or a cloud KMS, and the goal is satisfied.
  • You need high-throughput read/write performance on the encrypted columns — per-row key operations are unbenchmarked here.
  • You want a Laravel-native, widely adopted option (spatie/laravel-encryption or equivalent) with an Eloquent-native developer experience.
  • Your security policy forbids a single-maintainer, low-adoption dependency in the encryption path. That is a legitimate and common ruling — plan for the migration you will eventually need to do anyway.

How to Pitch It (Stakeholders)

For executives. "This would let us encrypt sensitive customer fields — payment fragments, health data, identifiers — automatically when they are written to the database, with very little custom code. It helps us meet GDPR/HIPAA-style obligations and shrinks the impact of a breach. Two honest caveats. First, it is a Symfony component, so getting it into our Laravel stack means first standardizing on Doctrine ORM for that service — an architecture decision with its own cost, not a one-line install. Second, any field we encrypt loses the ability to be filtered, sorted, or searched directly, so each candidate field needs a product-level look at which features depend on querying it. I am not recommending adoption today. I am recommending a small, time-boxed feasibility spike on one low-risk field so we can cost the Doctrine question and the query impact with real numbers instead of estimates. That is far cheaper than either an enterprise encryption platform or an unbounded compliance build."

For engineering. "Concretely: dwgebler/encrypted-fields-bundle is a Symfony bundle that hooks Doctrine lifecycle events and reads #[EncryptedField] attributes. It is configured by Symfony Flex, YAML, and bin/console commands. There is no service provider, no artisan command, no Eloquent support. Under Laravel we would first add laravel-doctrine/orm and then hand-wire a Symfony bundle's container config — that is an architecture change, so treat it as a platform decision, not a ticket. What we get if we do it: AES-256-GCM authenticated encryption by default, per-row keys wrapped by a master key and stored in an encryption_key table, declarative attribute usage, selective encryption of array elements, and a working rotation command (gebler:encryption:rotate-key with --generate-new-key, --database-key, --database-key-file). What we own afterward, and must scope explicitly:

  • Non-deterministic ciphertext. Every WHERE, ORDER BY, LIKE, GROUP BY, unique index, and reporting export on a candidate column breaks or needs a blind-index rewrite. Inventory this before estimating.
  • Listener bypass. Bulk DQL, raw SQL, DBAL writes, and partial hydration will write plaintext silently. Enumerate and guard these call sites.
  • Backfill. No documented migration path for existing plaintext rows, and no safe mixed-state read. We design this ourselves.
  • Schema. Ciphertext is bigger; columns need widening and typed columns need conversion.
  • Pin and upgrade deliberately. The 2.0 release fixed a silent data-loss bug present in 1.x. Do not run 1.x.
  • Dependency risk. One maintainer, ~7 stars, no dependents. Assume we may need to fork or replace it; keep the encryption boundary interface-shaped so that stays cheap. Next step is a one-field spike plus a written inventory of query and write paths that touch candidate columns. That document is the real deliverable — it is what tells us whether the Doctrine move pays for itself."
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.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log