maize-tech/laravel-encryptable
Laravel Encryptable adds transparent encryption for Eloquent model attributes, keeping sensitive data secure at rest while preserving a familiar query workflow. A simple trait and cast setup lets you encrypt, decrypt, and search encrypted values without restructuring your models or database.
Architecture fit. maize-tech/laravel-encryptable is a narrow, single-responsibility package: it provides an Eloquent trait/cast that transparently encrypts and decrypts model attributes at the ORM boundary, keyed off Laravel's APP_KEY/encrypter. It fits any Laravel application with PII, PCI-adjacent, or regulated data in the database and no existing column-level encryption strategy. It does not attempt key management, rotation orchestration, or searchable encryption, so it slots in as a persistence concern rather than an architecture driver. Teams already using Laravel's built-in encrypted cast should note this package's value-add is mainly queryability ergonomics (whereEncrypted-style lookups) and per-attribute trait configuration, not cryptography.
Integration feasibility. Very high. Installation is Composer-only with no service provider ceremony beyond optional config publishing, and the change surface is limited to model declarations plus a migration for column sizing (ciphertext is materially longer than plaintext). Release 4.1.0 is a compatibility-only release — Laravel 13 and PHP 8.5 support plus a Dependabot bump to actions/fetch-metadata — with no new API surface, no deprecations, and no migration steps. That means an integration assessment from a prior baseline remains valid; this release reduces rather than introduces risk by keeping the package on the current framework support window.
Technical risk. The dominant risk is not the package code but the data lifecycle: encrypted columns are effectively unrecoverable if APP_KEY is lost or rotated without a re-encryption plan, and ciphertext defeats LIKE, range, and sort operations on those columns. Secondary risks: (a) column type/length assumptions (a VARCHAR(255) will silently truncate), (b) deterministic-looking behavior expectations from developers who assume encrypted fields are searchable, and (c) supply-chain exposure via a small-maintainer package. The Dependabot entry is CI hygiene only and carries no runtime implication. Laravel 13 support arriving in a minor release is a positive signal on maintenance responsiveness, but teams on Laravel 12 should confirm the package still resolves on their pinned constraints before adopting the new tag.
Key questions. Does the team have a documented key-rotation and key-recovery procedure, and does it survive this package's key derivation? Which existing columns would need backfill, and is a dual-read window required during migration? Are any encrypted attributes used in WHERE, ORDER BY, or reporting queries today? Is there an established policy on small-vendor dependencies, and does this package pass it? What is the fallback if the maintainer goes dormant mid-cycle?
Stack fit. Requires a Laravel application on a supported PHP version; 4.1.0 extends the matrix to Laravel 13 and PHP 8.5. It is framework-native and framework-version-coupled, so it is a natural fit for a standard Laravel service but a poor fit for shared codebases spanning multiple frameworks or for legacy apps pinned below the supported Laravel floor. No queue, cache, or external service dependencies are introduced.
Migration path. For greenfield models, adoption is a single trait import plus correct column definitions — low effort. For existing plaintext columns, treat it as a data migration, not a code change: add ciphertext-capable columns (typically TEXT or VARCHAR(512+)), backfill via chunked queued jobs, dual-read during the transition, then drop plaintext. Encrypted columns cannot be backfilled with a single UPDATE statement, so backfill throughput must be planned. Release 4.1.0 itself requires no migration; upgrading from 4.0.0 is a composer update with a regression pass.
Compatibility. Additive minor release — no breaking changes, no removed methods, no deprecations. Safe to adopt within existing constraints. Verify the application's Laravel and PHP pins actually resolve to 4.1.0, and confirm the CI matrix covers whichever Laravel version is in production rather than only the newest supported one. Pin to a caret constraint (^4.1) rather than floating to major to avoid unplanned breaks.
Sequencing. (1) Confirm framework/PHP pin compatibility and adopt 4.1.0 behind the existing constraint. (2) Publish and review config; establish key management and rotation runbook before any data is encrypted. (3) Pilot on one low-traffic, low-query-complexity model. (4) Validate column sizing and backfill jobs in staging with production-like volume. (5) Roll out model by model, with dual-read windows and rollback criteria defined per model. (6) Only after operational confidence, address any encrypted columns currently used in search or reporting.
Maintenance. Low ongoing code maintenance — the package is small and its API surface is stable across the 4.x line. The real maintenance burden is cryptographic lifecycle: key custody, rotation, and audit evidence, which sit with the team, not the vendor. The 4.1.0 release demonstrates active maintenance and current-framework tracking, which is the main thing to monitor; a gap in support for the next Laravel major would be the signal to reassess.
Support. Upstream support is community/small-vendor with a single primary contributor. There is no commercial SLA. Mitigation: pin versions, vendor the dependency if policy requires, and ensure at least one engineer can read the trait implementation — it is short enough that in-house ownership is realistic.
Scaling. Encryption/decryption is per-attribute, per-model-instantiation CPU work on the application tier. At high read volume on wide models with many encrypted attributes it becomes a measurable cost and is not cacheable without decrypting. It does not parallelize or offload, so capacity planning should account for the added CPU on hot paths, and encrypted columns should be excluded from SELECT * patterns and reporting extracts.
Failure modes. Lost or rotated-without-reencrypt APP_KEY → unrecoverable data and hard application failure on read; this is the catastrophic case and deserves a tested recovery drill. Column too short → truncation or write errors. Encrypted attribute used in a query predicate → wrong or empty results rather than an error, which is a silent correctness bug and the most likely real-world incident. Backfill job interruption → partially encrypted column requiring idempotent re-runs. Package abandonment → frozen framework compatibility, resolved by forking or replacing the cast.
Ramp-up. Roughly half a day for a Laravel-fluent engineer to adopt on a new model, including column sizing and a read/write test. Existing-column migration is a multi-day effort dominated by backfill tooling, dual-read logic, and verification, not by the package. Team-wide education should focus less on the API and more on the invariants: never log decrypted values, never assume encrypted fields are queryable, never commit a rotation without a re-encryption plan.
How can I help you explore Laravel packages today?