node-vault is a free, open source api development & testing project written in JavaScript and released under MIT. It has 555 GitHub stars, 160 forks and 15 open issues, and was last pushed 3 months ago. On this registry it ranks #147 of 154 tracked projects in API Development & Testing, with 5 head-to-head comparisons available.

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 [email protected]: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 pa

readme truncated — read the full docs on github

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 555 GitHub stars.