Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] ability to install packages with at least X days since publication #4494

Closed
2 tasks done
osher opened this issue Mar 3, 2022 · 12 comments
Closed
2 tasks done
Labels
Bug thing that needs fixing Needs Triage needs review for next steps Release 8.x work is associated with a specific npm 8 release

Comments

@osher
Copy link

osher commented Mar 3, 2022

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

Current Behavior

We're in work on FedRAMP certification, and there's a stormy debate about dependency scans and dependency vulnerabilities. Here's how it relates to you:

Currently, npm i and npm update will install the latest version of a depenency (or the latest according to the policy in package.json) - even if it was published just now.
Published just now - could also be - published with a new vulnerability that is yet to be reported.

e.g.

  • a package ownership was compromised and loaded with malicious code.
  • a package was just published with an exploit

Expected Behavior

Ideally, I would like to run npm i in a new project, or npm update in an existing project, and get all the dependencies that have had at least X days or more since their publication date.
My security team currently names 7, but teams should be able to can bring their own policy over some built-in default.

Basically,
This 7 or X can come from a global setting, from a project's .npmrc, from CLI args, from env-var - whatever you decide to support.

Ideally, there should be a form to configure such an X to a pattern in package name (e.g. starts with a prefix, belongs to a scope, or a concrete name) - but that's already high-end customization, way past the MVP of this feature.

When the policy of version-range that offers only too-new versions - I suppose I'd like a message about it, and it should be possible to control the npm exit code for this case.

Steps To Reproduce

Well, it's a feature request... I'll describe the usage

npm config set stabilityDays 7
npm config set '@my-corp/*.onOnlyTooNew' warn
npm config set '@my-corp/*.stabilityDays' 1
npm config set '@my-corp/*.onOnlyTooNew' info
npm config set package-that-gave-problems-before.stabilityDays 90
npm config set 'package-that-gave-problems-before.onOnlyTooNew' error

and then:

npm update

Can conisder to distinct npm config -g or something to distinct project settings and global settings.

Sure, this is a big one, and this might call for a discussion.
I hope this helps.

Environment

  • npm: any
  • Node.js: any active or LTS version
  • OS Name: all
  • System Model Name: all
  • npm config:
; copy and paste output from `npm config ls` here
@osher osher added Bug thing that needs fixing Needs Triage needs review for next steps Release 8.x work is associated with a specific npm 8 release labels Mar 3, 2022
@osher osher changed the title [Feature] ability to install packages with X days since publication [Feature] ability to install packages with at least X days since publication Mar 3, 2022
@ljharb
Copy link
Contributor

ljharb commented Mar 3, 2022

You can already run npm install --before=2022-03-01 or whatever date you like.

@osher
Copy link
Author

osher commented Mar 3, 2022

@ljharb - if that works - that's just might be what I need!

From what version is that? I cannot find it in the docs.

If it works - then treat this issue as a request to update the docs: https://docs.npmjs.com/cli/v8/commands/npm-install and a proposition for thinner config control

@ljharb
Copy link
Contributor

ljharb commented Mar 3, 2022

I think since npm 5 something? It’s been there for a long time (it can be controlled by .npmrc and env vars)

@osher
Copy link
Author

osher commented Mar 3, 2022

@ljharb - thanks that's very helpful

Now that you mentioned it - all I could find is this:

versions that were available **on or before** the \`--before\` time get

'enjoy-by': ['--before'],

Which , really, enjoy-by? I would have never guessed... 😛

and I am searching hard...

So lets take it to the next level.
I need to be biased in favor of dependency of my own corp (which are comfortably put under a scope)
e.g - require less time, or even to get a free-pass against this policy.

It gets more complicated when I want dependencies of my proprietary packages to answer to this policy, even when my proprietary packages "get a free pass".

Got an ace there for me?

@ljharb
Copy link
Contributor

ljharb commented Mar 3, 2022

No, i think you have to choose all or nothing with this approach.

Ab alternative approach is configuring your internal registry to wait a period of time before “releasing” things it’s downloaded from the public registry.

@osher
Copy link
Author

osher commented Mar 3, 2022

aha. finally found where it appears in the docs:
https://docs.npmjs.com/cli/v8/using-npm/config#before

Still could not find a word on such option on artifactory's docs - any help will be appreciated.

Anyway, this all-or-nothing thing kinda pulls the sting out of this feature 😢

I can't even think of a monkey-patching I can do to get latest fixes for corporate packages and deny the rest.
Suppose I grep my packages out of the package.json, and install it with --before. Great.
Now I checkout the original file, and grep out any package that is not mine. When I install - it could pull new packages again.

How about the opposite?
Suppose I npm i without grepping anything, then I grep out my own packages and npm i --before <date>.
This could be interesting if it will update things back, but leave my packages.
I will need to create a real-world test for this.

Anyway, that's what I got for today, any help will be appreciated!

@ljharb
Copy link
Contributor

ljharb commented Mar 3, 2022

It's entirely possible artifactory doesn't support it; you'd need to file an issue with them for that.

My personal opinion tho is that all of this is unnecessary, and the few times "waiting a day or two" would have helped in the last decade don't outweigh the billions of times immediate updates offer benefits :-) but i understand it may not be your decision.

I think that what you could do is npm install --package-lock-only --before=$whatever, and diff that lockfile to the current one, and determine if any public packages were updated?

@osher
Copy link
Author

osher commented Mar 3, 2022

You're right - it's not my decision, it's a security policy I'm trying to comply with, no say there.

So far, until this requirement fell down, we worked without a lockfile: when a version was packed into a docker - it was during CI and treated like a testable proofable binary: scanned, functional-tested, integration-tested and black-box e2e. With our coverage we're confident with using greatest and latest in everything except what vitally had to be pinned for a breaking change or a known vulnerability - which is followed up by the team with issues of technical debt until they are unpinned.

Now, on this comes the requirement to include latest of the corporate-packages, and 7 days old for the rest, taking that 7 days is legit delay for exploits to be noted.
If I cannot find a way to do that - the alternative is tools like renovate, dependabot or snyk , with all the noise they create, manual decisions they require and setup hussle for a monorepo of ~30 services and ~60 packages, each with it's own package.json.

I'm completely aware that such npm feature will not be developed fast enough for us even if the request will be adopted by npm. But I believe the usecase is sound.

Anyway. To our business - I'm probably missing something.... I'm trying to think how can I use what you just showed me: Say we detected some public packages were recently updated.
How does that bring us closer to public packages in delay next to latest corporate packages?
The main challenge is obviously that dependencies of dependencies should still follow same rules...
Even if I npm i --no-save a pinned version of some nested dependency - I'm not sure what npm will do to already insatalled versions. I'll have to test that with a real-life scenario. but this will not happen this week

@ljharb
Copy link
Contributor

ljharb commented Mar 3, 2022

Every application always needs a lockfile; that's a long-standing best-practice.

@darcyclarke
Copy link
Contributor

before is definitely what you're looking for afaict. If it's not, feel free to open a new issue/PR on our npm/rfcs repo where we discuss feature requests (notably, issues on the CLI repo are meant just for bugs)

@osher
Copy link
Author

osher commented Mar 9, 2022

@ljharb - lockfile is not a best practice. lockfile is a recipe for technical debt.
it's a solution for projects in kickoff that don't old dependency with their known vulnerabilities as a tradeoff for stability. You need this tradeoff when you don't have good coverage. If you have good coverage - you better test with latest and greatest, and if you test with latest and greatest - you can ship with latest and greatest.

Which IMHO a by far a better alternative to the noise of dependency bots create.

Obviously, if you don't have the coverage you do not have the guarantees - so you should stick to the lockfile until the project is mature enough.
It also helps if your CI implements a coverage ratchet.

@ljharb
Copy link
Contributor

ljharb commented Mar 9, 2022

@osher a lockfile is a requirement for an application to be mature; you are free to disagree with the rest of the industry, but it doesn’t change anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug thing that needs fixing Needs Triage needs review for next steps Release 8.x work is associated with a specific npm 8 release
Projects
None yet
Development

No branches or pull requests

3 participants