<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Dependencies on Brian Faust</title><link>https://vacua.dev/tags/dependencies/</link><description>Recent content in Dependencies on Brian Faust</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Mon, 01 Jan 0001 00:00:00 +0000</lastBuildDate><atom:link href="https://vacua.dev/tags/dependencies/rss.xml" rel="self" type="application/rss+xml"/><item><title>A Lockfile Gives Repeatability, Not Provenance</title><link>https://vacua.dev/a-lockfile-gives-repeatability-not-provenance/</link><pubDate>Mon, 01 Dec 2025 00:00:00 +0000</pubDate><guid>https://vacua.dev/a-lockfile-gives-repeatability-not-provenance/</guid><description>&lt;p&gt;&lt;code&gt;composer install&lt;/code&gt; exits successfully. It selects the version in the committed
lockfile, downloads an archive whose checksum matches, generates the autoloader,
and produces the same output on a second clean install.&lt;/p&gt;
&lt;p&gt;The output is &lt;code&gt;EXFILTRATED&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nothing about that result means Composer ignored the lock. The lockfile was
updated to select the malicious package and its correct checksum. Composer then
repeated that decision exactly.&lt;/p&gt;
&lt;p&gt;This is the useful boundary of a dependency lock. It records a resolution. It
can make later installations select the same versions, references, metadata,
and declared distribution bytes. It cannot prove who deserved to publish those
bytes, why the update was approved, what package code will do, whether new
advisories exist, or which artifact a consumer eventually executes.&lt;/p&gt;</description></item><item><title>Supply-Chain Security Begins with Who Can Change the Artifact</title><link>https://vacua.dev/supply-chain-security-begins-with-who-can-change-the-artifact/</link><pubDate>Sat, 01 Nov 2025 00:00:00 +0000</pubDate><guid>https://vacua.dev/supply-chain-security-begins-with-who-can-change-the-artifact/</guid><description>&lt;p&gt;&lt;code&gt;quote-tool.bin&lt;/code&gt; has a valid signature. Its provenance names the expected
source revision, dependency lock, workflow digest, and builder. The signature
verifies against the consumer&amp;rsquo;s trusted fixture key.&lt;/p&gt;
&lt;p&gt;The program is still malicious.&lt;/p&gt;
&lt;p&gt;In the &lt;a href="https://vacua.dev/reproductions/sec-01/"&gt;SEC-01 fixture&lt;/a&gt;
, the authorized builder changes the
artifact after the tests pass and signs the resulting digest. Signature
verification succeeds because the statement is authentic. Consumer policy
rejects the artifact because its digest does not match the independently
reproduced output.&lt;/p&gt;</description></item><item><title>Dependency Inversion Lets Policy Own the Boundary</title><link>https://vacua.dev/dependency-inversion-principle/</link><pubDate>Tue, 01 Jun 2021 00:00:00 +0000</pubDate><guid>https://vacua.dev/dependency-inversion-principle/</guid><description>&lt;p&gt;This class uses constructor injection and still points in the wrong direction:&lt;/p&gt;
&lt;figure class="code-figure"&gt;
 &lt;div class="code-block" data-copy-code&gt;
 &lt;button class="copy-code" type="button" aria-label="Copy code"&gt;copy&lt;/button&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="nx"&gt;readonly&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QuoteShipment&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="fm"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;GuzzleHttp\Client&lt;/span&gt; &lt;span class="nv"&gt;$http&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Shipment&lt;/span&gt; &lt;span class="nv"&gt;$shipment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Money&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;$response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/carrier/rates&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;json&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;CarrierPayload&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;fromShipment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$shipment&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Money&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;EUR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;json_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$response&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;price_cents&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
 &lt;/div&gt;
&lt;/figure&gt;
&lt;p&gt;The dependency is visible and testable, but the application use case knows an
HTTP client, carrier endpoint, payload, response shape, and currency
assumption. Replacing &lt;code&gt;new Client()&lt;/code&gt; with an injected client improved assembly;
it did not protect policy from the detail.&lt;/p&gt;</description></item></channel></rss>