berry icon indicating copy to clipboard operation
berry copied to clipboard

[Feature] Provide a way to pass in registry credentials to `yarn npm login`

Open vecerek opened this issue 5 years ago • 15 comments

  • [x] I'd be willing to implement this feature
  • [ ] This feature can already be implemented through a plugin

Describe the user story

I'm trying to configure Berry with authentication to JFrog, so that I can run yarn install in a GitHub Action workflow. Currently, to do that, I'm executing the following bash script:

#!/usr/bin/env bash

cat << EOF > ~/.yarnrc.yml
npmScopes:
  myScope:
    npmPublishRegistry: "https://myrepo.jfrog.io/myrepo/api/npm/npm"
    npmRegistryServer: "https://myrepo.jfrog.io/myrepo/api/npm/npm"
EOF

{ echo $ARTIFACTORY_USERNAME; sleep 2; echo $ARTIFACTORY_API_KEY; } | yarn npm login --scope myScope

However, this script is not very reliable. From time to time, the login fails with an authentication error. Using sleep is very brittle, it seems.

Describe the solution you'd like

Providing a way of passing in the credentials would make the use of yarn in CI environments much easier. Something along the lines of:

yarn npm login \
  --scope myScope \
  --username $ARTIFACTORY_USERNAME \
  --password $ARTIFACTORY_API_KEY

Describe the drawbacks of your solution

I cannot see any drawbacks to the proposed interface.

Describe alternatives you've considered

Alternatives could be:

  • reading credentials from the environment,
  • reading credentials from ~/.yarnrc.yml.

Additional context

Add any other context or screenshots about the feature request here.

vecerek avatar Oct 23 '20 11:10 vecerek

Isn't https://yarnpkg.com/configuration/yarnrc#npmScopes.npmAuthIdent or https://yarnpkg.com/configuration/yarnrc#npmScopes.npmAuthToken good enough?

merceyz avatar Oct 23 '20 11:10 merceyz

reading credentials from the environment,

As documented at the top here https://yarnpkg.com/configuration/yarnrc all (simple) configs can be env variables

merceyz avatar Oct 23 '20 12:10 merceyz

Adding these to the setup script:

npmAuthIdent: "$ARTIFACTORY_USERNAME:$ARTIFACTORY_API_KEY"
# or
npmAuthToken: "$ARTIFACTORY_API_KEY"

produces:

➤ YN0041: │ @myScope/my-package@npm:1.0.8::__archiveUrl=https%3A%2F%2Fmyrepo.jfrog.io%2Fmyrepo%2Fapi%2Fnpm%2Fnpm%2F%40myScope%2Fmy-package%2F-%2F%40myScope%2Fmy-package-1.0.8.tgz: Invalid authentication (as an unknown user)

vecerek avatar Oct 23 '20 12:10 vecerek

Did you place them under the scope? Also if you read the notice at the top here https://yarnpkg.com/configuration/yarnrc you can see that your syntax is incorrect

Try:

npmAuthToken: "${ARTIFACTORY_API_KEY}"

merceyz avatar Oct 23 '20 12:10 merceyz

Yes. The script currently looks like this but it still results in the same invalid authentication issue:

cat << EOF > ~/.yarnrc.yml
npmScopes:
  myScope:
    npmAuthToken: "${ARTIFACTORY_API_KEY}"
    npmPublishRegistry: "https://myrepo.jfrog.io/myrepo/api/npm/npm"
    npmRegistryServer: "https://myrepo.jfrog.io/myrepo/api/npm/npm"
EOF

vecerek avatar Oct 23 '20 16:10 vecerek

Could you try with npmAuthIdent: "${ARTIFACTORY_USERNAME}:${ARTIFACTORY_API_KEY}"?

merceyz avatar Oct 23 '20 20:10 merceyz

It also fails.

vecerek avatar Oct 23 '20 20:10 vecerek

@merceyz bump

vecerek avatar Nov 09 '20 13:11 vecerek

Pretty sure this is a duplicate of https://github.com/yarnpkg/berry/issues/1039

merceyz avatar Nov 09 '20 14:11 merceyz

For reference, the following works for GitHub Packages: https://github.com/Siteimprove/alfa/blob/c448d93e030b0f6b55433dec5bc667d874befd87/.github/workflows/release.yml#L15-L18

kasperisager avatar Mar 04 '21 15:03 kasperisager

Can yarn v2 not read npmAuthIdent from an env var? Doesn't seem to work for me.

austinbutler avatar Jan 25 '22 21:01 austinbutler

Ah, it's actually YARN_NPM_AUTHIDENT when translated to an environment variable.

austinbutler avatar Jan 25 '22 21:01 austinbutler

It is sometimes sort of possible to script this by using a shell hack like (echo "$USER"; sleep 2; echo "$PASS") | yarn npm login (and yes, the sleep is significant, ignoring it may lead to your username being interpreted as user<NEWLINE>password and have the command waiting for a password).

While passing credentials as an env var seems fine and dandy for regular automation, and the shell hack works in most cases, there's one situation when neither is an option - I've been trying to write a Sherlock reproduction case for #4341, but it seems the stars are all misaligned when running under Sherlock and the shell hack just won't work (the command just hangs, seemingly ignoring stdin), and since the bug I'm trying to reproduce has to do with yarn npm login, passing the env var defeats the purpose.

  1. One option would be having yarn npm login recognize if stdin is not a TTY and adapted to just do two readlines to get username/password. (Passing secrets via command line/env vars is generally considered bad, isn't it?)
  2. Alternatively, scripts/actions/sherlock-prepare.js could include some kind of helper function to invoke (an equivalent of) yarn npm login with script-provided credentials so you could do something like await yarnNpmLogin(username, password) for repro

gustafc avatar May 13 '22 06:05 gustafc

yes, passing secrets via arguments or env vars is bad. Honestly I think just accepting them from a pipe would be good, or being able to pass filenames --user-file --password-file, you might ask why to separate them, that's what the docker secrets spec would do.

xenoterracide avatar Jul 25 '22 17:07 xenoterracide

The workaround no longer seems to work in Node 18.6. I'm getting the following error:

node: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by node)
./script/setup-jfrog-authn: line 10: echo: write error: Broken pipe

Line 10 is

{ echo $ARTIFACTORY_USERNAME; sleep 2; echo $ARTIFACTORY_API_KEY; } | yarn npm login --scope myScope

UPDATE: nvm, the above was caused by a faulty installation of Node.

vecerek avatar Aug 27 '22 06:08 vecerek