title: Getting EACCESS when running NPM 8 as root
body: <p><strong>tldr; script using fs.readFileSync throws EACCESS when called using <code>npm</code>, but not using <code>node</code></strong></p>
  <p>On an ancient (2016) Docker image, I need to run a <code>postinstall</code> NPM script involving Bower (<code>bower install --allow-root</code>), but whenever I do, I get <code>EACCES: permission denied, open '/root/.config/configstore/bower-github.json'</code>. I found out that doing <code>npx bower</code> results in the same. Running <code>npx bower</code> <em>outside</em> of Docker works fine.</p>
  <p>Usually, I would easily have dealt with these issues, as they normally arise whenever someone has been executing a command using <code>sudo</code> when they should not have. The fix for those issues is usually to either change the owner back to the current user or just run the bower command with sudo and <code>--allow-root</code> (<a href="https://github.com/bower/bower/issues/2262" rel="nofollow noreferrer">example 1</a>, <a href="https://stackoverflow.com/questions/37032061/bower-install-eaccess-error">example 2</a>).</p>
  <p><em>This, however, is not one of these issues.</em> <strong>I am already root!</strong></p>
  <p>The full error is like any of the similar issues:</p>
  <pre><code>root@eaa32456c249:/var/www/myproj# npx bower --allow-root
  /var/www/myproj/node_modules/bower/lib/node_modules/configstore/index.js:54
                  throw err;
                  ^
  
  Error: EACCES: permission denied, open '/root/.config/configstore/bower-github.json'
  You don't have access to this file.
  
      at Object.openSync (node:fs:585:3)
      at Object.readFileSync (node:fs:453:35)
      at Configstore.get (/var/www/myproj/node_modules/bower/lib/node_modules/configstore/index.js:35:38)
      at new Configstore (/var/www/myproj/node_modules/bower/lib/node_modules/configstore/index.js:28:48)
      at readCachedConfig (/var/www/myproj/node_modules/bower/lib/config.js:19:23)
      at defaultConfig (/var/www/myproj/node_modules/bower/lib/config.js:11:12)
      at Object.&lt;anonymous&gt; (/var/www/myproj/node_modules/bower/lib/index.js:16:32)
      at Module._compile (node:internal/modules/cjs/loader:1101:14)
      at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
      at Module.load (node:internal/modules/cjs/loader:981:32) {
    errno: -13,
    syscall: 'open',
    code: 'EACCES',
    path: '/root/.config/configstore/bower-github.json'
  </code></pre>
  <p>I cannot elevate my rights any further and adding <code>--allow-root</code> does not do anything. I even inspected the module in question, seeing that the call that always failed was simply this:</p>
  <pre><code>readFileSync(this.path, 'utf8');
  </code></pre>
  <p>where <code>this.path</code> was of course <code>'/root/.config/configstore/bower-github.json'</code>.</p>
  <p>I then wrote this small test module that does the same, and it ran without issues:</p>
  <pre><code>root@eaa32456c249:/var/www/myproj# cat test.js
  const execSync = require('child_process').execSync;
  const fs = require('fs');
  const path = '/root/.config/configstore/bower-github.json';
  
  console.log('exec whoami: ', execSync('whoami').toString());
  try {
      const result = execSync('ls -l ' + path, { encoding: 'utf8' });
      console.log('exec ls -l: ', result);
  } catch (err) {}
  
  try {
      const parsed = JSON.parse(fs.readFileSync(path, 'utf8', { encoding: 'utf8' }));
      console.log('parsed: ', parsed);
  } catch (err) {
      console.error(err.message);
  }
  root@eaa32456c249:/var/www/myproj# node test.js
  exec whoami:  root
  
  exec ls -l:  -rw-r--r-- 1 root root 3 Dec  8 22:55 /root/.config/configstore/bower-github.json
  
  parsed:  {}
  </code></pre>
  <p>A mystery!</p>