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

Field Encrypt Bundle Laravel Package

insitaction/field-encrypt-bundle

Insitaction FieldEncryptBundle provides transparent field-level encryption for Doctrine entities in Symfony, letting you mark sensitive fields for automatic encryption and decryption with configurable keys and minimal code changes.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

The package targets application-layer field encryption: plaintext is encrypted inside the PHP process and only ciphertext reaches the database, so the threat model is "DBA, backup, replica, and log exposure" rather than "compromised host." That is the right layer for PII/PCI scoped columns where full-disk or TDE is insufficient because operators can still read rows.

The critical fit question is the name, and v3.0.5 answers it: "Allow symfony 7" is a Symfony-framework compatibility change. This is a Symfony bundle (Doctrine DBAL type + DI extension + services.yaml), not a Laravel package. Laravel has no bundle or container-extension concept, so a Doctrine-coupled core does not drop into Eloquent. Fit is conditional on the cipher primitive being decoupled from DBAL event subscribers and Doctrine column types. If it is, you wrap it in a custom Eloquent cast and get a clean architectural seam. If it is not, you are porting, not integrating — and this release is evidence toward the latter, since the maintainer's release cadence is driven by Symfony version support rather than by framework-agnostic crypto work.

Second fit question: Laravel already ships an encrypted cast and an Encrypter service backed by APP_KEY. Native covers naive "encrypt this column" use. This package only earns a place in the stack if it provides what native does not — deterministic encryption for equality lookups, blind-index support, ciphertext versioning, or KMS-backed key providers. Without a differentiator, architecture fit is negative: added dependency for parity functionality.

Integration feasibility

Low-to-moderate, gated entirely on decoupling, and the v3.0.5 release does not improve this. A Symfony-7-compatibility patch tells you the maintained surface area is the Symfony/Doctrine integration — the part you cannot use — rather than a standalone crypto library. Expect to extract, not to integrate.

The realistic path is a custom cast (Attribute::make(get: decrypt, set: encrypt)) or a Castable class delegating to the package's crypto service, plus a Builder macro if you need encrypted-field query helpers. That is a few hundred lines of glue, not a rewrite — plus whatever it takes to strip or stub the Doctrine DBAL type and Symfony DI extension so the primitive will autoload outside a Symfony kernel.

What pushes effort up: schema changes (ciphertext plus base64 encoding and nonce/tag overhead typically grows payload 1.5–3x, so VARCHAR(255) becomes TEXT or VARCHAR(512)), index invalidation on every encrypted column, and the absence of a Laravel service provider means you own wiring, config publishing, and container bindings yourself. Note also that Symfony 7 requires PHP 8.2+, so the package's effective PHP floor has likely moved up — verify against your fleet before assuming Laravel 10 on PHP 8.1 is supported.

Technical risk

High, concentrated in two places.

Supply-chain and crypto provenance. The v3.0.5 release corrects one data point in the prior assessment: this is not a single-release package — there is a v3.0.4 → v3.0.5 history, and a maintainer tracking upstream Symfony releases is at least alive. That is a marginal positive for "will it get patched for framework breakage." It does not change the dominant risk: zero dependents, no external validation, no CVE history, no evidence of third-party crypto review, and a 0.185 composite score. Maintenance activity on framework compatibility is not the same as maintenance activity on cryptographic correctness. For a component whose sole responsibility is cryptography, "no downstream users stress-testing it" remains the leading concern.

Key management. The package likely solves the easy half (AES the bytes) and leaves the hard half to you: where keys live, how they rotate, how ciphertexts are versioned so old and new keys coexist, and whether the mode is authenticated (GCM/secretbox) versus unauthenticated (CBC). Unauthenticated modes plus a mutable ciphertext column means an attacker with write access can tamper or splice ciphertexts between rows unless AAD binds each record.

Key questions

  1. Is this a Laravel package at all, or a Symfony bundle with a misleading label in the registry? Answered by v3.0.5: it is a Symfony bundle. Treat the registry label as a mis-tag and plan accordingly.
  2. Is the crypto core PSR-3/PSR-11 friendly and framework-agnostic, or bound to Doctrine DBAL types and Symfony DI? (Now the single highest-leverage unknown — everything downstream depends on the answer.)
  3. Which cipher and mode — AES-256-GCM, XSalsa20-Poly1305, CBC? Is authentication enforced and is AAD bound to row identity?
  4. Does it support key rotation with ciphertext version prefixes, and can keys be sourced from AWS KMS / GCP KMS / Vault rather than env vars?
  5. Does it offer deterministic mode or blind indexes, and does the documentation state the leakage tradeoff explicitly?
  6. Did v3.0.5 drop Symfony 5/6 or raise the PHP floor, and does the changelog's "allow Symfony 7" imply a widening of the constraint (safe) or a replacement of it (a breaking change for existing consumers that also signals a short support window)?
  7. Who maintains it, what is the disclosure policy, and is there any test suite covering nonce reuse and tamper detection? Has the test suite changed between v3.0.4 and v3.0.5, or was this a constraint-only bump?

Integration Approach

Stack fit

Presumes PHP 8.2+ (Symfony 7 floor), Laravel 10/11, Eloquent, MySQL or Postgres. Fit is good for append-mostly, read-by-primary-key PII columns (government IDs, phone numbers, addresses, payment tokens, health notes). Fit is poor for any column you filter, sort, aggregate, join, or LIKE on, unless deterministic encryption or a blind index is supported — and deterministic encryption on low-cardinality fields (status, country, boolean-ish flags) is a frequency-analysis gift to an attacker. Scope the column list before scoping the code.

The v3.0.5 signal sharpens the framing: you are not adopting a Laravel library, you are vendoring a Symfony component's crypto primitive. Budget the integration as a port with an upstream source, not as a composer require with a cast on top.

