-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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
Allow Node to use certificates from the macOS Keychain when making HTTPS requests #39657
Comments
Not sure, but I think it would probably have to be written in C++ somewhere in |
I'm wondering if using the If you submit an app to the App Store that is deemed to use cryptography, you normally have to do some extra export compliance paperwork. However there are exemptions if you're just using encryption that's built into the OS. Apple's docs (https://developer.apple.com/documentation/security/complying_with_encryption_export_regulations) say:
So perhaps if the Node |
Having done the US Dept Commerce export restrictions dance in a previous life working for a company that published our own build of Linux, I can confirm that leveraging the OS is a much easier route to go down. Functionally, this enhancement is pretty important for organizations that are using technologies such as Cisco Umbrella - it spoofs DNS and is essentially a "corporate security approved man-in-the-middle", generating its own SSL certs on the fly. Right now, node apps running behind such a regime cannot connect successfully to any site that Umbrella is intercepting because the SSL certs that Umbrella generates have their own root cert installed in the Apple System keychain. (Note: not in the System Roots keychain). Node would need to look in both keychains to be successful in such an environment - easiest way to do this is via the OS framework. |
Working around this is a pain for anyone with a corporate machine/proxy - node should ideally respect the CAs installed on macos |
This feature request comes up every 1.5 years or so. It's never been implemented and the chances of it happening this time are... let's say, no better than before. The reason node works the way it does is consistency. Node version x.y.z works exactly the same on every platform. Important for apps and libraries. Previous discussions also ran aground on questions like "what if there is more than one trust store?" (Case in point: my Linux box has two. Which one is leading?) |
If there were easier ways to specify the extra CAs that might also be a
good compromise. Currently you must export an (exact) path to a specific
variable. There's no way, for example to use package.json or a shared
config file to set this up just once....
…On Wed, 1 Jun 2022, 21:05 Ben Noordhuis, ***@***.***> wrote:
This feature request comes up every 1.5 years or so. It's never been
implemented and the chances of it happening this time are... let's say, no
better than before.
The reason node works the way it does is consistency. Node version x.y.z
works exactly the same on every platform. Important for apps and libraries.
Previous discussions also ran aground on questions like "what if there is
more than one trust store?" (Case in point: my Linux box has two. Which one
is leading?)
—
Reply to this email directly, view it on GitHub
<#39657 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJWOW6VUCQIYBMH7YZCG23VM667HANCNFSM5BRSNJ5Q>
.
You are receiving this because you commented.Message ID:
***@***.***>
|
I think the wider point is that node should respect what other tools in the
same environment respect. Namely curl
…On Wed, 1 Jun 2022, 23:42 Sam Duke, ***@***.***> wrote:
If there were easier ways to specify the extra CAs that might also be a
good compromise. Currently you must export an (exact) path to a specific
variable. There's no way, for example to use package.json or a shared
config file to set this up just once....
On Wed, 1 Jun 2022, 21:05 Ben Noordhuis, ***@***.***> wrote:
> This feature request comes up every 1.5 years or so. It's never been
> implemented and the chances of it happening this time are... let's say, no
> better than before.
>
> The reason node works the way it does is consistency. Node version x.y.z
> works exactly the same on every platform. Important for apps and libraries.
>
> Previous discussions also ran aground on questions like "what if there is
> more than one trust store?" (Case in point: my Linux box has two. Which one
> is leading?)
>
> —
> Reply to this email directly, view it on GitHub
> <#39657 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAJWOW6VUCQIYBMH7YZCG23VM667HANCNFSM5BRSNJ5Q>
> .
> You are receiving this because you commented.Message ID:
> ***@***.***>
>
|
I put together a package that lets you use the system's trust store: https://github.com/bnoordhuis/node-native-certs Uses the same library that Deno uses. Not yet published because I need to wrangle GitHub Actions into publishing the build artifacts somehow (it's a native library.) If an Actions guru wants to chip in, that'd be very welcome. |
@bnoordhuis thanks for your contribution, and good to know it's the same as Deno under the covers. I'll see if I can rustle up a GitHub Action for you |
As a noob, could you please explain how to go about using this package to allow node to access my keychain? |
This package is something that will be evolved in several iterations to integrate it closer with Node. In the first version, you'd install the package in a project which needs to use TLS root certs from the Keychain. You can either put that glue code in application startup (which will attach the bundle to all future requests), or you can attach the bundle to an individual request. For example, if you use the built-in const https = require("https")
const nativeCerts = require("native-certs")
const ca = nativeCerts()
// Note that this call is async so you also need a callback handler
https.get({ca, host: "example.com", path: "/"}) Or at startup it might look like: const https = require("https")
const nativeCerts = require("native-certs")
const ca = nativeCerts()
https.globalAgent.options.ca = ca
// later on...
https.get({host: "example.com", path: "/"}) After that, all your app's HTTPS requests will use the root certs obtained from:
If you want to use the certs on a different type of TLS connection (e.g. a database), you'd need to look up the respective networking library's way of specifying alternative certs. |
#44532 attempted to add Windows keychain support but seems to have stalled. The fact it's Windows-only makes it less likely to get merged so maybe someone wants to adopt it and add macOS support? Expectation management: I can't guarantee it's going to get merged but multi-platform support would definitely help strengthen its case. |
@chriskilding since the |
Hi @diogoperes, if you want to do this on your laptop this would be called a local module install. This uses the |
There has been no activity on this feature request for 5 months and it is unlikely to be implemented. It will be closed 6 months after the last non-automated comment. For more information on how the project manages feature requests, please consult the feature request management document. |
I think this should be kept open - it looks like there has been some progress toward something that may work... As mentioned, use expectation would be that node works like curl - if you can curl the file you should be able to use npm to install it... |
No one stepped up to do the leg work and "be like curl" is too generic to be actionable. It doesn't seem like this feature request is going anywhere and it's best to let it die off in that case. |
Since there's been no follow-up and no new pull requests (edit: as far as I can see), I'll take the liberty of closing this. |
I'm working on this, #56599 Would it be possible to re-open the issue please. |
On macOS and iOS platforms, Node should integrate with the Keychain to source its certificates for TLS requests.
Is your feature request related to a problem? Please describe.
At work our IT department is setting up TLS traffic inspection using custom certificates. These certificates are preinstalled in the keychains of our corporate Macs.
Mac apps and some CLI programs - like the system
curl
- are built against the Apple Secure Transport or Network frameworks. These allow them to use certificates from the keychain when making TLS requests. As a result the custom certificates work without issue in these programs.Meanwhile, other programs that don't use the Apple frameworks basically all break, unless application-specific workarounds are used. The most high-profile failure we see in Node apps is NPM failing to fetch dependencies because of certificate errors.
At the moment the workaround for Node is to export the root cert to the filesystem, and set the
NODE_EXTRA_CA_CERTS
variable. This is doable but it's annoying, and results in duplicates of the certificate that must be maintained going forward. It would be far easier if Node used one of the aforementioned Apple frameworks, so that it can use certificates from the keychain transparently.Describe the solution you'd like
Following the example of Curl (https://github.com/curl/curl/blob/master/docs/INSTALL.md#apple-platforms-macos-ios-tvos-watchos-and-their-simulator-counterparts), Node for macOS should use either the Secure Transport or Network framework to make TLS requests.
Describe alternatives you've considered
As far as I know the only way to integrate with the Keychain for TLS requests is to use the Apple frameworks.
The text was updated successfully, but these errors were encountered: