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

Lumos Laravel Package

esplora/lumos

Esplora Lumos is a Laravel package that adds a fast, keyboard-driven command palette, letting users quickly search and navigate your app’s pages, models, and custom actions from one lightweight, customizable interface.

View on GitHub
Deep Wiki
Context7

Getting Started

esplora/lumos wraps GPG decryption for Laravel apps — the typical use case is receiving encrypted files from a third party (bank, payroll provider, EDI/clearing partner, insurer) and getting plaintext into your import pipeline without shelling out to gpg by hand.

Minimal setup

  1. composer require esplora/lumos — pin ^1.1 now that the package has moved past 0.2.0 (see the versioning note in Gotchas).
  2. Publish and review the config: php artisan vendor:publish --tag=lumos-config (check the README for the exact tag) and put key paths / passphrases in .env, never in the config file.
  3. Read the README's facade/service section first — that is where the decrypt entry points live. Skim the src/ for the exception classes too; you will be catching them.

First use case

Decrypt an inbound .gpg / .asc file at the point of ingestion, before the file is parsed:

// Illustrative — confirm exact class/method names against the README.
$plaintext = Lumos::decrypt($path, /* passphrase for symmetric */ $passphrase);

Storage::disk('local')->put("incoming/{$name}.txt", $plaintext);
ImportOrdersJob::dispatch("incoming/{$name}.txt");

If you are coming from 0.2.x, read the 1.0.0 upgrade notes before touching production — the API shape changed across that jump.

Implementation Patterns

Encapsulate decryption in a single service. Do not scatter Lumos:: calls across controllers. A thin DecryptionService that resolves the package, picks the right key/passphrase from config, and returns a DTO (plaintext, source, encryptedWith) keeps the package swappable and makes testing trivial — bind a fake in the container.

Symmetric (1.1.0) vs public-key. The new symmetric path is passphrase-only: the sender encrypted with a shared secret rather than your public key. This is exactly the pattern banks and clearing houses use for recurring bulk files. Model both paths explicitly rather than guessing:

$strategy = $partner->uses_symmetric ? 'symmetric' : 'keypair';

Storing uses_symmetric on the partner/source record (or a config map keyed by sender ID) is far more robust than trying one mode, catching, and retrying.

Queue the work. GPG is CPU- and IO-bound and, for large files, slow. Decrypt inside a job with $timeout and $tries set deliberately, write plaintext to a short-lived disk or storage/app/private/tmp, and delete after import. Never decrypt synchronously in a request that also does the import.

Webhook / API ingestion. Decrypt first, then validate. A decrypt failure is a 4xx/5xx about the payload, not about your business logic — keep those error branches separate so you can alert the sender rather than your own team.

Scheduled mailbox/file drop. For SFTP or mail-collected files, a scheduled command that scans a drop directory, decrypts, moves the ciphertext to an archive prefix, and dispatches an import job is the low-effort durable pattern. Archive the ciphertext — it is your audit trail and the only way to re-run an import later.

Key rotation. Keep key and passphrase resolution behind a config lookup keyed by an identifier (partner code, key ID) so rotating a partner's passphrase is a config/env change, not a code change.

Gotchas and Tips

The 0.2.0 → 1.1.0 jump matters. The release notes only announce symmetric decryption, but the version range spans a 1.0.0 that is not documented here. Treat 1.0.0 as the likely API-stabilisation release: read the changelog diff on GitHub before upgrading in place, and don't assume a 0.2.x code path still exists.

Passphrase handling. Symmetric decryption means a shared secret now lives in your environment. Put it in .env / a secrets manager, keep it out of config/lumos.php committed to git, and be aware that php artisan config:cache bakes config values into bootstrap/cache — a rotated passphrase needs a config cache rebuild, not just an env change. Queue workers must be restarted to pick up new values.

Don't leak plaintext or secrets into logs. Exception messages from GPG can include command lines and file paths, and Laravel's default exception handler logs them. Catch package exceptions at the boundary, log a redacted identifier (partner code, filename hash), and rethrow a domain exception. Scrub the passphrase from any Process output you surface.

Detect the mode before you decrypt. A symmetric ciphertext handed to a keypair routine (or vice versa) produces a confusing GPG error, not a clean one. Sniff the packet header (PGP symmetric vs public-key encrypted packets) or trust your partner metadata — do not implement fallback-by-exception.

Filesystem and homedir permissions. GPG is picky about the permissions of its home directory and keyring. If the package shells out, the www-data/queue user must own the GNUPGHOME, and the directory must not be group/world-readable. Failures here look like "no secret key" rather than a permissions problem.

Memory on large files. String-returning decrypt methods load the whole plaintext into PHP memory. For multi-hundred-MB drops, decrypt to a temp file and stream, or run the import from the file handle. Check whether the package exposes a file-to-file variant before writing your own.

Testing. Keep a small fixture set: one symmetric ciphertext with a known test passphrase, one public-key ciphertext, and one corrupt file. Assert on your exception mapping for the corrupt case — that is the branch that will page you at 3am.

Extension point. If the package's decryptor is bound in the container, decorate it rather than forking: wrap with timing/metrics, a "decrypt and archive" layer, or per-partner passphrase resolution. That keeps you upgrade-safe for 1.2.0.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
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