node-vault is a free, open source api development & testing project written in JavaScript and released under MIT. It has 557 GitHub stars, 160 forks and 15 open issues, and was last pushed 22 days ago. On this registry it ranks #178 of 186 tracked projects in API Development & Testing, with 5 head-to-head comparisons available. It gained 2 stars over the last 30 tracked days.

What is node-vault?

node-vault is a client for the HTTP API of HashiCorp's Vault, written for Node.js, intended for JavaScript and Node.js developers who need to manage secrets, tokens, and Vault server state from their own code.

What it is

node-vault is a Node.js client for the HTTP API of HashiCorp's Vault. It lives in the JavaScript and npm ecosystem, is published as the npm package node-vault under the MIT license, and carries topics such as api-client, hashicorp, nodejs, secrets, and vault. Instead of shelling out to the vault command-line tool or writing raw HTTP requests, an application requires the module, configures an endpoint and token, and calls methods such as init, unseal, write, read, update, delete, and list.

The concrete problem it solves is programmatic access to a Vault server from Node.js. Node.js services need to initialize Vault, unseal it after a restart, store and retrieve secrets, and manage their lifecycle, and doing that by hand means maintaining HTTP plumbing, request paths, and auth details. node-vault replaces that ad-hoc layer with a small client that accepts configuration through constructor options or environment variables and maps JavaScript calls onto Vault's HTTP API. It is a client only; the Vault server it talks to is separate software.

Key capabilities

  • Client for the HashiCorp Vault HTTP API, written for Node.js and published on npm as node-vault.
  • Vault lifecycle calls: vault.init({ secret_shares, secret_threshold }) and vault.unseal({ key }), including repeated unseal calls until a threshold is met, with result.sealed and result.progress reporting.
  • Secret operations through vault.write, vault.read, and vault.delete, plus vault.update, which sends a PATCH request using the application/merge-patch+json content type.
  • Secret listing through vault.list, for example vault.list('secret/metadata/'), which returns result.data.keys.
  • Configuration through options such as endpoint, token, namespace, pathPrefix, and apiVersion, or through the environment variables VAULT_ADDR, VAULT_TOKEN, VAULT_NAMESPACE, VAULT_PREFIX, and VAULT_SKIP_VERIFY.
  • Automatic stripping of trailing slashes in the endpoint URL to prevent malformed request URIs.
  • A Kubernetes auth example that reads the service account token from /var/run/secrets/kubernetes.

Who users are and how they work

  • Node.js services that read secrets at runtime from a Vault server reachable at an endpoint such as http://127.0.0.1:8200.
  • Platform and DevOps automation that initializes and unseals Vault servers during provisioning, including multi-key unsealing where secret_threshold is greater than one.
  • Kubernetes workloads using the Kubernetes auth method, reading the service account token mounted at /var/run/secrets/kubernetes.
  • Applications that need to manage Vault secrets from JavaScript without invoking the vault CLI or hand-rolling HTTP requests.
  • Vault Enterprise users who need namespace support through the VAULT_NAMESPACE variable or the namespace option.

Getting started

Install with npm install -S node-vault, which requires Node.js 18.0.0 or newer; older Node.js, from 6.x upward, needs an older release of the package. The client is then constructed with an endpoint and token, or with VAULT_ADDR and VAULT_TOKEN set in the environment.

How it compares

node-vault stands alone in this registry: the facts provided name no comparable Vault client for Node.js and no list of paid products that it replaces. The only comparison supported by the facts is its own model, an MIT-licensed client that talks to a self-hosted Vault server, with no hosted or paid tier described.

When to use it — and when not to

Because node-vault is only a client, anyone self-hosting must also run and operate the Vault server itself, including its storage backend and TLS, and should treat the VAULT_SKIP_VERIFY option with care since it disables SSL certificate verification. Teams that are not on Node.js 18 or newer, or that want managed secrets without operating a Vault server, should look elsewhere. The facts here document core lifecycle and key-value operations plus a Kubernetes auth example, so coverage of other Vault secrets engines is not evidenced.

project readme (upstream, from github) — read inline

node-vault

Build Status Download Status NPM Version License Dependency Status Open Collective backers and sponsors

A client for the HTTP API of HashiCorp's Vault written for Node.js.

Install

Prerequisites:

  • Node.js >= 18.0.0
npm install -S node-vault

