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

Composer Audit Responsibility Laravel Package

netresearch/composer-audit-responsibility

A Composer plugin that extends composer audit with responsibility metadata, letting teams assign owners to dependencies so vulnerability findings reach the right people and remediation gets tracked. Configuration-driven, lightweight, and easy to drop into existing Composer workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Composer plugin, not a Laravel package — it has no service provider, no config/*.php, no Artisan commands, and nothing at runtime. It hooks Composer's post-install/post-update audit and turns advisories into a hard failure unless the project has explicitly accepted the risk with a documented reason. Treat it as part of your build/CI contract, not your application code.

Minimal steps:

  1. Install per project, never globally.

    composer require --dev netresearch/composer-audit-responsibility:^0.4.1
    

    Composer 2.2+ requires plugin consent, so add it to config.allow-plugins when prompted. The global-install path is exactly what 0.4.1 fixed (a globally installed plugin was overriding each project's risk acceptance), so keep it in require-dev and pin tightly — this is still 0.x.

  2. Run an install and watch it fail. Trigger a known advisory in a scratch branch or point at a package with an open advisory. The point of the first run is to see the blocking output and confirm your CI gate is real.

  3. Accept the risk explicitly. Add the advisory to your project policy with a reason — the reason is printed in the output, which is the whole "responsibility" model: no silent ignores.

  4. Where to look first: the README's config table, then PolicyConfig and Auditor::processAdvisories() in the plugin source. Those two classes define exactly which keys are honoured and how matching works, including the Composer 2.10+ code path.

Implementation Patterns

Keep one source of truth for ignores. Configure the policy.advisories block (with ignore, ignore-id, ignore-severity) and let the plugin handle config.audit.* interop itself. Since 0.4.1, when policy.advisories is set on Composer 2.10+, the plugin injects platform-only ignores into policy.advisories.ignore-id because Composer skips audit.ignore in that case. Duplicating the same CVE into both policy.advisories and config.audit.ignore creates drift and confusing double-reporting.

Ignore by ID with a reason, not by package.

{
  "config": {
    "allow-plugins": {
      "netresearch/composer-audit-responsibility": true
    }
  },
  "extra": {
    "policy": {
      "advisories": {
        "ignore-id": {
          "CVE-2024-XXXXX": "Not reachable: affected code path is unused (see SEC-412)"
        },
        "ignore-severity": ["low"]
      }
    }
  }
}

(Confirm exact placement against the README for your version.) Ignoring by package name suppresses future advisories for that package — precisely the risk you're trying to stop accepting implicitly.

Split local and CI behaviour deliberately. Locals can use policy.advisories.block: false to downgrade to a warning and keep moving; CI should run with blocking fully enabled, so composer install itself is the gate. Don't rely on a separate composer audit step as your only check — the two read config differently on Composer 2.10+.

Pipeline shape for a Laravel app:

  • A dedicated job runs composer install --no-dev --prefer-dist against the committed composer.lock; a non-zero exit is the security gate.
  • Keep a separate composer audit --format=json job for reporting/SBOM output, but don't treat it as the enforcement point.
  • Renovate/Dependabot PRs that pull in a newly-disclosed advisory will fail here. That's the intended behaviour: the PR author either bumps, or adds a documented ignore to composer.json — a reviewable diff with a justification string.
  • Store the ignore reason as ticket/risk-register reference (SEC-412) rather than prose like "false positive". It ends up in logs and, for regulated teams, in audit evidence.

Pair with composer audit correctly. Because the plugin now injects ignores where Composer 2.10 actually reads them, your composer audit output and your post-install gate should agree. If you set policy.advisories, verify by running both on the same lockfile and diffing the advisory lists — a mismatch means a config key is being read from the wrong place.

Rollout pattern for existing codebases: first land the plugin with blocking disabled plus a baseline of ignores, capture the advisory list, then flip blocking on in a follow-up PR. Otherwise the first composer install on main fails for everyone at once.

Gotchas and Tips

  • Pin >=0.4.1. Before this release, a globally installed plugin overrode a project's explicit ignores and broke composer install — the worst kind of failure, because the "fix" people reach for is uninstalling the plugin. Per-project install plus ^0.4.1 avoids the whole class.
  • Disabled policy now warns instead of erroring. policy: false, policy.advisories: false, policy.advisories.block: false and audit.block-insecure: false all downgrade to warnings. Good for rollout, dangerous as a silent failure mode: a typo'd or misplaced key turns your gate into noise that nobody reads. Assert in CI that the policy is actually active (e.g. a smoke job that expects a non-zero exit on a fixture advisory), not merely present in composer.json.
  • Composer 2.10 changed where ignores are read. If policy.advisories is set, Composer skips audit.ignore entirely. Projects migrating from legacy audit.ignore / audit.ignore-severity while also adopting policy.advisories will find some ignores silently stop applying. Migrate keys in one commit and re-run both composer install and composer audit.
  • Older Composer uses a fallback that mirrors legacy rules rather than Composer's own PolicyConfig. If CI and developers are on different Composer versions, matching behaviour can differ. Pin Composer (composer-runtime-api constraint or the CI image) so everyone runs the same code path.
  • Duplicate IDs keep the project's reason. The plugin won't overwrite an entry you already defined — useful, but it means a stale project reason can mask a changed plugin default. Review ignore entries periodically; they're your risk register.
  • Debug with verbosity. composer install -vvv shows which advisories were matched and ignored and why. composer diagnose catches plugin/allow-plugins problems; composer audit --format=json gives you machine-readable parity checks.
  • Network dependency. Advisories come from Packagist's API at install time. Air-gapped or heavily cached CI images can produce errors that look like policy failures — distinguish fetch failures from genuine blocks before widening ignores.
  • Keep ignores narrow and bounded. Prefer ignore-id over ignore, low over medium, and never a wildcard. An ignore without a reason is the thing this plugin exists to prevent — treat a reasonless entry in code review the same as a failing test.
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.
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
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle