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

Laravel Secure Fields Laravel Package

vimatech/laravel-secure-fields

Laravel package that adds transparent encryption for sensitive database fields. Protect PII, tokens, and secrets with automatic encrypt/decrypt through Eloquent casts, no schema changes or query rewrites, plus configurable keys, key rotation, and searchable blind indexes.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

Choosing which data to protect, and admitting the tradeoff in writing. This package is only worth adopting if a roadmap item exists that says "PII at rest, but we still need to look records up." The moment you encrypt a field, you lose LIKE, ORDER BY, range queries, aggregates, joins, and reporting on that column — permanently, by design. Encrypted fields are queryable only by exact match against a companion hash column. That is a product decision, not an implementation detail: it constrains admin search, customer support tooling, fraud rules, and every BI dashboard built on that table. Decide which is acceptable before an engineer picks the package.

Feature scoping: "lookup-required PII" is the sweet spot. Best-fit fields are identifiers you must match exactly — users.phone, accounts.external_ref, national ID, email when used for login lookup. Worst-fit: anything the business filters, sorts, or reports on (amounts, dates, names in a directory), and anything needing prefix or fuzzy search. If a stakeholder asks for "encrypt everything," that request needs to be decomposed into exact-match fields (doable here) and analytical fields (needs a separate controlled store).

Roadmap sequencing that is not optional. Adoption implies four workstreams that must be scheduled, not discovered mid-sprint:

  • Schema migration widening columns to TEXT and adding indexed *_hash columns (with UNIQUE where the business rule requires uniqueness — a unique index on the encrypted column will never fire).
  • A backfill command for hash columns, chunked and throttled, because no SQL expression produces the package's hash.
  • A rehearsed key-rotation runbook with a two-version deploy window and a "keep the old key far longer than feels necessary" retention rule.
  • An export path to an analytics store for anyone who currently queries that column directly.

Build vs buy vs native. Laravel ships encrypted casts that handle transparent encryption with no extra dependency. This package's added value is narrow and specific: dedicated keys separate from APP_KEY, a separate blind-index hash key, and a rotation command with unreadable-row reporting. If you only need "encrypted at rest, never searched," the framework already does it and you should not take the dependency. If you need searchable encryption and rotation, that's the gap this fills — at the cost of a single-maintainer, zero-star, zero-dependent dependency on a security-critical surface.

Risk acceptance as an explicit decision record. A security-critical package with zero stars and zero dependents should be pinned to an exact version, wrapped behind one internal adapter class, and reviewed diff-by-diff. A patch release (v2.0.1) changed only punctuation in exception messages and two lines of rotate output — behaviour, classes, and exit codes untouched — and still broke any health check grepping the text. That is the shape of the tail risk. Product should treat this as a bounded bet with a designed exit, not a settled architectural choice.

Compliance commitments you can now make — and ones you can't. You can credibly claim encryption at rest with dedicated, independently managed keys for named fields. You cannot claim fields are unreadable to application operators (values decrypt transparently into model attributes and therefore flow into toArray(), toJson(), API resources, queue payloads, log context, and exception traces by default). Masking in API resources, $hidden defaults, and ID-only job payloads are product requirements, not engineering preferences — without them, the encryption buys you database-dump protection and very little else.

When to Consider This Package

Adopt when most of these are true:

  • You have a small, named set of PII fields that need encryption at rest and exact-match lookup.
  • You are willing to widen columns, add hash columns, and run backfills and a rotation rehearsal.
  • You are on a standard Laravel version and can test against your actual DB matrix (MySQL strict mode, PostgreSQL TEXT, SQLite in CI).
  • You can dedicate one adapter seam and one owner so the package is not called from fifty places.
  • Someone will own the deployment checklist: two keys in the secret manager, both present in .env.example as empty strings, config:clear after env changes.

Look elsewhere — or use native encrypted casts — when:

  • You need ordering, ranges, prefix/fuzzy search, or analytics on the field. No amount of configuration fixes this; it is inherent.
  • You need encryption without lookup. Laravel's built-in encrypted cast covers it with zero third-party surface.
  • Your compliance posture requires a vendor with a security programme, a disclosure policy, or an SLA. Zero stars, zero dependents, single maintainer.
  • Low-entropy fields under a blind index (phone numbers, national IDs). Equal values produce equal hashes by construction; a leaked hash key enables dictionary attacks. Either accept that in writing, or specify keyed-HMAC over a normalised, salted representation.
  • You cannot absorb the failure modes: mass updates (->update(), DB::table(), seeders, importers, upsert()) silently write plaintext past the casts; firstOrCreate/updateOrCreate on a secure attribute never matches and silently creates duplicates. Every one of these is a data-integrity incident that surfaces months later.
  • You are not prepared to keep a retired key alive indefinitely for restored backups and stale replicas.

A reasonable middle path: pilot on one field where you need both halves of the behaviour — encrypt at rest and exact-match search — and treat it as a bounded experiment with an adapter in place from day one. If the reporting constraints or the maintenance burden prove unacceptable, migrating to native casts is a one-file change.

How to Pitch It (Stakeholders)

To executives — one paragraph. We can encrypt specific sensitive customer fields in the database while keeping the app's code and normal lookups unchanged. The cost is that those fields stop supporting search-by-partial, sorting, and reporting, and we take on a small third-party dependency plus two extra secrets to manage. It protects against database dumps and backup leaks; it does not make data invisible to the application itself, so masking in APIs and discipline about logs and queues are required. Recommended scope: a short list of exact-match identifiers, piloted on one field, with an internal wrapper so we can swap it out.

To engineering — the operating rules. Encryption is a model-layer concern; everything below the model is raw bytes. Declare fields one way only (property or cast, never mixed). Never call firstOrCreate/updateOrCreate on a secure attribute — put that in the PR template. Route all hashing through one SecureSearch adapter so the hash key never appears in a controller. Assert three things in every test touching a secure field: plaintext on the model, ciphertext in the table, correct hash in the hash column — plus one negative test per endpoint that plaintext does not appear in the JSON body. Catch SecureFieldsException by class and assert exitCode(), never message text. Pin the exact version, read every patch diff, and run the package's suite against our Laravel/PHP/DB matrix before committing regulated data.

To security and audit — what we are and are not claiming. Dedicated encryption key and separate blind-index hash key, both in the secret manager, neither derived from APP_KEY; AES-256-GCM; versioned keys with a rehearsed rotation runbook and a non-zero "unreadable values" count treated as an incident signal. Known, accepted limitations: equality leakage on hashed fields, ciphertext visible to raw queries, replicas, and BI tools, and plaintext present in application memory by design. Document those limits explicitly rather than letting the word "encrypted" imply more than it delivers.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums