drupal/core-vendor-hardening
Composer plugin for Drupal that hardens the vendor directory by stripping unnecessary files such as tests, documentation, and version-control metadata from dependencies. It reduces deployment size and attack surface while keeping required code intact.
Architecture fit
drupal/core-vendor-hardening is a Composer plugin (type: composer-plugin) that subscribes to install/update events, strips files matching configurable patterns from vendor/, and writes .htaccess deny rules into vendor directories. It solves exactly one problem: making vendor/ safe to expose when it lives inside a web-served docroot. Laravel's canonical layout puts composer.json and vendor/ above public/, with a single front controller — so the threat model this package addresses should not exist in our stack. Architectural fit is therefore low: it is a compensating control for a misconfiguration we should not tolerate, not a component that adds capability.
Secondary fit problem: the delivered control is Apache .htaccess. Most of our deployments terminate at nginx, Envoy, or a cloud LB, where AllowOverride semantics don't apply and the generated rules are inert. The file-deletion half of the plugin is server-agnostic, but deletion-based hardening is the weaker half.
Integration feasibility
Technically trivial and stack-agnostic — no Drupal runtime dependency, just Composer 2. Install is one dev dependency plus an allow-plugins entry in composer.json (Composer 2.2+ blocks plugins by default). Real work is not installation but the surrounding governance: allow-plugins policy, build-time-only execution, and reconciling mutated vendor/ contents with lockfile/SBOM expectations.
Technical risk
vendor/ after Composer has verified dist archives; vendor/ no longer matches upstream packages. That breaks file-level provenance, SBOM accuracy (CycloneDX/Composer-generated manifests), and any artifact-attestation or diff-based vendor auditing..git) can remove files a package loads at runtime; failures surface only when a rarely executed code path is hit.vendor/, we are distributing GPL source and need a documented policy. Legal review, not a blocker.Key questions
vendor/ actually reachable in any environment today? Probe /vendor/autoload.php and /vendor/composer/installed.json on every host before doing anything else.AllowOverride even enabled?allow-plugins, and is there a review gate for Composer plugins generally?Stack fit Composer 2-native, PHP 7.3+/8.x, no Laravel service provider, no runtime coupling. Fits the build stage of CI → image → deploy; it must never run on production hosts (no Composer in prod). It sits alongside other vendor post-processors, which is where friction appears.
Migration path Preferred path is not this package:
root directive so vendor/ is outside the web root./vendor, /storage, /bootstrap/cache, dotfiles — defense in depth that works on nginx.vendor/ resolves under public/ or if a probe URL returns 200.If a legacy host cannot be re-rooted, adopt the plugin as a documented compensating control: composer require --dev drupal/core-vendor-hardening, register in allow-plugins, configure extra.vendor-hardening with an explicit, reviewed exclusion list and .htaccess output, pin the version, and record the rationale for auditors.
Compatibility
vendor/: cweagans/composer-patches (a patch may target a file this plugin deletes), composer/installers, and SBOM generators.composer install and composer install --no-dev changes what gets deleted; both paths must be validated..htaccess half; nginx deployments get file-stripping only.Sequencing Verify exposure first (hours) → fix server root (days, highest leverage) → add CI guardrail → only then consider the plugin if an unfixable host remains, validated in staging before a canary.
Maintenance Small surface area, low churn, but maintained by a different ecosystem on a different cadence. We would own integration risk for a package whose maintainers optimize for Drupal. Bus factor is effectively one vendor; the code is small enough to fork if abandoned, which is the main mitigation.
Support Community issues only, no commercial backing, no internal Drupal familiarity assumed. Escalation path is "read the source, fork it." Document that in the ADR so on-call isn't surprised.
Scaling
No runtime cost — build-time only. Adds seconds to composer install and touches thousands of files, which is visible on cold CI caches and can invalidate container layers, increasing image churn and registry storage. No effect on request-path scaling.
Failure modes
.htaccess ignored (nginx, AllowOverride None) → the exposure remains and the team believes it's closed. This is the worst outcome.allow-plugins misconfiguration → installs fail in CI with opaque errors.vendor/ → audit findings.Ramp-up Hours for a Composer-fluent engineer to install and configure; the real cost is conceptual — the team must internalize that this is a mitigation for an architectural defect, not a security feature. Budget a short design review and an ADR entry, and a brief security-education note so nobody adds it as a checkbox to future projects.
TPM verdict: Low strategic leverage (score 0.115, 17 stars is consistent with a narrow, single-ecosystem tool). Sponsor the docroot fix and the CI guardrail instead; keep this package in reserve only as a time-boxed compensating control for hosts we cannot re-architect.
How can I help you explore Laravel packages today?