diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index e9c61d4..6082113 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -33,4 +33,4 @@ jobs:
run: npm ci
- name: Publish
- run: npm publish --access public
+ run: npm publish --provenance --access public
diff --git a/README.md b/README.md
index f51229f..299a047 100644
--- a/README.md
+++ b/README.md
@@ -47,14 +47,16 @@ vaultClient.read('secret/tst').then(lease => {
```javascript
const vaultClient = VaultClient.boot('main', {
- api: { url: 'https://vault.example.com:8200/' },
+ api: {
+ url: 'https://vault.example.com:8200/',
+ namespace: 'some_namespace', // Optional. X-Vault-Namespace header (canonical location; auth.config.namespace is honored as a legacy fallback)
+ },
auth: {
type: 'iam',
mount: 'aws', // Optional. Vault AWS auth mount point ("aws" by default)
config: {
role: 'my_iam_role',
iam_server_id_header_value: 'https://vault.example.com:8200/', // Optional. X-Vault-AWS-IAM-Server-ID header
- namespace: 'some_namespace', // Optional. X-Vault-Namespace header
region: 'eu-central-1', // Optional. AWS STS region (see below)
credentials: { // Optional. Resolved from the AWS provider chain when omitted
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
@@ -136,6 +138,14 @@ const vaultClient = VaultClient.boot('main', {
* [.read(path)](#VaultClient+read) ⇒ Promise.<Lease>
* [.list(path)](#VaultClient+list) ⇒ Promise.<Lease>
* [.write(path, data)](#VaultClient+write) ⇒ Promise.<Object>
+ * [.delete(path)](#VaultClient+delete) ⇒ Promise.<Object>
+ * [.update(path, data)](#VaultClient+update) ⇒ Promise.<Object>
+ * [.request(method, path, [data])](#VaultClient+request) ⇒ Promise.<Object>
+ * [.deleteVersions(path, versions)](#VaultClient+deleteVersions) ⇒ Promise.<Object>
+ * [.undeleteVersions(path, versions)](#VaultClient+undeleteVersions) ⇒ Promise.<Object>
+ * [.destroyVersions(path, versions)](#VaultClient+destroyVersions) ⇒ Promise.<Object>
+ * [.readMetadata(path)](#VaultClient+readMetadata) ⇒ Promise.<Object>
+ * [.deleteMetadata(path)](#VaultClient+deleteMetadata) ⇒ Promise.<Object>
* [.close()](#VaultClient+close)
* _static_
* [.boot(name, [options])](#VaultClient.boot) ⇒ VaultClient
@@ -143,6 +153,11 @@ const vaultClient = VaultClient.boot('main', {
* [.clear([name])](#VaultClient.clear)
* [Lease](#Lease)
+**Return contract**: [`read()`](#VaultClient+read) and [`list()`](#VaultClient+list) resolve to a
+[`Lease`](#Lease) — use its accessors to extract the secret data. Every other data-plane method
+(`write`, `delete`, `update`, `request` and the KV v2 helpers) resolves to the raw parsed Vault
+response body, which may be empty/undefined for `204 No Content` responses.
+
#### new VaultClient(options)
@@ -157,12 +172,14 @@ Client constructor function.
| [options.api.apiVersion] | String | `v1` | |
| [options.api.requestOptions] | Object | | extra options merged into every HTTP request (see [Custom transport](#custom-transport-proxy--self-signed-tls)) |
| [options.api.namespace] | String | | Optional. Vault namespace, sent as the `X-Vault-Namespace` header on **every** request — login, token lookup/renewal, and all secret operations — for every auth type. This is the canonical location; `auth.config.namespace` is still honored for backward compatibility. |
+| [options.api.kv.autoDetect] | boolean | `false` | auto-detect the KV version of each mount on first use (see [KV v2 & generic backends](#kv-v2--generic-backends)) |
+| [options.api.engines] | Object | `{}` | static mount-to-version map, e.g. `{ secret: 2, legacy: 1 }` (see [KV v2 & generic backends](#kv-v2--generic-backends)) |
| options.auth | Object | | |
| options.auth.type | String | | |
| [options.auth.mount] | String | | Vault auth backend mount point; default varies per method (e.g. "aws" for iam, "approle", "token", "kubernetes") |
| options.auth.config | Object | | auth configuration variables |
| [options.auth.config.namespace] | String | | Optional. Legacy location for the Vault namespace (see `api.namespace`). Sent as the `X-Vault-Namespace` header on **every** request for every auth type. |
-| options.logger | Object | `false` | | Logger that supports "error", "info", "warn", "trace", "debug" methods. Uses `console` by default. Pass `false` to disable logging. |
+| [options.logger] | Object \| false | | Logger that supports "error", "info", "warn", "trace", "debug" methods. Uses `console` by default. Pass `false` to disable logging. |
##### Custom transport (proxy / self-signed TLS)
@@ -197,6 +214,8 @@ env var with no code change. Only disable verification
(`new Agent({ connect: { rejectUnauthorized: false } })`) in throwaway/dev setups — it removes
MITM protection.
+
+
#### vaultClient.fillNodeConfig() ⇒ Promise
Populates Vault's values to NPM "config" module
@@ -237,9 +256,131 @@ Resolves to the raw parsed Vault response body, which may be empty/undefined for
| Param | Type | Description |
| --- | --- | --- |
-| path | | path used to write data |
+| path | string | path used to write data |
| data | object | data to write |
+
+
+#### vaultClient.delete(path) ⇒ Promise.<Object>
+Deletes a secret
+
+On KV v2 mounts this sends `DELETE` to the `data/` path, soft-deleting the latest version.
+On KV v1 / non-KV mounts this sends `DELETE` to the raw path. Resolves to the raw parsed
+Vault response body, which may be empty/undefined for `204 No Content` responses.
+
+**Kind**: instance method of [VaultClient](#VaultClient)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| path | string | path to the secret |
+
+
+
+#### vaultClient.update(path, data) ⇒ Promise.<Object>
+Updates (merge-patches) a KV v2 secret
+
+Sends `PATCH` with `Content-Type: application/merge-patch+json`, merging `data` into the
+existing secret without overwriting keys that are not listed. KV v2 merge-patch operation —
+KV v1 mounts do not support `PATCH` and Vault returns `405` there. Resolves to the raw
+parsed Vault response body.
+
+**Kind**: instance method of [VaultClient](#VaultClient)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| path | string | path to the secret |
+| data | object | keys to merge into the existing secret |
+
+
+
+#### vaultClient.request(method, path, [data]) ⇒ Promise.<Object>
+Raw request — escape hatch for any Vault backend
+
+Sends the literal API path with no KV path rewriting and no response unwrapping, and
+resolves to the parsed response body. Use it for non-KV backends (e.g. Transit) or when you
+have already constructed the complete Vault API path.
+
+**Kind**: instance method of [VaultClient](#VaultClient)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| method | string | HTTP method (e.g. `GET`, `POST`) |
+| path | string | literal API path, sent as-is |
+| [data] | object | request body |
+
+
+
+#### vaultClient.deleteVersions(path, versions) ⇒ Promise.<Object>
+Soft-deletes specific versions of a KV v2 secret
+
+KV v2 only — rejects with `UnsupportedOperationError` on non-v2 mounts. Resolves to the raw
+parsed Vault response body.
+
+**Kind**: instance method of [VaultClient](#VaultClient)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| path | string | path to the secret |
+| versions | Array.<number> | version numbers to soft-delete |
+
+
+
+#### vaultClient.undeleteVersions(path, versions) ⇒ Promise.<Object>
+Undeletes (restores) soft-deleted versions of a KV v2 secret
+
+KV v2 only — rejects with `UnsupportedOperationError` on non-v2 mounts. Resolves to the raw
+parsed Vault response body.
+
+**Kind**: instance method of [VaultClient](#VaultClient)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| path | string | path to the secret |
+| versions | Array.<number> | version numbers to restore |
+
+
+
+#### vaultClient.destroyVersions(path, versions) ⇒ Promise.<Object>
+Permanently destroys specific versions of a KV v2 secret
+
+The destroyed version data cannot be recovered. KV v2 only — rejects with
+`UnsupportedOperationError` on non-v2 mounts. Resolves to the raw parsed Vault response body.
+
+**Kind**: instance method of [VaultClient](#VaultClient)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| path | string | path to the secret |
+| versions | Array.<number> | version numbers to destroy |
+
+
+
+#### vaultClient.readMetadata(path) ⇒ Promise.<Object>
+Reads KV v2 metadata for a secret
+
+Resolves to the metadata document (`current_version`, the `versions` map, timestamps, etc.).
+KV v2 only — rejects with `UnsupportedOperationError` on non-v2 mounts.
+
+**Kind**: instance method of [VaultClient](#VaultClient)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| path | string | path to the secret |
+
+
+
+#### vaultClient.deleteMetadata(path) ⇒ Promise.<Object>
+Deletes all metadata and version history for a KV v2 secret (permanent)
+
+KV v2 only — rejects with `UnsupportedOperationError` on non-v2 mounts. Resolves to the raw
+parsed Vault response body, which may be empty/undefined for `204 No Content` responses.
+
+**Kind**: instance method of [VaultClient](#VaultClient)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| path | string | path to the secret |
+
#### vaultClient.close()