Note: If you need to use an older version of Node.js (>= 6.x), use node-vault Please be aware that node-vault Note: Trailing slashes in the endpoint URL (e.g. http://127.0.0.1:8200/) are automatically stripped to prevent malformed request URIs.

Environment Variables

The client reads the following environment variables as defaults:

Variable Description
VAULT_ADDR Vault server URL (overridden by endpoint option)
VAULT_TOKEN Vault token (overridden by token option)
VAULT_NAMESPACE Vault Enterprise namespace (overridden by namespace option)
VAULT_PREFIX Request path prefix (overridden by pathPrefix option)
VAULT_SKIP_VERIFY When set, disables SSL certificate verification

Usage

Init and unseal

const vault = require('node-vault')({
  apiVersion: 'v1',
  endpoint: 'http://127.0.0.1:8200',
  token: 'MY_TOKEN', // optional; can be set after initialization
});

// init vault server
vault.init({ secret_shares: 1, secret_threshold: 1 })
  .then((result) => {
    const keys = result.keys;
    // set token for all following requests
    vault.token = result.root_token;
    // unseal vault server
    return vault.unseal({ secret_shares: 1, key: keys[0] });
  })
  .catch(console.error);

Unseal a vault that is already initialized

If the vault server has been restarted or sealed, you can unseal it using the unseal keys from the original initialization. If the vault was initialized with secret_threshold > 1, you must call unseal multiple times with different keys until the threshold is met.

const vault = require('node-vault')({
  apiVersion: 'v1',
  endpoint: 'http://127.0.0.1:8200',
});

// unseal vault server with a single key
vault.unseal({ key: 'my-unseal-key' })
  .then(console.log)
  .catch(console.error);

When the vault requires multiple unseal keys (threshold > 1):

vault.unseal({ key: 'first-unseal-key' })
  .then((result) => {
    // result.sealed will be true until enough keys are provided
    console.log('Sealed:', result.sealed);
    console.log('Progress:', result.progress + '/' + result.t);
    return vault.unseal({ key: 'second-unseal-key' });
  })
  .then((result) => {
    // once the threshold is met, sealed will be false
    console.log('Sealed:', result.sealed);
  })
  .catch(console.error);

See example/unseal.js for a working example.

Write, read, update and delete secrets

vault.write('secret/hello', { value: 'world', lease: '1s' })
  .then(() => vault.read('secret/hello'))
  .then(() => vault.delete('secret/hello'))
  .catch(console.error);

The update method sends a PATCH request with application/merge-patch+json content type:

vault.update('secret/data/hello', { data: { value: 'new-world' } })
  .catch(console.error);

List secrets

vault.list('secret/metadata/')
  .then((result) => console.log(result.data.keys))
  .catch(console.error);

Kubernetes Auth Example

const fs = require('fs');

// Read service account token from default mount path
const jwt = fs.readFileSync('/var/run/secrets/kubernetes.io/serviceaccount/token', { encoding: 'utf8' });

// If the Vault Kubernetes auth endpoint is /auth/example-cluster/login and the role is example-role
vault.kubernetesLogin({
  role: 'example-role',
  jwt: jwt,
  mount_point: 'example-cluster',
}).catch(console.error);

AppRole Auth Example

const vault = require('node-vault')();

vault.approleLogin({
  role_id: 'my-role-id',
  secret_id: 'my-secret-id',
})
  .then((result) => {
    // client token is automatically set on successful login
    console.log(result.auth.client_token);
  })
  .catch(console.error);

Error Handling

The client exposes two error types accessible from the module:

  • VaultError — Base error class for all vault-related errors.
  • ApiResponseError — Thrown on non-200/204 responses. Contains a response property with statusCode and body.
vault.read('secret/missing')
  .catch((err) => {
    console.error(err.message);       // Error message from Vault
    if (err.response) {
      console.error(err.response.statusCode); // e.g. 404
      console.error(err.response.body);       // Response body from Vault
    }
  });

Custom Commands

You can register custom API commands using generateFunction:

vault.generateFunction('myCustomEndpoint', {
  method: 'GET',
  path: '/my-custom/endpoint/{{id}}',
});

// Use the generated function
vault.myCustomEndpoint({ id: 'abc123' })
  .then(console.log)
  .catch(console.error);

Docs

Generate docco docs via:

npm run docs

Examples

Please have a look at the examples and the generated feature list to see all supported Vault API endpoints.

Instead of installing all the dependencies like vault itself and postgres, you can use docker and docker-compose to link and run multiple docker containers with all of their dependencies.

git clone git@github.com:nodevault/node-vault.git
cd node-vault
docker-compose up vault

Now you can run the examples from another terminal window.

First of all you should initialize and unseal the vault:

node example/init.js

You should see root_token: followed by a long key in the response. Please copy that long key and export it as an environment variable:

export VAULT_TOKEN=<insert long key here>

Now you are able to run all of the other examples:

node example/policies.js

Connecting to Vault Through a Bastion Host

To connect to a vault server in a private network through a bastion host, first open a SOCKS proxy connection:

ssh -D <socksPort> bastion.example.com

Then configure the client with a SOCKS proxy agent:

const { SocksProxyAgent } = require('socks-proxy-agent');
const agent = new SocksProxyAgent(`socks://127.0.0.1:${socksPort}`);

const vault = require('node-vault')({
  apiVersion: 'v1',
  requestOptions: {
    httpsAgent: agent,
    httpAgent: agent,
  },
});

Custom SSL/TLS Configuration

If you encounter SSL errors after upgrading to Node 18+ (e.g., EPROTO errors related to unsafe legacy renegotiation disabled), you can pass SSL/TLS options via requestOptions or rpDefaults when initializing the client:

const vault = require('node-vault')({
  apiVersion: 'v1',
  endpoint: 'https://vault.example.com:8200',
  token: 'MY_TOKEN',
  requestOptions: {
    agentOptions: {
      securityOptions: 'SSL_OP_LEGACY_SERVER_CONNECT',
    },
  },
});

The requestOptions object supports TLS/SSL options (ca, cert, key, passphrase, agentOptions, strictSSL) as well as timeout, httpsAgent, and httpAgent. TLS options are mapped to an https.Agent and applied to every request. You can also pass native axios request options such as custom headers.

You can also pass request options per-call to any method:

vault.read('secret/hello', {
  agentOptions: {
    securityOptions: 'SSL_OP_LEGACY_SERVER_CONNECT',
  },
});

See example/pass_request_options.js for more examples.

Backers

Frequently asked questions

Is node-vault free to use?

node-vault is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does node-vault do?

Client for HashiCorp's Vault

What is node-vault written in?

node-vault is primarily written in JavaScript. Its source is publicly available at https://github.com/nodevault/node-vault, and it has 557 GitHub stars.