armincms/eset
ArminCMS Eset is a Laravel package for storing application settings in the database through Eloquent models. It provides a simple key-value interface for reading and writing configuration values, letting you manage settings dynamically without editing config files.
This is a pre-1.0 package (0.4.x), so treat it as moving fast and pin your version in composer.json rather than floating on ^0.4. The 0.4.2 patch is a pure bugfix — safe to take — but the 0.x series as a whole has no stability promise.
Minimal setup path:
composer require the package and run php artisan vendor:publish --provider="...ServiceProvider" to get the config and any migration out of the vendor tree. Publishing early matters because the config file is where key prefixing, length, and hashing behaviour live — you want it in your repo, diffable, before you start building on top of it.api_keys table you own). Decide immediately whether keys are stored on the users table or a separate table with a relation — the package's default assumption drives everything downstream.php artisan tinker before wiring it into a controller. You want to see the plaintext-vs-stored-hash split with your own eyes before you build auth around it.First real use case: issuing a key to a user in a settings page, showing it once, and authenticating a stateless API request with it. Get that vertical slice working end-to-end before adding scopes, expiry, or rotation.
Where to look first, in order: the config file (it is the package's real documentation), the migration, then the service class that generates keys. The README is thin for a 0.x package; the source is the spec.
Store the hash, show the plaintext once. The standard shape for this class of package: generation returns the plaintext key to the caller, while the database column holds a hash or an encrypted value. Never persist the plaintext yourself "for convenience" — you defeat the entire design. Pattern the flow as: generate → return in the HTTP response → flash a copy-once notice in the UI → discard.
Middleware or guard, not both. Pick one integration point. If the package ships a middleware, register it on the API route group. If it ships a guard, register it in config/auth.php under a distinct guard name so you can mix it with session auth on the same app. Doing both leads to two sources of truth for "who is the caller" and confusing failures in policy checks.
Bind the key to an owner, always. Keys that are not attributable to a user or tenant become impossible to revoke selectively. If the package's default schema is a standalone api_keys table, add the user_id (or tenant_id) foreign key in your own migration if it's absent, and make the resolving relationship explicit.
Wrap key generation in a domain action. Don't call the package's generator directly from controllers. Put it behind something like IssueApiKey::handle($user, $name) that owns naming, expiry, audit logging, and any scoping. When the package changes shape between 0.x releases — which it will — you patch one class instead of a dozen controllers.
Rotation and revocation as first-class UI. The 0.4.2 fix specifically concerns generation on edit, which hints that "editing" a key is a supported path in the package. In practice, editing a key should mean renaming or re-scoping it — not reissuing the secret. Treat "regenerate" as revoke-plus-issue, and make sure the old secret stops working the instant the new one is shown.
Test with assertDatabaseMissing on plaintext. Write one test that greps the whole api_keys table for the plaintext you got back from generation and asserts it isn't there. That single test catches the most common integration mistake and survives package upgrades better than mocking internals.
The 0.4.2 fix is worth understanding, not just installing. "Fixed API key generation per edit issue" is a one-liner, and the failure mode it describes — generation misbehaving when triggered from an edit/update path — is exactly the kind of thing that leaves bad data behind. If you had any flow where a key was created as part of saving an existing model (an "update settings and issue a key" form, a profile-save observer), audit those rows. Check for keys with null hashes, empty prefixes, duplicate secrets, or records pointing at the wrong owner. Reissue anything suspect rather than patching rows by hand.
Re-run your own suite, not just composer update. For a patch release with this little detail, the release note tells you nothing about surface area. Your integration tests around issue/revoke/authenticate are the real changelog.
Pinning matters more than usual. With 0.4.x, "^0.4" will silently pull 0.5 when it lands, and pre-1.0 minor bumps routinely rename methods. Use "0.4.2" or "~0.4.2" and bump deliberately with a read of the diff.
Config caching catches people out. If the package reads config at boot — prefix, length, hashing driver — php artisan config:cache in production will freeze whatever was in the file at deploy time. Change the config, forget to re-cache, and you get keys generated with the old prefix. Add config:cache to your deploy script rather than remembering it manually.
Hashing vs encryption is a migration trap. If the stored value is a hash, a lost key cannot be recovered — only reissued. If it's encrypted, key rotation in APP_KEY can invalidate every stored key at once. Confirm which the package does before you promise users "we can look it up for you," and never rotate APP_KEY without a reissue plan.
Extension points to prefer. The safe places to customise are your own wrapper class, a custom ApiKey model if the package allows overriding it via config, and a middleware you write yourself around the package's resolver. Avoid subclassing internal generator classes — those are the most likely to move in 0.5.
Debugging auth failures. When a key is rejected, narrow it in this order: is the header/query parameter name the one the package expects; is the key being trimmed of whitespace; does the record still exist and is it unexpired; does the hash comparison pass in tinker. Log the prefix only — never the full key — when you instrument this, or you'll write secrets into your logs.
Version note for the next reader. This assessment reflects 0.4.2. There is no prior assessment to diff against, so re-verify the config keys and any method signatures cited here against the source at your installed version before relying on them.
How can I help you explore Laravel packages today?