Migration path

Do not adopt the bundle wholesale; treat it as a source of a cipher primitive.

  1. Encrypt-in-place risk is real: existing plaintext rows need a chunked backfill job with idempotent "already ciphertext?" detection, run against a replica-tested copy first.
  2. Introduce dual-read: decrypt-if-ciphertext, pass-through-if-plaintext, so the app tolerates mixed state during the backfill window.
  3. Widen columns and drop or rebuild indexes on encrypted fields in the same migration; a UNIQUE constraint on a randomized ciphertext column is meaningless and will silently stop enforcing uniqueness — that is a data-integrity regression, not a performance one. Use a blind index with a UNIQUE constraint if uniqueness must survive.
  4. Run shadow writes to a parallel encrypted column for one release before cutover, so you can diff decrypt(round-trip) against source.

Compatibility

Native encrypted casts coexist fine with a custom cast as long as each column has exactly one cast. Laravel's APP_PREVIOUS_KEYS rotation is column-agnostic and global; if this package versions keys per field, do not mix the two rotation mechanisms in one codebase. Watch interaction with encrypted:array / encrypted:collection if any column is currently JSON-cast.

The v3.0.5 change is a vendor-constraint edit against Symfony, which has no runtime meaning in a Laravel app once the primitive is extracted — but it does mean upstream's tested matrix no longer exercises older Symfony/PHP combinations, so any Doctrine-adjacent code paths you copy are validated only on the newer stack.

Sequencing

  1. Data classification and threat model — decide which fields, and justify why TDE or disk encryption is insufficient. If you cannot articulate the adversary, stop here.
  2. Spike: two engineer-days against a schema clone to determine decoupling and cipher mode. This is the build-versus-adopt decision gate, and the Symfony-7 signal makes "can this autoload without a Symfony kernel?" the first thing to test.
  3. Decide explicitly between: (a) native encrypted cast, (b) native plus Sodium deterministic wrapper you own, (c) vendor the package's primitive, (d) adopt wholesale. Option (d) is now effectively off the table for a Laravel codebase — you cannot adopt a Symfony bundle wholesale without pulling in Doctrine and the Symfony DI container.
  4. KMS/envelope-design and rotation runbook before any production ciphertext is written. Ciphertext written under an undesigned key scheme is technical debt you cannot migrate without decrypting everything.
  5. Rollout behind a feature flag with shadow writes, then backfill, then verify, then cut over reads, then drop plaintext columns in a later release so rollback remains possible.

Operational Impact

Maintenance

Assume you own it. v3.0.5 shows a maintainer responding to upstream Symfony releases, which is better than the prior read of a dead package — someone is watching the constraint file. What it does not show is any work on the crypto path, any test additions, or any dependent ecosystem. Zero dependents still means no upstream fixes driven by real users for PHP minor-version breaks, framework upgrades, or cipher findings. Budget a fork-and-vendor: pin to a commit (v3.0.5 or later), copy into app/Support/Crypto or a private package registry, strip the Doctrine/DI scaffolding, and add it to the dependency-review list alongside your other security-critical code. If that is unacceptable to the team, the decision reduces to "use Laravel native," which is the honest default.

Support

No community, no issue triage, no SLA. Internal on-call becomes the effective maintainer. Escalation path for a suspected crypto defect is your own security team — plan for that before, not during, an incident. The existence of a v3.0.5 patch does not create a support channel; a constraint bump shipped without release notes beyond an emoji and a changelog link is not a signal of a support process.

Scaling

Cryptographic CPU cost is negligible (AES-NI throughput is orders of magnitude above typical request volume); the scaling cost is in the database layer. Encrypted columns push filtering and sorting into PHP, which means fetching and decrypting N rows to answer what used to be an indexed WHERE. Blind index tables add a write per indexed field per insert and need their own key. Backfill jobs contend with production I/O — throttle and run off-peak. Set a hard cap on how many rows any code path is allowed to decrypt in memory; without one, an "export" or "search" endpoint becomes a memory and latency cliff.

Failure modes

Rank-ordered by severity:

  • Key loss — unrecoverable data. This is the only failure mode that can destroy the business. Mandate escrowed backups, tested restore, and a documented break-glass procedure.
  • Nonce/IV reuse in a stream or CTR-style mode — catastrophic and silent; the ciphertext looks fine while confidentiality collapses.
  • Rotation without versioning — mass decryption failure across every row, presenting as an outage with no obvious cause.
  • Silent query failure — filtering on an encrypted column returns empty rather than erroring, and the bug ships as "no results" rather than a stack trace. Add explicit guards that reject where() on encrypted columns.
  • Ciphertext truncation — column too narrow, data written truncated to a valid-looking but undecryptable blob.
  • Double encryption on re-save during mixed-state windows, producing a value that decrypts to ciphertext.
  • Stale key cache in long-lived queue workers after rotation.
  • Upstream constraint drift — a future bump that widens or replaces the Symfony constraint is invisible to you once forked; pin the commit and track upstream releases manually rather than relying on Composer resolution.

Each of these needs a detection signal: a canary row decrypt check in the health endpoint is cheap and catches most of them.

Ramp-up

API surface is small — a senior PHP engineer grasps the cast in half a day. The real ramp is the runbook: key custody, rotation rehearsal in staging, backfill tooling, and the "what do we do if a key is compromised" play. Allocate roughly two engineer-days for the evaluation spike and two to four engineer-weeks for production hardening plus backfill, and require a security sign-off before the first production ciphertext is written. Add half a day for the extraction work implied by v3.0.5 — confirming nothing in the crypto path drags the Symfony container in with it.

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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle