How nvm Handles Mirrored Node.js Downloads with Authentication Headers

nvm handles mirrored Node.js downloads with authentication headers by reading the NVM_AUTH_HEADER environment variable, sanitizing the value via nvm_sanitize_auth_header, and injecting it into curl or wget commands during the download process.

When working with private or corporate Node.js mirrors that require authentication, the nvm-sh/nvm repository provides built-in support for injecting HTTP Authorization headers without modifying core scripts. This functionality enables seamless downloads from authenticated endpoints through environment-driven configuration.

Mirror Resolution via nvm_get_mirror

The nvm_get_mirror function in nvm.sh (lines 2221-2230) determines the base URL for Node.js or io.js downloads. It checks environment variables to override the default public registry.

nvm_get_mirror() {
  local NVM_MIRROR=''
  case "${1}-${2}" in
    node-std) NVM_MIRROR="${NVM_NODEJS_ORG_MIRROR:-https://nodejs.org/dist}" ;;
    iojs-std) NVM_MIRROR="${NVM_IOJS_ORG_MIRROR:-https://iojs.org/dist}" ;;
    *) nvm_err 'unknown type of node.js or io.js release'; return 1 ;;
  esac
  nvm_echo "${NVM_MIRROR}"
}

Key behaviors:

  • Flavor detection – Accepts node or iojs as the first parameter and std as the second.
  • Environment override – Uses NVM_NODEJS_ORG_MIRROR or NVM_IOJS_ORG_MIRROR when defined, falling back to official URLs otherwise.
  • URL validation – Ensures the mirror string is a valid HTTP/HTTPS URL before returning.

Header Sanitization with nvm_sanitize_auth_header

Before injecting authentication credentials into shell commands, nvm sanitizes the header value to prevent command injection attacks. The nvm_sanitize_auth_header function (lines 60-63) strips dangerous characters.

nvm_sanitize_auth_header() {
  nvm_echo "$1" | command sed 's/[^a-zA-Z0-9:;_. -]//g'
}

This function removes any characters outside the allowed set of alphanumeric characters, colons, semicolons, underscores, periods, spaces, and hyphens. It executes only when NVM_AUTH_HEADER is present in the environment.

Download Execution in nvm_download

The nvm_download function (lines 118-158) constructs the actual HTTP request. When NVM_AUTH_HEADER is set, it builds a curl command with the --header flag containing the sanitized Authorization value.

nvm_download() {
  if nvm_has "curl"; then
    local CURL_COMPRESSED_FLAG=""
    local CURL_HEADER_FLAG=""

    if [ -n "${NVM_AUTH_HEADER:-}" ]; then
      sanitized_header=$(nvm_sanitize_auth_header "${NVM_AUTH_HEADER}")
      CURL_HEADER_FLAG="--header \"Authorization: ${sanitized_header}\""
    fi

    local NVM_DOWNLOAD_ARGS=''
    for arg in "$@"; do
      NVM_DOWNLOAD_ARGS="${NVM_DOWNLOAD_ARGS} \"$arg\""
    done
    eval "curl -q --fail ${CURL_COMPRESSED_FLAG:-} ${CURL_HEADER_FLAG:-} ${NVM_DOWNLOAD_ARGS}"
  elif nvm_has "wget"; then
    # wget implementation mirrors the same header injection logic

    # lines 151-155 handle the equivalent --header parameter for wget

  fi
}

Implementation details:

  • Conditional injection – The Authorization header is added only if NVM_AUTH_HEADER is non-empty.
  • Dual backend support – Both curl and wget paths implement identical authentication logic.
  • Quote safety – The sanitized header is wrapped in quotes to handle tokens containing spaces.

Practical Configuration Example

To download Node.js from an authenticated private mirror, export the following environment variables before running nvm commands:


# Configure the private mirror endpoint

export NVM_NODEJS_ORG_MIRROR="https://private-mirror.company.com/nodejs"

# Set the authentication header (Bearer token example)

export NVM_AUTH_HEADER="Bearer abc123def456"

# Install Node.js - nvm will resolve the mirror and inject the auth header

nvm install 18.20.0

This configuration generates a curl command equivalent to:

curl -q --fail --header "Authorization: Bearer abc123def456" \
     -L -s "https://private-mirror.company.com/nodejs/v18.20.0/node-v18.20.0-linux-x64.tar.xz" -o -

If the mirror requires Basic authentication, set the header accordingly:

export NVM_AUTH_HEADER="Basic dXNlcjpwYXNzd29yZA=="

Summary

  • Environment-driven configuration – Mirrors and authentication are controlled entirely through NVM_NODEJS_ORG_MIRROR, NVM_IOJS_ORG_MIRROR, and NVM_AUTH_HEADER without code modifications.
  • Injection protection – The nvm_sanitize_auth_header function in nvm.sh prevents command injection by stripping unsafe characters from header values.
  • Universal backend support – Both curl and wget implementations in nvm_download handle authenticated requests consistently.
  • Zero-touch setup – Private corporate proxies and authenticated CDNs work seamlessly with standard nvm installations.

Frequently Asked Questions

What environment variables configure authenticated mirrors in nvm?

Set NVM_NODEJS_ORG_MIRROR (or NVM_IOJS_ORG_MIRROR for io.js) to specify the mirror URL, and set NVM_AUTH_HEADER to provide the Authorization header value. nvm reads these variables during nvm install and nvm use operations.

How does nvm prevent security risks from authentication headers?

The nvm_sanitize_auth_header function removes characters that could break shell command syntax or enable injection attacks. It allows only alphanumeric characters, colons, semicolons, underscores, periods, spaces, and hyphens, ensuring the header value cannot escape the curl/wget command context.

Does nvm support both curl and wget for authenticated downloads?

Yes. The nvm_download function in nvm.sh implements authentication header injection for both curl (using --header) and wget (using --header or --http-user/--http-password depending on the implementation). The logic ensures consistent behavior regardless of which tool is available on the system.

Can I use nvm with a corporate Node.js mirror requiring authentication?

Absolutely. Configure NVM_NODEJS_ORG_MIRROR to point to your corporate mirror (e.g., https://artifactory.company.com/nodejs-dist), set NVM_AUTH_HEADER to your token or credentials, and run nvm install normally. nvm will route all requests to your internal endpoint with proper authentication.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →