hamoi1/eloquent-encryptable
hamoi1/eloquent-encryptable adds transparent attribute encryption to Laravel Eloquent models: define encrypted casts and the package encrypts values on save and decrypts them on read, keeping sensitive data secure while preserving normal model usage.
Architecture fit. eloquent-encryptable is an Eloquent-layer package: it hooks attribute get/set (trait or cast) so encryption is transparent to application code. That is the right seam for a Laravel codebase — no service-layer surgery, no dual-write plumbing at the domain level. The critical architectural consequence is that encryption becomes transparent to the database but not to the query builder: any where, orderBy, pluck, whereIn, or aggregate on an encrypted column either fails or silently compares ciphertext. Whether the package offers blind indexing / deterministic mode for lookup columns is the single biggest architectural question — if it does not, any model with searchable PII needs parallel hash columns maintained by the app.
Integration feasibility. Mechanically low: composer require, publish config, add trait plus an $encryptable array per model. Greenfield models are an afternoon. Brownfield models are not an integration task but a data-migration project — every existing row must be re-encrypted, and column types widened before the trait is enabled (AES-GCM + base64 typically inflates payload ~1.4x plus IV/tag, which overflows VARCHAR(255) fast).
Technical risk. The package is pre-1.0 (v0.1.3), which under semver means the public API is explicitly unstable — a 0.2.0 may break trait signatures or config keys. The notes for this release contain nothing but a compare link, so this version cannot be evaluated on its merits; treat the upgrade as unverified. Above the package sits the real risk: key management. If it derives from APP_KEY, then a key rotation is a total-outage event and key loss is unrecoverable data loss. It is a small, single-maintainer dependency handling crown-jewel data — that is a supply-chain and bus-factor exposure, not a code-quality question.
Key questions.
illuminate/* constraints are pinned or loose.APP_KEY) or independently configured keys? Is multi-key decrypt / key rotation supported?json, array, date, or custom casts.DecryptException?toArray()/toJson() serialization, model $hidden, and queued job payloads — or only DB persistence?Stack fit. Native Laravel, config-driven, no external services. Fits Forge/Vapor/ECS deployments. Note the boundary: it protects the Eloquent path only. DB::table(), raw SQL, and BI/analytics replicas will read ciphertext — plan for that explicitly rather than discovering it in a dashboard.
Migration path. Widen target columns to TEXT/MEDIUMTEXT first, in a separate deploy. Then enable the trait behind a per-model feature flag, with a chunkById backfill command that is idempotent and resumable. Keep a decrypt-or-passthrough read helper for one release cycle so rollback is a flag flip, not a restore. Provision key material in Secrets Manager/KMS separately from APP_KEY, with an offline escrow copy and a documented recovery procedure, before any data is encrypted.
Compatibility. Pin the exact version (0.1.3) and commit the lockfile; do not allow ^0.1 to float. Add a CI contract test asserting encrypt→persist→retrieve→decrypt round-trips across the cast combinations actually used. Re-run that suite before any Laravel or PHP upgrade, since pre-1.0 packages lag framework majors.
Sequencing. (1) Maintainer/security diligence and a feature-gap check against blind indexing; (2) column widening; (3) KMS key provisioning + recovery runbook; (4) trait on one low-risk model in staging; (5) backfill; (6) flip reads, verify, drop plaintext; (7) pilot one production PII model before widening scope.
Maintenance. Effectively unmaintained-by-contract: one maintainer, pre-1.0, and a release published with an empty changelog. Budget a small but real ongoing cost — vendor the package into the repo or maintain a fork you can patch, add Dependabot with manual review, and assume you own the code path. Release hygiene this thin is itself a governance finding to raise.
Support. No commercial support, no SLA. Escalation is internal engineering. Written runbooks are mandatory for: key rotation, decryption failure triage, and restore-from-backup with a non-current key.
Scaling. Decryption cost is per-attribute, per-hydration: AES is cheap but not free, and it compounds on large result sets and high-RPS list endpoints. Mitigate with explicit select() column lists, avoiding encrypted attributes in paginated index queries, and per-request memoization. Ciphertext inflation increases row size and hurts index efficiency on adjacent columns.
Failure modes.
APP_KEY (or package key) rotated without re-encryption → every read throws, full outage on affected models.dd(), and log context dumping decrypted values — encryption at rest undone by observability.Ramp-up. Low for the mechanics: a Laravel developer is productive in hours. The genuine ramp is operational discipline — key lifecycle, backfill/rollback design, and downstream-system communication — realistically one to two sprints including the runbook and a staged pilot, not a same-week ship.
How can I help you explore Laravel packages today?