ssbityukov/filament-command-center
Filament plugin for running pre-approved Artisan and shell commands from your panel. Commands come only from an allow-list defined in config, database, or code — never free-form input. Supports per-command gates, queued runs with live output, run history, and CI validation.
Process::run() call, an authorization check, and a history table — then the same again for the next command. That's roughly a sprint of work per team, repeated per product, usually written without an argv model, a CI guard against fromShellCommandline(), or per-command gates. This package replaces that recurring build with a config array plus three gate definitions. The buy case is strong specifically because the naive build is the insecure build, and shipping the insecure version is the default outcome when a PM doesn't fund the secure one.cache:clear / queue:restart / migrate:status for me" requests into a UI action with a gate. That is a support-load decision, not a technical one: if your roadmap has a persistent tail of small operational favours landing on one or two senior engineers, this is a candidate fix.database history driver turns "who ran migrate in production at 14:02, and did they have the right to" into a queryable record. If a SOC 2 / ISO 27001 / customer-security-questionnaire workstream is on the roadmap, that requirement exists whether or not this package does; the cache driver (default, TTL-bounded, erased by cache:clear) does not satisfy it and must be explicitly upgraded.command-center:check fails on unknown tokens and undefined abilities) does not silently drift.Adopt when most of these hold:
composer require, one ->plugin(...) call, and three gate definitions — this is a days-not-weeks evaluation.migrate:status, storage:link, deploy hooks. If you can write the list on one page, the allow-list model fits perfectly.src/-wide CI script asserting no shell-execution primitive exists is the single most valuable thing here, and it's the thing a homegrown tool will not have.command-center:access exists, nobody sees the module. That is a correct and slightly annoying default; plan for it rather than discovering it during a demo.Look elsewhere, or build, when:
commands table — can run anything the PHP process can. That's deploy-level privilege. If your tenancy model can't guarantee nobody writes that table, don't enable the database source.redact hides a value from history, not from ps. Secrets must go through environment variables; if the product decision is "operators paste the API key into a text field," stop.For executives — the one-paragraph version. This is a small, MIT-licensed component that lets trusted administrators run a fixed, pre-approved list of server maintenance commands from the admin panel they already use, instead of asking an engineer to SSH in. It removes a recurring tax on senior engineers, shortens the loop on routine operational work from "find someone with access" to "click the button you're authorised for," and — if we switch on the database history driver — produces an audit record of who ran what, when, and under which permission. Cost to evaluate is a day; cost to adopt is a config entry and three permission definitions.
For engineering — why this one and not the obvious alternative. The security model is the argument. Execution is always an argv array through Process; Process::fromShellCommandline() appears nowhere in src/ and a CI script enforces that. The HTTP payload carries a command key, never a command string, so a value containing ; rm -rf / stays one argument. A token can't become an option or the binary. Authorization is re-checked server-side in the run action, in the dispatcher, and again inside the queued job, because a gate can be revoked between dispatch and execution. command-center:check fails CI on unknown tokens, orphaned variables, undefined abilities, and an unguarded database editor. That is a materially better posture than the panel page we would write in a sprint, and the maintainer has been honest about the limits in a way that usually only comes from having thought hard about them.
For security and compliance — what to ask before sign-off. Three things, in order. First, who can write the allow-list? Config write access and the commands table are both equivalent to deploy access, and the database source is the highest-privilege surface in the package — it needs a named owner and the command-center:manage-commands gate defined. Second, do we need the database history driver? The default cache driver is capped, TTL-bounded, and erased by cache:clear; if audit is in scope, it does not qualify. Third, accept explicitly that this cannot sandbox a running command and cannot hide a secret from ps — those stay platform and process concerns.
For the product team — what it doesn't do, so we don't oversell it. It doesn't give you a web terminal. It doesn't let the database editor define variables yet, so variable-bearing commands need a deploy. Cancelling a synchronous run is unreliable by design; cancel is a queued-run feature. Windows isn't supported or claimed. And it is a young package — 4 stars, no dependents, one maintainer, no browser test suite — so we pin the version, fork if we need to, and don't put it anywhere we can't own for a year.
How can I help you explore Laravel packages today?