<p>I'm developing a Blazor WebAssembly app with PWA enabled, and with files <code>appsettings.json</code>, <code>appsettings.Development.json</code> and <code>appsettings.Production.json</code>. The last one is empty because it would contain secrets to replace when production environment is deployed to a kubernetes cluster.</p>
<p>I'm using k8s to deploy, and a <code>Secret</code> resource to replace the empty <code>appsettings.Production.json</code> file by an encrypted file, into a nginx based container with the published blazor app inside.</p>
<p>Now I'm getting this issue in the browser:
<a href="https://i.stack.imgur.com/Cxpqn.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Cxpqn.png" alt="Failed integrity validation on resource" /></a></p>
<p>When the application was built using docker build in a CI pipeline, the file was an empty json file, and got a SHA computed that does not match then one computed by the build process.</p>
<p><strong>My question is</strong>: How can I replace the <code>appsettings.Production.json</code> during deployment, much later than the build process, and don't have the integrity test failed over that file?</p>
<p>The file <code>blazor.boot.json</code> does not contain any SHA for the <code>appsetting.Production.json</code> file:</p>
<pre class="lang-json prettyprint-override"><code>{
  &quot;cacheBootResources&quot;: true,
  &quot;config&quot;: [
    &quot;appsettings.Development.json&quot;,
    &quot;appsettings.json&quot;,
    &quot;appsettings.Production.json&quot;
  ],
  &quot;debugBuild&quot;: false,
  &quot;entryAssembly&quot;: &quot;IrisTenantWeb&quot;,
  &quot;icuDataMode&quot;: 0,
  &quot;linkerEnabled&quot;: true,
  &quot;resources&quot;: {
    &quot;assembly&quot;: {
      &quot;Azure.Core.dll&quot;: &quot;sha256-rzNx\/GlDpiutVRPzugT82owXvTopmiixMar68xLA6L8=&quot;,
      // Bunch of .dlls,
      &quot;System.Private.CoreLib.dll&quot;: &quot;sha256-S7l+o9J9ivjCunMa+Ms\/JO\/kVaXLW8KTAjq1eRjY4EA=&quot;
    },
    &quot;lazyAssembly&quot;: null,
    &quot;pdb&quot;: null,
    &quot;runtime&quot;: {
      &quot;dotnet.timezones.blat&quot;: &quot;sha256-SQvzbzBfueaAxSKIKE1khBH02NH2MJJaWDBav\/S5MSs=&quot;,
      &quot;dotnet.wasm&quot;: &quot;sha256-YXYNlLeMqRPFVpY2KSDhleLkNk35d9KvzzwwKAoiftc=&quot;,
      &quot;icudt.dat&quot;: &quot;sha256-m7NyeXyxM+CL04jr9ui1Z6pVfMWwhHusuz5qNZWpAwA=&quot;,
      &quot;icudt_CJK.dat&quot;: &quot;sha256-91bygK5voY9lG5wxP0\/uj7uH5xljF9u7iWnSldT1Z\/g=&quot;,
      &quot;icudt_EFIGS.dat&quot;: &quot;sha256-DPfeOLph83b2rdx40cKxIBcfVZ8abTWAFq+RBQMxGw0=&quot;,
      &quot;icudt_no_CJK.dat&quot;: &quot;sha256-oM7Z6aN9jHmCYqDMCBwFgFAYAGgsH1jLC\/Z6DYeVmmk=&quot;,
      &quot;dotnet.5.0.5.js&quot;: &quot;sha256-Dvb7uXD3+JPPqlsw2duS+FFNQDkFaxhIbSQWSnhODkM=&quot;
    },
    &quot;satelliteResources&quot;: null
  }
}
</code></pre>
<p>But the <code>service-worker-assets.js</code> file DOES contains a SHA computed for it:</p>
<pre class="lang-js prettyprint-override"><code>self.assetsManifest = {
  &quot;assets&quot;: [
    {
      &quot;hash&quot;: &quot;sha256-EaNzjsIaBdpWGRyu2Elt6mv3X+48iD9gGaSN8xAm3ao=&quot;,
      &quot;url&quot;: &quot;appsettings.Development.json&quot;
    },
    {
      &quot;hash&quot;: &quot;sha256-RIn54+RUdIs1IeshTgpWlNViz\/PZ\/1EctFaVPI9TTAA=&quot;,
      &quot;url&quot;: &quot;appsettings.json&quot;
    },
    {
      &quot;hash&quot;: &quot;sha256-RIn54+RUdIs1IeshTgpWlNViz\/PZ\/1EctFaVPI9TTAA=&quot;,
      &quot;url&quot;: &quot;appsettings.Production.json&quot;
    },
    {
      &quot;hash&quot;: &quot;sha256-OV+CP+ILUqNY7e7\/MGw1L5+Gi7EKCXEYNJVyBjbn44M=&quot;,
      &quot;url&quot;: &quot;css\/app.css&quot;
    },
   // ...
  ],
  &quot;version&quot;: &quot;j39cUu6V&quot;
};
</code></pre>
<blockquote>
<p>NOTE: You can see that both <code>appsettings.json</code> and <code>appsettings.Production.json</code> have the same hash because they are both the empty json file <code>{}</code>. But in production the second one is having a computed hash of <code>YM2gjmV5...</code> and issuing the error.</p>
</blockquote>
<p>I can't have different build processes for different environments, because that would not ensure using the same build from staging and production. I need to use the same docker image but replacing the file at deployment time.</p>

