Does NPM support encryption of the _auth property in .npmrc? - authentication

By using npm adduser, my credentials get stored as a base64-encoded String username:password into the ~/.npmrc file:
_auth=aGV5OmN1cmlvdXM7LSk=
Anyone with access to this file could easily decode this and find out my password.
Is it possible in NPM to encrypt the _auth value?

It seems that they try to tackle this by using environment variables that are injected in .npmrc when needed:
All npm config files are an ini-formatted list of key = value parameters. Environment variables can be replaced using ${VARIABLE_NAME}
from: https://docs.npmjs.com/files/npmrc
So, in your case you can save your password token in an env variable
export ENV_TOKEN=${mytoken} and have your .npmrc file auth line changed to:
_auth=${ENV_TOKEN}

Related

how to use auth and authToken together with artifactory?

I have problem authenticating artifactory on both local and CI environments with .npmrc:
local config works only with _authToken
#render:registry=https://artifactory.corpname.io/artifactory/api/npm/npm/
//artifactory.corpname.io/artifactory/api/npm/npm/:_authToken=${JFROG_AUTH_TOKEN}
//artifactory.corpname.io/artifactory/api/npm/npm/:always-auth=true
//artifactory.corpname.io/artifactory/api/npm/npm/:email=myemail#corpname.io
CI works only with _auth
#render:registry=https://artifactory.corpname.io/artifactory/api/npm/npm/
//artifactory.corpname.io/artifactory/api/npm/npm/:_auth=${JFROG_AUTH_TOKEN}
//artifactory.corpname.io/artifactory/api/npm/npm/:always-auth=true
//artifactory.corpname.io/artifactory/api/npm/npm/:email=myemail#corpname.io
I've tried adding both hoping it will take whatever is compatible with env
#render:registry=https://artifactory.corpname.io/artifactory/api/npm/npm/
//artifactory.corpname.io/artifactory/api/npm/npm/:_authToken=${JFROG_AUTH_TOKEN}
//artifactory.corpname.io/artifactory/api/npm/npm/:_auth=${JFROG_AUTH_TOKEN}
//artifactory.corpname.io/artifactory/api/npm/npm/:always-auth=true
//artifactory.corpname.io/artifactory/api/npm/npm/:email=myemail#corpname.io
this didn't help, what else can I do to have consistent setup?
as far as I understood env difference is that one of them uses npm login and another one basic auth, but what is responsible for this? both envs use same node version and how do I sync the setup is unclear for me
Try something like:
curl -u %ARTIFACTORY_USER%:%ARTIFACTORY_KEY% https://artifactory.corpname.io/artifactory/api/npm/auth > ~/.npmrc
echo '#render:registry https://artifactory.corpname.io/artifactory/api/npm/components-npm' >> ~/.npmrc
npm config set registry https://artifactory.corpname.io/artifactory/api/npm/mirror-npmjs-org
npm config set #render:registry https://artifactory.corpname.io/artifactory/api/npm/components-npm
Adjust the lines for linux if needed.

Get cache location with env variable

I get get the NPM cache location using:
cache_location="$(npm get cache)"
however, is this value also represented by an env variable that I can read?
Something like NPM_CACHE_LOCATION?
https://docs.npmjs.com/cli/cache
Short answer: It depends on when/how you want to access it, as there is no env variable, (e.g. NPM_CACHE_LOCATION), available whilst npm is not running.
You'll need to invoke npm config get cache or npm get cache as you are currently doing.
However, once npm is running the configuration parameters are put into the environment with the npm_ prefix.
The following demonstrates this...
Discover which env variables are available:
As a way to find out what env variable(s) npm puts in the environment, you can utilize printenv in an npm-script. For example in package.json add:
...
"scripts": {
"print-env-vars": "printenv | grep \"^npm_\""
},
...
Then run the following command:
npm run print-env-vars
Get the cache location via an env variable:
In the resultant log to the console, (i.e. after running npm run print-env-vars), you'll see that there's the npm_config_cache environment variable listed. It reads something like this:
npm_config_cache=/Users/UserName/.npm
In the docs it states:
configuration
Configuration parameters are put in the environment with the npm_config_ prefix. For instance, you can view the effective root config by checking the npm_config_root environment variable.
Note: Running printenv | grep "^npm_" directly via the CLI returns nothing.
Accessing the cache location with env variable:
You can access the cache location via an npm-script, For example:
"scripts": {
"cache-loc-using-bash": "echo $npm_config_cache",
"cache-loc-using-win": "echo %npm_config_cache%"
},
See cross-var for utilizing a cross-platforms syntax.
Accessing the npm cache location via a Nodejs script. For example:
const cacheLocation = process.env.npm_config_cache;
console.log(cacheLocation)
Note: This node script will need to be invoked via an npm-script for the process.env.npm_config_cache to be available. Invoking it via the command line running, e.g. node ./somefile.js will return undefined - this further demonstrates that the parameters with the _npm prefix are only put into the environment whilst npm is running.
Not ideal, however you could set your own environment variable using export of course:
export NPM_CACHE_LOCATION="$(npm get cache)"
and unset to remove it:
unset NPM_CACHE_LOCATION

