Documentation Index
Fetch the complete documentation index at: https://docs.provisionr.io/llms.txt
Use this file to discover all available pages before exploring further.
Purpose
This document provides a transparent, unfiltered analysis of the Provisionr Workspace CLI dependency tree. It is intended for CISOs, security researchers, and procurement teams evaluating supply chain risk for enterprise deployment.
We believe transparency builds trust where technology has its own limits. Rather than present a sanitized inventory, this narrative explains why each dependency exists, what architectural constraints we are working within, and what we are doing about it.
This document is a companion to the Software Bill of Materials, which provides the formal CycloneDX 1.6 inventory in both human-readable and machine-readable formats.
Distribution Model
Provisionr Workspace CLI is distributed as a compiled PHP binary via Homebrew. The binary bundles all runtime dependencies at compile time. No packages are fetched at install time or at runtime. The application makes outbound HTTPS connections only to the Provisionr API.
This means the dependency tree is frozen at build time. End users receive a self-contained binary with no ability to modify, inject, or update individual dependencies post-install.
Dependency Overview
| Metric | Count |
|---|
Direct dependencies (declared in composer.json) | 8 |
| Transitive dependencies (resolved by Composer) | 80 |
| Total packages in binary | 88 |
| Packages actively invoked by application code | ~30 |
| Packages present but never invoked | ~58 |
The gap between “present” and “invoked” is the central topic of this narrative.
The Composer Replace Mechanism
This is the single most important architectural constraint to understand.
What Happens
The CLI framework, Laravel Zero, is designed as a lightweight CLI framework. It deliberately requires only the individual illuminate/* component packages it needs:
laravel-zero/framework requires:
illuminate/cache ^12.40.0
illuminate/collections ^12.40.0
illuminate/config ^12.40.0
illuminate/console ^12.40.0
illuminate/container ^12.40.0
illuminate/contracts ^12.40.0
illuminate/events ^12.40.0
illuminate/filesystem ^12.40.0
illuminate/process ^12.40.0
illuminate/support ^12.40.0
illuminate/testing ^12.40.0
However, the full laravel/framework package declares that it replaces all illuminate/* packages in its composer.json:
{
"replace": {
"illuminate/cache": "self.version",
"illuminate/console": "self.version",
"illuminate/http": "self.version",
...36 more packages
}
}
When Composer resolves the dependency tree, it determines that installing the single laravel/framework monolith satisfies all illuminate/* requirements. This is standard Composer behavior and cannot be overridden without forking the framework.
The Consequence
Installing laravel/framework as a monolith pulls in 27 packages that Laravel Zero does not need and our application never calls:
- Email subsystem:
symfony/mailer, symfony/mime, egulias/email-validator, symfony/css-selector, tijsverkoyen/css-to-inline-styles
- HTTP server subsystem:
symfony/routing, symfony/http-foundation, symfony/http-kernel, fruitcake/php-cors
- Markdown subsystem:
league/commonmark, league/config, nette/schema, nette/utils, dflydev/dot-access-data
- Other unused:
doctrine/inflector, league/flysystem, league/flysystem-local, league/uri, dragonmantank/cron-expression, various polyfills
These packages are present in the compiled binary as inert code. They are not autoloaded at startup, not registered as service providers, and not invoked by any application code path.
Our Assessment
Risk level: Low, but material for SBOM purposes.
While these packages cannot execute without being explicitly called, their presence means:
- They appear in automated vulnerability scans (Nessus, Snyk, FOSSA, Dependency-Track). A CVE against
symfony/mailer would flag in your scan even though the code path is unreachable in our application.
- They expand the binary size unnecessarily.
- They introduce license complexity (see: Nette dual-licensing below).
What we are doing about it: We are tracking the upstream Laravel and Composer ecosystems for any movement toward split-package resolution. We document all unused packages explicitly in our SBOM so that security teams can scope their risk assessment accurately.
Dependency Provenance Map
Every production dependency traces back to one of 8 direct composer.json entries. The following map shows the full chain.
laravel-zero/framework (52 transitive packages)
The heaviest direct dependency. It provides the CLI application framework and accounts for the majority of the dependency tree.
Directly required by laravel-zero/framework:
| Package | Purpose | Used? |
|---|
symfony/console | CLI command framework | Yes |
symfony/process | Sub-process execution | Yes |
symfony/event-dispatcher | Event system | Yes |
symfony/error-handler | Error handling | Yes |
symfony/finder | File discovery | Yes |
symfony/var-dumper | Debug output | Yes |
guzzlehttp/guzzle | HTTP client | Yes |
vlucas/phpdotenv | .env file loading | Yes |
ramsey/uuid | UUID generation | Framework internals |
nunomaduro/collision | CLI error display | Yes |
nunomaduro/termwind | Styled CLI output | Yes |
nunomaduro/laravel-console-summary | Help screen | Yes |
nunomaduro/laravel-console-task | Task output | Yes |
nunomaduro/laravel-desktop-notifier | Desktop notifications | No |
laravel-zero/foundation | Framework foundation | Yes |
laravel/prompts | Interactive prompts | Yes |
league/flysystem | Filesystem abstraction | No |
dragonmantank/cron-expression | Cron scheduling | No |
psr/log | Logging interface | Yes |
Pulled in via laravel/framework monolith (all unused):
| Package | Chain | What It Does |
|---|
symfony/mailer | laravel/framework | Send email via SMTP/API transports |
symfony/mime | laravel/framework → symfony/mailer | Construct MIME messages |
symfony/routing | laravel/framework | HTTP route matching |
symfony/http-foundation | laravel/framework | HTTP request/response objects |
symfony/http-kernel | laravel/framework | HTTP middleware pipeline |
symfony/css-selector | laravel/framework → tijsverkoyen | CSS-to-XPath conversion |
tijsverkoyen/css-to-inline-styles | laravel/framework | Inline CSS in HTML email |
fruitcake/php-cors | laravel/framework | CORS header middleware |
egulias/email-validator | laravel/framework | RFC-compliant email validation |
doctrine/lexer | egulias/email-validator | Tokenizer for email parser |
doctrine/inflector | laravel/framework | Word pluralization/singularization |
league/commonmark | laravel/framework | GitHub-Flavored Markdown parser |
league/config | league/commonmark | Schema-validated configuration |
nette/schema | league/config | Configuration schema validation |
nette/utils | nette/schema | Nette utility functions |
dflydev/dot-access-data | league/commonmark | Dot-notation data access |
league/flysystem-local | laravel/framework | Local filesystem adapter |
league/mime-type-detection | league/flysystem | MIME type detection |
league/uri + league/uri-interfaces | laravel/framework | RFC 3986 URI parsing |
laravel/serializable-closure | laravel/framework | Serialize PHP closures |
guzzlehttp/uri-template | laravel/framework | RFC 6570 URI templates |
voku/portable-ascii | laravel/framework | Portable ASCII string helpers |
psr/simple-cache | laravel/framework | Caching interface |
symfony/translation + contracts | nesbot/carbon | i18n translation |
symfony/polyfill-intl-idn | laravel/framework | IDN polyfill |
symfony/polyfill-php83 | laravel/framework | Dead code (requires PHP 8.4) |
symfony/polyfill-php84 | laravel/framework | Dead code (requires PHP 8.4) |
provisionesta/datadumper (19 transitive packages)
Provides CSV, JSON, and YAML data export capabilities with diff changelog and manifest features. This is a first-party Provisionr package.
| Package | Chain | Used? |
|---|
provisionesta/audit | direct | Yes — audit logging |
provisionesta/gitlab-api-client | direct | No — transitive, not invoked by CLI |
provisionesta/google-api-client | direct | No — transitive, not invoked by CLI |
nesbot/carbon | direct | Yes — date/time in 11+ files |
spatie/simple-excel | direct | Yes — CSV export |
openspout/openspout | spatie/simple-excel | No — XLSX/ODS engine, only CSV is used |
symfony/yaml | direct | Yes — YAML export |
carbonphp/carbon-doctrine-types | nesbot/carbon | Carbon internals |
laravel/prompts (0 unique transitive packages)
All of its dependencies (symfony/console and chain) are already pulled by laravel-zero/framework.
illuminate/http, illuminate/log, illuminate/validation (0 unique)
These are declared as direct dependencies to make intent explicit, but they are resolved by the laravel/framework monolith that is already in the tree.
symfony/uid (1 transitive package)
Pulls symfony/polyfill-uuid only.
Supply Chain Risk Assessment
Elevated Attention Items
The items below are not vulnerabilities. They are architectural observations intended to give security reviewers complete context.
Unused Network-Capable Packages
The following packages have the technical capability to make network connections or invoke OS-level processes, but are never called by our application:
| Package | Capability | Why It Is Not a Risk |
|---|
symfony/mailer | SMTP/HTTP email sending | Not autoloaded, no service provider registered, no config present |
provisionesta/gitlab-api-client | GitLab REST API calls | Not autoloaded, no service provider registered, no config present |
provisionesta/google-api-client | Google REST API calls | Not autoloaded, no service provider registered, no config present |
jolicode/jolinotif | OS-level notify-send / osascript | Not invoked, no triggers registered |
guzzlehttp/guzzle | HTTP client | This one IS used — for Provisionr API calls only |
These packages cannot execute without explicit invocation. PHP does not auto-execute library code simply because it exists on disk. The Laravel Zero framework uses conditional service provider registration — only components with both their package installed and their configuration file present are registered at runtime.
Single-Maintainer / Stale Packages
| Package | Last Updated | Concern | Mitigation |
|---|
ralouphie/getallheaders | 2019-03-08 | Polyfill, single maintainer, 7 years without updates | Transitive dep of Guzzle PSR-7; cannot be removed. Monitored for CVEs. |
league/config | 2022-12-11 | Low activity | Only present via unused CommonMark chain |
Dead Polyfills
The application requires PHP 8.4+. The following polyfills backport features from PHP versions the application already requires or exceeds:
symfony/polyfill-php80 — PHP 8.0 features (4 major versions behind)
symfony/polyfill-php83 — PHP 8.3 features (1 minor version behind)
symfony/polyfill-php84 — PHP 8.4 features (current version)
symfony/polyfill-ctype — ctype is standard in PHP 8.4
These add no functionality. They are inert but increase binary size and SBOM surface area. They are included because laravel/framework supports a wider PHP version range than our application.
License Risk
All 88 packages use permissive licenses (MIT, BSD-3-Clause, Apache-2.0).
Two packages (nette/schema, nette/utils) are dual-licensed under BSD-3-Clause and GPL-2.0/GPL-3.0. Provisionr elects the BSD-3-Clause license for both, as permitted by Nette’s published licensing terms. This election is documented in the SBOM.
Automated SBOM scanners (FOSSA, Black Duck, Snyk) may flag the GPL option in metadata. The composer.lock reports all available licenses, not the elected one. Security teams should reference this document and the SBOM for the authoritative license election.
CVE Monitoring
When a CVE is published against any dependency listed in the SBOM — including unused transitive dependencies — Provisionr evaluates the following:
- Is the vulnerable code path reachable? For the ~58 unused packages, the answer is almost always no.
- Does the CVE affect the version we ship? Checked against
composer.lock pinned versions.
- What is the CVSS score and exploitability? Evaluated in context of a compiled CLI binary (no network listener, no user-uploaded content processing).
We publish security advisories when a CVE materially affects the application. For CVEs in unused transitive dependencies, we document the assessment in release notes to preempt scan findings.
Recommendations for Security Reviewers
Interpreting Scan Results
If you are scanning the Provisionr Workspace CLI binary or its SBOM with Nessus, Dependency-Track, Snyk, or similar tools, expect the following:
- ~88 components will appear in the inventory.
- Nette packages may flag as GPL. See License Elections — BSD-3-Clause is elected.
- CVEs against
symfony/mailer, symfony/routing, league/commonmark, fruitcake/php-cors, or other unused packages should be evaluated as not applicable — the code paths are unreachable.
provisionesta/datadumper may flag as dev-main in older builds. Current builds pin to a tagged release.
OWASP SAMM Alignment
This dependency narrative supports the following OWASP Software Assurance Maturity Model (SAMM) practices:
| Practice | Activity | How This Document Supports It |
|---|
| Software Dependencies | Inventory | Complete SBOM with provenance mapping |
| Software Dependencies | Risk assessment | Per-package risk categorization with rationale |
| Security Architecture | Threat assessment | Identification of unused network-capable components |
| Operational Management | Vulnerability tracking | CVE evaluation methodology documented |
NIS2 and EU Cyber Resilience Act
For organizations subject to the NIS2 Directive (EU 2022/2555) or preparing for the EU Cyber Resilience Act:
- This SBOM satisfies the supply chain transparency requirements under NIS2 Article 21(2)(d) regarding supply chain security.
- The CycloneDX 1.6 JSON artifact is compatible with the machine-readable SBOM requirements anticipated under the Cyber Resilience Act’s vulnerability handling obligations.
- The dependency narrative provides the risk assessment context required for due diligence under both frameworks.
AI and Automated Decision-Making
Provisionr Workspace CLI does not incorporate AI models, machine learning inference, automated decision-making, or generative AI capabilities. The application is a deterministic CLI tool that executes policy rules defined by human administrators. No dependencies in this SBOM provide AI/ML functionality.
This distinction is relevant for organizations evaluating software under the EU AI Act (Regulation 2024/1689) — this application falls outside the regulation’s scope as it does not constitute an AI system as defined in Article 3(1).
Questions
For questions about this dependency analysis or to request additional documentation for your security review, contact security@provisionr.io.