isierra
<p>I edited the <code>wwwroot/service-worker.published.js</code> file, which first lines are as follow:</p>
<pre class="lang-js prettyprint-override"><code>// Caution! Be sure you understand the caveats before publishing an application with
// offline support. See https://aka.ms/blazor-offline-considerations

self.importScripts('./service-worker-assets.js');
self.addEventListener('install', event =&gt; event.waitUntil(onInstall(event)));
self.addEventListener('activate', event =&gt; event.waitUntil(onActivate(event)));
self.addEventListener('fetch', event =&gt; event.respondWith(onFetch(event)));

const cacheNamePrefix = 'offline-cache-';
const cacheName = `${cacheNamePrefix}${self.assetsManifest.version}`;
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];

async function onInstall(event) {
    console.info('Service worker: Install');

    // Fetch and cache all matching items from the assets manifest
    const assetsRequests = self.assetsManifest.assets
        .filter(asset =&gt; offlineAssetsInclude.some(pattern =&gt; pattern.test(asset.url)))
        .filter(asset =&gt; !offlineAssetsExclude.some(pattern =&gt; pattern.test(asset.url)))
        .map(asset =&gt; new Request(asset.url, { integrity: asset.hash }));
    await caches.open(cacheName).then(cache =&gt; cache.addAll(assetsRequests));
}
...
</code></pre>
<p>I added an array of patterns, similar to <code>offlineAssetsInclude</code> and <code>offlineAssetsExclude</code> to indicate which files I want to skip integrity checks.</p>
<pre class="lang-js prettyprint-override"><code>...
const offlineAssetsInclude = [ /\.dll$/, /\.pdb$/, /\.wasm/, /\.html/, /\.js$/, /\.json$/, /\.css$/, /\.woff$/, /\.png$/, /\.jpe?g$/, /\.gif$/, /\.ico$/, /\.blat$/, /\.dat$/ ];
const offlineAssetsExclude = [ /^service-worker\.js$/ ];
const integrityExclude = [ /^appsettings\.Production\.json$/ ]; // &lt;-- new variable

</code></pre>
<p>Then at <code>onInstall</code>, instead of always returning a <code>Request</code> with <code>integrity</code> set, I skipped it for excluded patterns:</p>
<pre class="lang-js prettyprint-override"><code>...
async function onInstall(event) {
    console.info('Service worker: Install');

    // Fetch and cache all matching items from the assets manifest
    const assetsRequests = self.assetsManifest.assets
        .filter(asset =&gt; offlineAssetsInclude.some(pattern =&gt; pattern.test(asset.url)))
        .filter(asset =&gt; !offlineAssetsExclude.some(pattern =&gt; pattern.test(asset.url)))
        .map(asset =&gt; {
            // Start of new code
            const integrity =
                integrityExclude.some(pattern =&gt; pattern.test(asset.url))
                ? null
                : asset.hash;

            return !!integrity 
              ? new Request(asset.url, { integrity }) 
              : new Request(asset.url);
            // End of new code
        });
    await caches.open(cacheName).then(cache =&gt; cache.addAll(assetsRequests));
}
...
</code></pre>
<p>I'll wait for others to comment and propose other solutions, because the ideal response would set the correct SHA hash to the file, instead of ignoring it.</p>