How should I use artifactory access token for access to npm repo

I would like to use an access token to publish and retrieve from an artifactory npm repo from a CI environment. I have created a Bearer token using the artifactory API but when I try and use that for access in the .npmrc with the format:
//mydomain.jrog.io/:_authToken=myveryverylongaccesstoken
registry=https://mydomain.jfrog.io/mydomain/api/npm/npm
I always receive 401 errors back.
In addition, though perhaps a different issue, if I try to use npm login with my actual artifactory credentials I get the response:
adduser Incorrect username or password
npm WARN adduser You can reset your account by visiting:
npm WARN adduser
npm WARN adduser https://npmjs.org/forgot
npm WARN adduser
npm ERR! code E403
npm ERR! forbidden No oauth npm default login configuration found: org.couchdb.user:myusername
The artifactory docs around access tokens explicitly say this is the sort of use case to set up an access token, but the docs around setting up the npm repo alwyas seem to imply you need a real user account and make no mention of access tokens...
What is your artifactory version?
The "npm login" way is only supported since 5.4 (aka. _authToken), so if you are below that, your only chance is to authenticate with BASIC authentication (aka. _auth).
Basic authentication is fairly easy to setup, Artifactory provides an easy entry point to help you set up your .npmrc
Launch the following (and do not forget to replace user and encrypted_password with the Artifactory user account you want to authenticate with)
curl -u user:encrypted_password https://mydomain.jfrog.io/mydomain/api/npm/auth
It will output something like
_auth = YourLongBasicAuthToken
always-auth = true
email = user#server.com
Copy these 3 lines in your .npmrc, and this should work well...
To generate the contents for .npmrc, use an existing user like admin with its password
curl -uadmin:<PASSWORD> http://<ARTIFACTORY_SERVER_DOMAIN>/artifactory/api/npm/auth
afterwards you can replace/set the _auth key with any base64 encoded username:ACCESS_TOKEN
for scoped packages, use
curl -uadmin:<PASSWORD> http://<ARTIFACTORY_SERVER_DOMAIN>/artifactory/api/npm/npm-repo/auth/<SCOPE>
and set ..username and .._password (base64) with any user and access token
Using Basic Authentication
Using the next described steps you should change your local .nprmc file with the output of the command
To retrieve the next fields _auth, email and always-auth automatically generated -> Run the following command to retrieve these strings directly from Artifactory:
curl -u {username}:{API_key}
http://{artifactory_server_domain}/{domain}/artifactory/api/npm/auth
Notes:
{username} -> Name near Welcome when you are logged in - take a look at the attached screenshot
{Api_key} -> Copy and paste this key - take a look at the attached screenshot
{artifactory_server_domain} - domain of your artifactory accrodingly.
{domain} - additional filed of domain in you url (if present)
Screenshot describes {artifactory_server_domain} and {domain}
The _auth line in the other answers breaks some scoped package retrieval from npmjs. I found that I needed to use specific _auth for just the one registry I was using. See my original answer here https://stackoverflow.com/a/57014522/442837
in addition to the previously offered solutions:
curl -u username:encrypted_password http://<ARTIFACTORY_SERVER_DOMAIN>/artifactory/api/npm/auth >> ~/.npmrc
curl -u username:personal_api_key http://<ARTIFACTORY_SERVER_DOMAIN>/artifactory/api/npm/auth >> ~/.npmrc
here is another option without using curl (*does not work with API key):
npm config set _auth $(echo -n username:encrypted_password | base64)
My experience adds to the comments made by others.
I was working with jfrog and already placed the package in jfrog. When trying to resolve that using jfrog.
I got the error "npm ERR! Unable to authenticate, need: Basic realm="Artifactory Realm"" when i checked logs.
After spending hours trying to resolve.
I came across the documentation.
https://www.jfrog.com/confluence/display/JFROG/npm+Registry#npmRegistry-ConfiguringthenpmClientforaScopeRegistry
This is very useful..The issue is I'm just pasting the access token instead of base64 encoded one.
the helpful part of the page
Then I ran that command curl -u admin with a new credentials and token and got back the base64 encoded one.
Then it started working ..Hope it's helpful to anyone working with jfrog
For windows user :-
1/ Add https://registry.npmjs.org to .npmrc to user profile on top:
registry=https://registry.npmjs.org
or 2/ Run below command
npm config set registry https://registry.npmjs.org

