Multi-user authentication across multiple scopes in the same registry
See this idea for a similar request.
I have two separate logins to publish packages in different orgs (i.e., “scopes”) to
https://registry.npmjs.org/. For security reasons, user A shouldn’t have access to publish to scope B and vice versa. This wouldn’t be an issue if both scopes were in different registries, but because both scopes are in the same registry (public NPM registry), I have to manage different
.npmrc files for both users and remember to provide a
--userconfig option every time I need to authenticate with the registry. This increases the potential for simple mistakes that occur as a result of human error.
I could set up project-specific
.npmrc files, but then I’d have to manage numerous
.npmrc files across all of
@a/* scoped and
@b/* scoped packages, duplicating my authentication credentials and increasing the surface area for an accidental commit of an
.npmrc file to a public service. Should that happen, then I’d have to go update credentials across every single project using the same credentials.
@apackages should all be licensed under MIT (
@bpackages should all be licensed under Apache 2.0 (
Once again, I’m forced to use yet another set of
.npmrc files to load with
npm init --userconfig=scope/a/.npmrc. For similar reasons mentions above, this is undesirable.
I don’t know about other devs, but it makes sense to organize all
@a/* scoped projects in the same directory parent directory (e.g.,
@a/**/). As such, it’d be extremely helpful to define all of my
@a default configs at
~/@a/.npmrc and automatically recognized if I run
npm init from within
Add directory traversal to the .npmrc lookup algorithm
Example Directory Structure
~/.npmrc # init-version=0.0.1 ~/@foo/.npmrc # scope configuration # (inherits "init-version" from ../.npmrc) # scope=foo # init-license=MIT # //registry.npmjs.org/:_authToken=AAAA-AAAA-AAAA-AAAA-AAAA ~/@foo/bar/.npmrc # project configuration # (inherits "init-version", "init-license", "scope", and auth creds from ../.npmrc) ~/@bar/.npmrc # init-version=1.0.0 (overrides ../.npmrc) # init-license=Apache-2.0 # scope=bar # //registry.npmjs.org/:_authToken=BBBB-BBBB-BBBB-BBBB-BBBB
Configuration Option Resolution
Config options resolve in the following order (earlier definitions trump later ones):
- CLI options (e.g.,
- Project-level config (
- Scope-level config (
- User-level config (
- Global config file (
- npm builtin config file (
(Note: I’m not sure where environment variables fit into this hierarchy.)
- Scope-specific auth is isolated to a single
- If you’re not using a monorepo, this keeps authToken away from accidental exposure via version control.
- If you are using a monorepo, this is already possible today, with a project-level config.
- Project-level configs inherit scope-level configs, so there’s no need to add the scope-level authToken to every project in the same scope.
npmautomatically knows how to resolve config settings without the need to manually include
--userconfigevery time you need to override a default setting
npm initcan pull
init-license, etc. automatically when I initialize a new scoped directory
npm publishcan pull registry, authentication, and scope configs in order to publish to the right place as the right user, every time
- Because nested
.npmrcfiles can inherit the config of its parent directory, you can override as little or as much as needed, no matter how deep your directories are nested.
- Any configuration can be overridden at any level.
- May no longer need @scoped registry config(just change
registry=...at any level)
- Can be somewhat daunting to new package developers. Will need more robust and user-friendly output from
npm config listcommand.
- I’m not sure where environment variables fit into the config resolution hierarchy.
Hopefully, I’ve explained this clear enough.