61

I have a project where we use font awesome 5 library. I followed the instructions that are written here and added an .npmrc file with my auth token.

Is this a safe behaviour to put this in a repo? I want the devs to have access to it, but if the repo goes public we might be exposing the token.

What is the best practice in situation like this?

Brian Zelip
  • 2,909
  • 4
  • 33
  • 45
mdmb
  • 4,833
  • 7
  • 42
  • 90

4 Answers4

72

https://docs.npmjs.com/using-private-packages-in-a-ci-cd-workflow

Export your secret token into your session, e.g., export NPM_TOKEN="00000000-0000-0000-0000-000000000000"

Inside your ~/.npmrc, add //registry.npmjs.org/:_authToken=${NPM_TOKEN}

konyak
  • 10,818
  • 4
  • 59
  • 65
  • 2
    THIS is the answer I was looking for the last 4 HOURS! I don't know if all other answers I found work good on Win & Mac, but this is actually the only solution that worked on Linux for me! THANK YOU! ( I can only upvote 1 time.. this needs more upvotes!) – chriszichrisz Apr 14 '21 at 12:20
  • 2
    Is there a reason why `:_authToken=` doesn't work and that I had to put it on a separate line as `_auth=`? Was there some kind of syntax change or something? – codenamezero Nov 05 '21 at 14:14
  • With `{}` it returns: `error An unexpected error occurred: "Failed to replace env in config: ${NODE_AUTH_TOKEN}".`, without `{}` it works, as post above says. – Ian Vaughan Mar 01 '22 at 18:53
  • without the {} it will fail in the remote pipelines :( – v3nt Aug 22 '22 at 09:41
  • I keep my pw in `~/.ssh` (as this is a good, rights-deprived as much as possible folder anyway…) And load it into the env var with: `export NPM_TOKEN=$(sudo cat ~/.ssh/npmpass | tr -d '[:space:]')` (I am not going for full automation, just lazyness, so the inner sudo is just perfect for me as a barrier, allowing me to not even grant myself user rights to this file.) – Frank N Feb 07 '23 at 09:33
  • This worked for me with `{}`. `yarn version v1.22.19` – Alex Ulyanov Apr 05 '23 at 18:05
71

UPDATE 2021-05-02

This answer remains questionable - see the comments below. I no longer have access to a private ($paid) npm account anymore, so I can no longer test to answer questions.

Perhaps try @konyak's answer.


It is definitely NOT a safe behavior to put the token in any git checked file, including .npmrc.

Below are the steps your team can take to safely leverage your npm token.

There are two different environments to consider:

  1. each developer's local dev machine
  2. the app's deployment platform

local dev

Following the Global Set Up instructions you linked to in your question, is not the solution.

Create the .npmrc file similar to the "Per project" instructions, but substitute your real token with a variable name, prefixed by $. ie:

@fontawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=$TOKEN

npm will detect an environment variables file named .env. So, in a .gitignored .env file, add your secret key value pair, ie:

TOKEN=ABC123

You can also prefix the variable name with "NPM_CONFIG_", according to the npm-config docs, ie:

NPM_CONFIG_TOKEN=ABC123

Now, when the dev runs npm i, font-awesome dependencies will load from the private repo.

NOTE: Don't follow the current npm-config docs about the environment variables syntax! See this stack overflow answer, ie:

 BAD npm-config ENVIRONMENT VAR SYNTAX 

${TOKEN}
 GOOD npm-config ENVIRONMENT VAR SYNTAX 

$TOKEN

app deployment platform

Do all the steps from the local dev section above, PLUS:

  • create an environment variable on the platform with the same name as in the .npmrc file.

If your app host is Netlify, see their Build Environment Variables docs.

Brian Zelip
  • 2,909
  • 4
  • 33
  • 45
  • 15
    Where is it documented that npm install reads from .env? This solution is not working for me, the environment variables are not being detected. – evianpring Sep 04 '19 at 14:30
  • 3
    in .npmrc the '$' is not needed – Anthony Johnston Nov 18 '19 at 09:53
  • 2
    How do you prevent `npm login` from just putting your auth token right back in there? – Marcel May 30 '20 at 15:58
  • 10
    The answer you linked to on why `$TOKEN` is preferable than `${TOKEN}` has been deleted (and also, never explained *why* `$TOKEN` should be preffered, just stated that it should). Can you please elaborate on this: why is `$TOKEN` preferable to `${TOKEN}`? If one works for you and the other doesn't, which OS are you on? – user56reinstatemonica8 Sep 29 '20 at 09:34
  • 6
    The answer about expansion isn't correct `$TOKEN` and `${TOKEN}` are identical in regards to what they expand to. Quoting the bash manual `The ‘$’ character introduces parameter expansion, command substitution, or arithmetic expansion. The parameter name or symbol to be expanded may be enclosed in braces, which are optional` (lmk if you want me to link to the zsh manual saying the same thing :D) – Benjamin Gruenbaum Feb 07 '21 at 14:53
  • 5
    Saving to a `.env` file did not work for me. Had to export to my session – Borduhh Mar 01 '21 at 22:32
  • 3
    Using a .env file did not work either for me. It somehow seems that the variable replacement does not fetch what's defined in the .env file. Is there some way to tell npm to read the .env file ? Using $TOKEN just fails with authorization errors while using ${TOKEN} fails with error " Failed to replace env in config : ${TOKEN}". (Note : placing the token directly in the .npmrc file works just fine, so the token itself is valid) – Wasabi Apr 01 '21 at 09:33
  • 1
    do we have any work around for this @Brian Zelip ? I also see similar error failed to replace env in config? – kaleshanagineni Apr 29 '21 at 14:40
  • when using expo eas build the "bad syntax" worked while the "good syntax" failed – Amr Oct 12 '21 at 11:41
  • `$TOKEN` never worked for me, had to use the curly brackets `${TOKEN}`... – codenamezero Nov 05 '21 at 14:15
  • 2
    Locally I can use `TOKEN` or `$TOKEN`, both work, but `${TOKEN}` fails! But on GitHub CI and Heroku it has to be `${TOKEN}`!!! Otherwise I get `Request failed \"401 Unauthorized\"` – Ian Vaughan Mar 01 '22 at 18:59
  • 1
    It was the only working solution for me, thank you very much. MacOS. – OZ_ May 25 '22 at 12:17
0

I put the relevant config line, with the token in plaintext, in a .npmrc file in my home directory. You can then use filesystem / OS permissions to protect it, avoid accidentally checking it in to source control, and NPM will read it automatically with no further action on your part.

In the project directory, we have .npmrc with a scoped registry declaration only (@fontawesome:registry=https://npm.fontawesome.com/), and a separate ci.npmrc which has that plus the variable-substitution authToken assignment:

@fontawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=$FONTAWESOME_NPM_TOKEN

The CI build job just has to replace .npmrc with ci.npmrc before doing anything with npm, and set a secret environment variable with an auth token assigned to the appropriate service account.

Coderer
  • 25,844
  • 28
  • 99
  • 154
0

Just an additional, regarding on Brian Zelip updated answer, I try to use custom variable name but it doesn't work, I guess there are variable enumeration behind this, because I use NPM_TOKEN and it works fine as well

Marvin
  • 647
  • 7
  • 15