vsts-npm-auth can't get authentication token on VSTS build

I'm attempting to use vsts-npm-auth to get the authentication token for our VSTS package repository. On my development machine I can run the commands
npm install -g vsts-npm-auth
vsts-npm-auth -config path-to-my\.npmrc
and it succeeds in providing me with an authentication token. I'm now trying to recreate this as a build step on VSTS, so I create the powershell script auth-vsts.ps1
$npmrcFile = "$PSScriptRoot\path-to-my\.npmrc";
npm install -g vsts-npm-auth;
vsts-npm-auth -config $npmrcFile;
and add it as a powershell task. However, the task fails as follows
2017-05-30T09:37:41.1082686Z ##[section]Starting: auth-vsts
2017-05-30T09:37:41.1092712Z ==============================================================================
2017-05-30T09:37:41.1092712Z Task : PowerShell
2017-05-30T09:37:41.1092712Z Description : Run a PowerShell script
2017-05-30T09:37:41.1092712Z Version : 1.2.3
2017-05-30T09:37:41.1092712Z Author : Microsoft Corporation
2017-05-30T09:37:41.1092712Z Help : [More Information](https://go.microsoft.com/fwlink/?LinkID=613736)
2017-05-30T09:37:41.1092712Z ==============================================================================
2017-05-30T09:37:41.1112679Z ##[command]. 'd:\a\1\s\auth-vsts.ps1'
2017-05-30T09:37:47.3792461Z C:\NPM\Modules\vsts-npm-auth -> C:\NPM\Modules\node_modules\vsts-npm-auth\bin\vsts-npm-auth.exe
2017-05-30T09:37:47.3792461Z C:\NPM\Modules
2017-05-30T09:37:47.3802239Z `-- vsts-npm-auth#0.25.0
2017-05-30T09:37:47.3802239Z
2017-05-30T09:37:47.3802239Z
2017-05-30T09:37:47.3802239Z vsts-npm-auth v0.25.0.0
2017-05-30T09:37:47.3802239Z -----------------------
2017-05-30T09:37:47.3802239Z Creating npmrcFile. Path: D:\a\1\s\.npmrc
2017-05-30T09:37:47.3802239Z Getting new credentials for source:https://our-domain/_packaging/SharedLib/npm/registry/, scope:vso.packaging_write vso.drop_write
2017-05-30T09:37:49.8729702Z Caught exception: The prompt option is invalid because the process is not interactive.
2017-05-30T09:37:49.8729702Z Parameter name: PromptType
2017-05-30T09:37:49.8729702Z Caught exception: The prompt option is invalid because the process is not interactive.
2017-05-30T09:37:49.8729702Z Parameter name: PromptType
2017-05-30T09:37:49.8729702Z Couldn't get an authentication token for //our-domain/_packaging/SharedLib/npm/registry/:_authToken.
2017-05-30T09:37:50.1769711Z ##[error]Process completed with exit code 1.
2017-05-30T09:37:50.1809715Z ##[section]Finishing: auth-vsts
The error gives no indication as to why it can't obtain the credentials. Any ideas why this might be?
I faced this issue while trying to execute via Visual Studio Code`s powershell terminal
vsts-npm-auth -config .npmrc
But running the same command via simple console solved this issue and I was redirected to authentication window.
Can suggest that due to internal limitations powershell disabled to open another windows.
The error did indicate why it cannot obtain the credentials:
The prompt option is invalid because the process is not interactive.
This could be caused by the build agent does not run in interactive mode which make the credential dialog cannot be prompted. If you are using Hosted Build Agent, the build agent is run as service and there isn't any way to change to interactive mode.
However, the issue here is that if you want to use the feed in a build step, it does not make sense to prompt a credential dialog during the build process since the build step cannot enter the required credential automatically. Not sure if there is any specific requirement in your environment, but the general workflow should be uploading the .npmrc file generated in your local machine to the Source Control so that npm can use the auth token in the file to install/publish packages to VSTS Feed.
Inside your project, you can open a terminal and run
vsts-npm-auth -F -C .npmrc
This script refreshes the npm token. Here I set two parameters: -F forces the refresh (if not set, the token is refreshed only if it is already expired), while -C fileName defines the configuration file.
The vsts authentication system sometimes authenticates the use by popping up a browser window. If the terminal you're running the command from is not interactive (e.g., ssh terminal, vscode terminal) it won't be able to pop up that window, and the authentication will fail.
This worked for me
npx vsts-npm-auth -config .npmrc

Subversion export/checkout in Dockerfile without printing the password on screen

I want to write a Dockerfile which exports a directory from a remote Subversion repository into the build context so I can work with these files in subsequent commands. The repository is secured with user/password authentication.
That Dockerfile could look like this:
# base image
FROM ubuntu
# install subversion client
RUN apt-get -y update && apt-get install -y subversion
# export my repository
RUN svn export --username=myUserName --password=myPassword http://subversion.myserver.com/path/to/directory
# further commands, e.g. on container start run a file just downloaded from the repository
CMD ["/bin/bash", "path/to/file.sh"]
However, this has the drawback of printing my username and password on the screen or any logfile where the stdout is directed, as in Step 2 : RUN svn export --username=myUserName --password=myPassword http://subversion.myserver.com/path/to/directory. In my case, this is a Jenkins build log which is also accessible by other people who are not supposed to see the credentials.
What would be the easiest way to hide the echo of username and password in the output?
Until now, I have not found any way how to execute RUN commands in a Dockerfile silently when building the image. Could the password maybe be imported from somewhere else and attached to the command beforehand so it does not have to be printed anymore? Or are there any methods for password-less authentication in Subversion that would work in the Dockerfile context (in terms of setting them up without interaction)?
The Subversion Server is running remotely in my company and not on my local machine or the Docker host. To my knowledge, I have no access to it except for accessing my repository via username/password authentication, so copying any key files as root to some server folders might be difficult.
The Dockerfile RUN command is always executed and cached when the docker image is build so the variables that svn needs to authenticate must be provided at build time. You can move the svn export call when the docker run is executed in order to avoid this kind of problems. In order to do that you can create a bash script and declare it as a docker entrypoint and pass environment variables for username and password. Example
# base image
FROM ubuntu
ENV REPOSITORY_URL http://subversion.myserver.com/path/to/directory
# install subversion client
RUN apt-get -y update && apt-get install -y subversion
# make it executable before you add it here otherwise docker will coplain
ADD docker-entrypoint.sh /enrypoint.sh
ENTRYPOINT /entrypoint.sh
docker-entrypoint.sh
#!/bin/bash
# maybe here some validation that variables $REPO_USER $REPO_PASSOWRD exists.
svn export --username="$REMOTE_USER" --password="$REMOTE_PASSWORD" "$REPOSITORY_URL"
# continue execution
path/to/file.sh
Run your image:
docker run -e REPO_USER=jane -e REPO_PASSWORD=secret your/image
Or you can put the variables in a file:
.svn-credentials
REPO_USER=jane
REPO_PASSWORD=secret
Then run:
docker run --env-file .svn-credentials your/image
Remove the .svn-credentials file when your done.
Maybe using SVN with SSH is a solution for you? You could generate a public/private key pair. The private key could be added to the image whereas the public key gets added to the server.
For more details you could have a look at this stackoverflow question.
One solution is to ADD the entire SVN directory you previously checked out on your builder file-system (or added as a svn:externals if your Dockerfile is itself in a SVN repository like this: svn propset svn:externals 'external_svn_directory http://subversion.myserver.com/path/to/directory' ., then do a svn up).
Then in your Dockerfile you can simply have this:
ADD external_svn_directory /tmp/external_svn_directory
RUN svn export /tmp/external_svn_directory /path/where/to/export/to
RUN rm -rf /tmp/external_svn_directory
Subversion stores authentication details (if it not disabled in configuration) at client side and use stored username|password on request for the subsequent operations on the same URL.
Thus - you have to run (successful) svn export in Dockerfile with username|password only once and allow SVN to use cached credentials (remove auth. options from command-line) later