limit users allowed to publish packages within an organization


(Matt Travi) #1

Now that semantic-release has support for publishing pre-releases in beta, I no longer have any reason for anyone in my organization, including myself, to publish a package manually.

We use a bot account for publishing with semantic-release from CI, whose credentials are not available to most of the team. The only tokens created for that account have been CIDR restricted to the CI service that we use. We would like this to be the only way a package can be published, but since all users within an org automatically have publish rights, we cannot limit this properly.

Is this something that might already be in the works, or would it be worth writing up an RFC?


(Kat Marchán) #2

you can already do this, I’m pretty sure?

something like:

$ npm access grant read-only myorg:developers @myorg/mypkg
$ npm team create myorg:robots
$ npm team add myorg:robots travi-deploy-bot
$ npm access grant read-write myorg:robots @myorg/mypkg

Does this not do what you want?


(Matt Travi) #3

i guess i was aware that access can be restricted per package, but as far as i understand, you can only restrict per package, correct? i’d like to restrict at the organization level for all packages owned by the organization and prevent most org members from being able to remove the restriction.

alternatively, rather than being acress the org, maybe across the scope would be better? those are kind of synonymous, but the scope probably covers my goal in a similar way if it would be a better approach. that would cover all private packages and some of our public packages. non-scoped packages initially published by the bot would be owned by the bot, so those are naturally restricted based on our existing practices.

does that help clarify?


(Kat Marchán) #4

There’s two ways to do what I think you’re looking for:

  1. just iterate over npm access ls-packages @org and do npm access grant read-only myorg:developers <pkg>. From there, just make sure that myorg:developers gets read-only access to any package you add.

  2. probably easiest: make sure that, when you add a new user to the org (with $ npm org add orgname username), you remove them from the default <orgname>:developers team and add them to a separate, non-publishing team.

  3. I think there’s a way to change the default team users get added to when you add them to orgs, but you’d need to email support@npmjs.org to clarify that.

The three steps above would all let you manage “at the org level”, or pretty damn close to that. Sufficiently close that I’m not sure we’d need an additional feature. Please note that there’s no such thing as an unscoped org package: they’re all scoped (to the org).


(Matt Travi) #5

i think you’re right that that gets very close to what i’m looking for. my preference from those you listed would be #1, but creating new packages sounds like it would be the complication.

From there, just make sure that myorg:developers gets read-only access to any package you add.

If I understand correctly, this is probably the missing piece to what I think I was asking about. It sounds like I would need to come back after publishing a package and reduce the rights that the developers team has, correct? It would be better if there was a setting on the team itself to ensure that it would only get read-only access on all tokens going forward. This does not exist at this point, correct?

I guess one other piece worth considering is that we do scaffold each new project, so it could be possible to run an npm access command when scaffolding. However, that script would run at repo creation time, before any publishing would have happened. Can the access command be run against a package that hasn’t been published yet? I assume npm wouldn’t know about the package yet, correct?


(Kat Marchán) #6

I’m not actually sure :developers gets read-write access automatically if you publish with a different team. You’d have to test it out because it’s been a while for me. That step might be unnecessary after all.


(Matt Travi) #7

so, i’ve continued to experiment to attempt to figure out what process could accomplish what i’m after.

first, to clarify what wasn’t completely clear above, i’ve settled on what i think i’m really trying to accomplish with teams:

  • a team for org members that only need to consume packages, including private packages, through npm install (with the latest semantic-release features, this is all humans)
  • a team with rights to publish packages (this can now be limited to only our bot account)

based on the conversation above, i decided that making the “developers” team the one with publish rights would currently be the simplest approach, so i moved humans to a new team named “consumers”. the downside that i knew about to this approach is the additional management to move new team members out of the “developers” team and into the “consumers” team. this part isn’t too big of a deal since that happens infrequently and is already a manual process. the part that i’ve finally confirmed is that publishing a new package does not automatically give any rights to teams other than the “developers” team. this is a pretty sensible default behavior, but does mean that some step would need to be taken to grant read access to the team of humans that will be trying to install the package shortly after publishing (since something else will likely depend on it shortly after it is published). additionally, since it seems like granting this access would have to wait until after at least a pre-release version is actually published, it would be difficult to add this as a step to our existing scaffolding script.

long story short, even after spending time attempting to get my head around current behavior, i feel like i still have more unanswered questions than answered ones for how i would ensure the proper access is set for every package under the org. i wasnt able to find much clarification in the docs and even questions asked here are left with a number of maybe’s. i dont say that to suggest anyone should be able to recite all behaviors of the top of their head, but not being able to determine concrete answers adds further discouragement to following through to limit access appropriately.

to be clear, my goal is for the team structure described above to apply to every package under the org. since all configuration is per package, it seems to be far more difficult than in could be to accomplish what seems to be like a pretty simple access rule. this may be a big assumption when there are so many users of npm, but it seems like this would be a very common use case across many teams.

The three steps above would all let you manage “at the org level”, or pretty damn close to that. Sufficiently close that I’m not sure we’d need an additional feature.

while i do think that you are correct that it can technically be accomplished, in practice doing so would be pretty heavy addition to a team that creates new packages regularly. security is a difficult practice to do well, so simplifying doing the right thing would be the reason i think there would be value in a way to apply such a rule consistently across an org rather than per package. might even be an opportunity to structure pricing in a way that encourages even further by charging more for team members that have publish rights than those that only have read access.

i’d love to understand if there are other angles to consider, but even when i consider myself pretty security conscious, i’m having a hard time finding the energy to jump through the hoops that would be required to do this well currently.