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 Settings Laravel Package

padosoft/laravel-settings

Laravel Settings gives your application a simple, persistent key-value store for configuration. Define settings in the database, read and update them through a clean API, and rely on caching so values load fast without extra queries. Settings stay editable at runtime, keeping configuration out of co...

View on GitHub
Deep Wiki
Context7

Getting Started

This release is primarily an upgrade task, not a greenfield onboarding, so start with the upgrade path before writing any new code.

  1. Read UPGRADE-7.0.md first. The release notes deliberately defer the full breaking-change list to that file. Everything below assumes you have read it.
  2. Run the new migration. settings.value is widened to TEXT. An pdsenc:v1:<kid>:<payload> envelope will not fit in VARCHAR(255), so skipping this migration will truncate or reject encrypted values.
  3. Configure the keyring. Encryption is now driven by a dedicated keyring independent of APP_KEY. Populate the current key plus any previous keys (see config/settings.php / the keyring config referenced in the upgrade guide). Back this up — it is now the single source of truth for decryptability.
  4. Declare encrypted_keys. Only settings listed there are encrypted. If you have never populated encrypted_keys, you are functionally unaffected by this release.
  5. Audit before you deploy. Run encryption-audit (dry-run by default). It reports whether allowlisted keys are stored as envelopes or plaintext, without printing values or lengths.

First use case: store a third-party API token. Add the key to encrypted_keys, write it through SettingsManager::set() (or via the Eloquent model — both paths now converge on SettingsCipher), and read it back through the normal accessor. You get plaintext in PHP, an envelope in the DB, and the same envelope in the cache.

Where to look first: Encryption\SettingsCipher (the single encryption point), the new encryption-* commands, and Exceptions\DecryptException.

Implementation Patterns

Write through either path — they are finally equivalent. The headline fix is that the Model mutator and SettingsManager::set() previously produced incompatible ciphertext (one layer vs. two), so Eloquent writes broke cache-cold reads. In 7.0 both route through SettingsCipher, so save() on the model and setAndStore() are interchangeable. Prefer the Manager API in application code for consistency, but you no longer need to police how other code writes settings.

Treat plaintext as the application-level contract. Validation rules and casts are now applied to the decrypted value rather than the ciphertext. Rules like string|max:255 on an encrypted setting now behave the way you always expected. Casts likewise operate on plaintext.

Rely on cache warm/cold parity. DB and cache contain the same raw envelope. You can stop special-casing cache clears after writes, and you can stop worrying that a cold cache will surface different behaviour than a warm one.

Rotation is a two-phase, keyring-driven operation:

  1. Add the new key as current; move the old key into previous. Both remain decryptable.
  2. Run encryption-rotate as a dry run to see the scope, then apply it (see UPGRADE-7.0.md for the exact apply flag).
  3. Re-run encryption-audit to confirm no values remain under the old kid.
  4. Remove the previous entry only after the audit is clean.

The command is idempotent, so re-running it is safe and is a reasonable thing to do in a deploy pipeline.

Migrating existing plaintext into encrypted storage follows the same shape: encryption-migrate dry-run → review → apply → encryption-audit. Because the release is fail-closed, any allowlisted key still holding plaintext will throw once 7.0 is live, so run this migration before or as part of the deploy that ships 7.0.

Handle failures narrowly. All encryption exceptions extend Exceptions\DecryptException. If you already catch that type, your existing handlers keep working — you do not need to enumerate the new subclasses. Catching it around settings reads is the right integration point for degraded-mode behaviour (e.g. fall back to a read-only integration, surface a config error page).

Use redaction as a safety net, not a feature. toArray() / toJson() now redact encrypted values, and logging is scrubbed. That means it is now safe to accidentally Log::info($settings) or return a settings model from a debug endpoint. It also means array-based exports will not contain the secret — fetch the attribute directly when you actually need the value.

In tests and CI, run encryption-audit as an assertion step. Its output is designed to be loggable (no values, no lengths), so it can go straight into CI logs. Pair it with a check that the keyring is present in the environment.

Gotchas and Tips

  • The TEXT migration is not optional. This is the most likely cause of a "works locally, explodes in prod" failure, because local SQLite is permissive about column width.
  • APP_KEY rotation no longer affects settings encryption — and that cuts both ways. Previously a leaked APP_KEY compromised encrypted settings; now it does not. But losing the keyring means permanently losing the data. There is no APP_KEY-based recovery path. Store the keyring in your secret manager alongside the database backups.
  • Envelopes are bound to the deployment context. A value encrypted in production will not decrypt in staging even with the same keyring. This is intentional and is a real improvement, but it breaks the common "copy prod DB to staging" workflow. Plan for re-encryption or exclusion of the settings table in your seed/copy scripts.
  • Fail-closed is a deploy-ordering constraint. Any allowlisted key with a plaintext value in storage throws. Run encryption-audit against production before rolling out 7.0, and sequence encryption-migrate accordingly. The old silent fallback to the default value is gone — which means bugs that used to be quiet misconfigurations are now loud exceptions.
  • Keep previous keys until the audit says you can drop them. Removing a previous key mid-rotation orphans every value still encrypted under that kid. The two-phase flow exists precisely so this window is observable.
  • Everything is dry-run by default. This is the right default, but it means a deploy script that calls encryption-rotate and assumes it did something will silently do nothing. Check the upgrade guide for the apply flag and verify via encryption-audit, not via exit code alone.
  • The cache now holds ciphertext. If anything outside this package reads the settings cache directly — another service, a custom repository, a dashboard — it will see pdsenc:v1:... instead of a usable value. Audit cache consumers.
  • encryptString() replaced serialization. The envelope is now a versioned, string-encrypted payload rather than a serialized structure. If you had tooling that inspected or migrated ciphertext by unserialize()-ing it, that tooling is dead and needs rewriting against the envelope format.
  • Removed echo statements from accessors. Rare, but if any test or console command depended on that output appearing, it will now be missing.
  • Debugging tip: encryption-audit intentionally never prints values or lengths. Do not expect it to tell you what is stored — only whether the storage shape is correct. For a specific value, decrypt it in tinker through the normal accessor and accept that it will be redacted in toArray().
  • Extension points: Encryption\SettingsCipher is the single seam for all encryption. If you need custom key resolution or envelope handling, that is the class to decorate or bind — not the Model mutator and not SettingsManager::set(), which is exactly the split that caused the 6.x breakage.
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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource