-
Notifications
You must be signed in to change notification settings - Fork 0
FAQ
Quick answers to questions we hear often. For deeper dives, the page links go to the relevant reference.
No — they solve different problems.
| Tool | What it catches |
|---|---|
| PHPStan / Psalm / Larastan | Type errors, unreachable code, undefined methods, model attribute typos |
| DevGuard | Production-readiness, deploy-config issues, env consistency, dependency CVEs, code shape (fat controllers, etc.) |
Use both. PHPStan finds bugs in your code; DevGuard finds bugs in your deployment. They don't overlap meaningfully.
Yes. DevGuard's rules are Laravel-specific (it knows about .env, app/Http/Controllers, composer.lock, etc.). For non-Laravel PHP projects, the env audit and dependency audit could partially apply, but the deploy and architecture rules wouldn't make sense.
If there's appetite, a future "DevGuard Core" could be framework-agnostic — open a GitHub issue if you'd use that.
A guard for developers — it's the gate that catches your obvious mistakes before they cost you. Originally devsanity was the working name, then dev-guard, then settled on the camelCase form.
Ahmed Anbar (begnulinux@gmail.com). Solo project so far. Contributions welcome — see Extending DevGuard.
DevGuard itself is in 0.x — minor versions can introduce changes. The CLI is in active use on real Laravel projects (the maintainer's own projects, plus the smoke test). Tests are green, real-world tested, and the JSON / SARIF schemas are stable within a minor.
We're not at 1.0 because there are still patterns we want to settle (plugin discovery, more auto-fix coverage, more CI integrations). But it's safe to use today — just expect minor-version churn until 1.0.
Per-project (composer require --dev) is the recommended default. Reasons:
- Every contributor and CI runs the same DevGuard version (committed in
composer.lock) - Updates are tracked alongside other dependencies
- No cross-machine "works on my laptop" surprises
Global is fine if you audit many Laravel projects from the same machine and don't want to add a dev dep to each. They're not mutually exclusive.
No. The CLI is a Composer-installed PHP package. You can however use the GitHub Action (which bundles composer + the CLI internally) without adding anything to your project's composer.json.
Currently PHP 8.2 and 8.3. Tested in CI on both. PHP 8.4 should work — let us know if it doesn't.
No — DevGuard is just a PHP CLI. It detects Laravel by reading your project's composer.json and checking for the laravel/framework require. If your project isn't Laravel, most rules become no-ops or warn.
Ping is a sanity-check tool that confirms DevGuard found your project and detected Laravel. It's always green, fast (<10ms), and useful as a "did the install work?" signal. You can skip it by running specific tools:
devguard run deploy,architecture,env,depsCurrently you run all or one named tool. Multi-tool selection (e.g., devguard run deploy,architecture) isn't supported via the CLI yet — but it works for --tools in install-hook. This is a candidate for a future minor release.
Workaround: run them sequentially in shell:
devguard run deploy && devguard run architecture && devguard run envNot via CLI flag. Use Configuration to disable individual rules at the config level, or use @devguard-ignore annotations for one-off skips.
Typical benchmarks on a medium Laravel app (200 files, 50 controllers):
| Run | Time |
|---|---|
devguard run ping |
<50ms |
devguard run deploy |
~100ms |
devguard run architecture |
~500ms (AST scanning) |
devguard run env |
~500ms (AST scanning) |
devguard run deps |
~2s (network call to packagist) |
devguard run all |
~2.5s |
devguard run all --changed-only (3 files) |
<300ms |
These scale roughly linearly with codebase size. Big monorepos (1000+ files) can take ~10s for all; use --changed-only for hooks on big repos.
Not natively — DevGuard ships console / JSON / HTML / SARIF. You can convert JSON to markdown with jq:
devguard run all --json | jq -r '
"# DevGuard Report\n",
.tools[] | "## " + (.name | ascii_upcase),
"\n",
(.results[] | "- " + .status + ": " + .message)
'GitHub Actions example:
- name: Notify Slack
if: failure() # only on red
uses: rtCamp/action-slack-notify@v2
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_MESSAGE: 'DevGuard found issues on ${{ github.event.pull_request.title }}'For richer messages with the actual findings, parse JSON output and POST to a Slack webhook directly. See Other CI Systems.
Not directly. Use --json and pipe to a script that inserts findings into your DB:
devguard run all --json | python3 ingest_audit_findings.pyThis is a common pattern for orgs running DevGuard across many projects and wanting a unified dashboard.
Because not all fixes are mechanical. APP_DEBUG=true → false looks trivial but flipping it on a developer's local machine breaks debugging. Architecture refactors require understanding the domain. The general rule: if the suggestion has any "depending on your environment" qualifier, it's not auto-fixable.
See Auto-fix → When not to use auto-fix.
Cross-file fixes have a deliberate two-step flow:
- First run: append the new key to
.env.example(the public template) - Second run: append the same key to
.env(the local file with real values)
Combining both into one auto-fix would teach users to commit secrets-shaped values into .env.example. The two-step forces a review pause between template and instance. See Auto-fix → Two-step flow.
It runs composer update <package> --with-dependencies, which honors your version constraints. It won't pull in a major version bump unless your composer.json already allows it. So:
-
^1.5.0constraint → fix updates to latest 1.x — usually safe -
^1.5.0 || ^2.0.0constraint → fix may update to latest 2.x — possibly breaking, review the diff
Always review composer.lock changes after fix deps, even if it's just to confirm the version range is what you expect.
Yes — three ways:
-
Baseline file:
devguard baselinesnapshots all current findings; future runs suppress them -
Inline annotation:
// @devguard-ignoreon the offending line or above it - Configure impact to 0: keeps the check running but stops the score deduction
For new code that triggers a check intentionally, use @devguard-ignore. For bulk legacy adoption, use baseline. For "always false positive on this rule across the project," lower the impact to 0 in config.
Add 'fail_on' => 'warning' in config/devguard.php for a tool — turns every warning into a failure. Or set fail-on-warning: 'true' on the GitHub Action.
For per-rule strictness, raise impact values (e.g., 'debug_mode' => ['impact' => 30]) — making a single failure drop the score below the gate threshold.
Set its impact to 0 — keeps it visible in reports without affecting the score. For tools (the whole group), 'enabled' => false removes it entirely.
Yes. The Action's Docker image is public (anyone can pull it), but the runner can be on a private repo. permissions: security-events: write works on private repos exactly the same way (assuming GitHub Advanced Security is enabled, which is automatic for public repos and a paid feature for private orgs).
Yes, assuming the runner has Docker (the Action is Docker-based). Self-hosted ARM runners need to confirm composer:2 image runs there (it should, but verify).
@v1 is the rolling tag — auto-updates with patch releases. Most teams want the latest CLI fixes flowing in automatically (especially security fixes). For regulated environments needing byte-for-byte reproducibility, pin to @v1.1.2.
If you want notifications on Action updates, watch the devguard-action repo — every patch release shows up there.
Yes, with caveats:
- The finding must have a real
fileandline(project-wide findings show up in the PR's checks list, not on the diff) - The line must be in the PR's diff (lines unchanged by the PR don't get annotations)
- Code Scanning must be enabled (free for public repos, paid for private — which is GitHub Advanced Security)
If you're not seeing annotations: check the run's "Code Scanning" check status. If it's green but no annotations, check whether the SARIF actually had findings (look at the artifact).
The CLI itself: no. It runs entirely locally — reads files, parses ASTs, writes reports. No network calls.
Exceptions:
-
composer audit(used by the deps tool) calls packagist.org to fetch advisory data. This is composer's behavior, not ours. Runcomposer auditdirectly to see exactly what it does. - The GitHub Action's SARIF upload step posts findings to GitHub's Code Scanning API. That's part of
github/codeql-action/upload-sarif, not DevGuard.
No telemetry, no usage tracking, no phone-home. Open the source if you want to verify.
Wherever you tell them to:
- Console: stdout
-
--json: stdout (or pipe to file) -
--html: file in your project (defaultdevguard-report.html) -
--sarif: file in your project (defaultdevguard.sarif)
DevGuard never writes outside the project directory unless --output= or --html= / --sarif= specifies an absolute path elsewhere.
When DevGuard hits 1.0:
- Caret semantics will work normally (
^1.0→>=1.0.0 <2.0.0) — no more OR-chains - The JSON / SARIF schemas commit to backward compatibility (no field removals across minors)
- Plugin discovery (likely): a Composer-plugin pattern for registering third-party tools without editing
bin/devguard - Stable release cadence
We're not there yet. Until then, expect occasional minor-version migrations.
No fixed cadence. Recent releases:
| Version | Date | Reason |
|---|---|---|
| v0.8.3 | 2026-04-24 | Bug fix: --locked for composer audit |
| v0.8.2 | 2026-04-24 | Bug fix: declare symfony/process |
| v0.8.1 | 2026-04-24 | Bug fix: SARIF locations |
| v0.8.0 | 2026-04-22 | Feature: --changed-only mode |
| v0.7.2 | 2026-04-21 | Feature: env auto-fix expansion |
When something needs fixing, a release happens. When new features land, a release happens. See Changelog and Versioning for the full list.
- Have a specific issue? → Troubleshooting
- Want to know what changed in version X? → Changelog and Versioning
- Want to contribute? → Extending DevGuard
DevGuard for Laravel · MIT licensed · Maintained by Ahmed Anbar
Source · Action · Packagist · Issues · Wiki source
Getting Started
Reference
Workflows
Advanced
Help
Links