{"_id":"@brpvieira/vltx","_rev":"2-8fe87f3b03487bea3c5d6391e286c9b1","name":"@brpvieira/vltx","dist-tags":{"latest":"2.0.0"},"versions":{"1.0.0":{"name":"@brpvieira/vltx","version":"1.0.0","keywords":["secrets","encryption","env","security","vault"],"author":{"name":"Bernardo Vieira"},"license":"ISC","_id":"@brpvieira/vltx@1.0.0","maintainers":[{"name":"brpvieira","email":"bvieira.lists@gmail.com"}],"homepage":"https://github.com/brpvieira/vltx?tab=readme-ov-file","bugs":{"url":"https://github.com/brpvieira/vltx/issues"},"bin":{"vltx":"dist/bin/cli.js"},"dist":{"shasum":"0645eb4be62b202db1f2ac6a66e58277155de246","tarball":"https://registry.npmjs.org/@brpvieira/vltx/-/vltx-1.0.0.tgz","fileCount":17,"integrity":"sha512-YjtqB/tAW05dt3tFRVjjx6Vz7GnYMeTIjKPbYzGBnGr3fmvbnTOl4dkzSGlbBGzSxtVKGhccRIpDSmnNLwG0lQ==","signatures":[{"sig":"MEUCIQCQb8Qi3IWVAlTfa+55wWhIMQNDfnDUwcVJ5ekPziZoPQIgVVpxUR4ZTGcv+NXZNKwsvLXiMRSNGOd3XLirQTbjDg8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":308937},"main":"dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"dist/index.js","engines":{"node":">=16"},"exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"d3b2da3d202bb89866e805159b4d1c97706b965b","scripts":{"cli":"npm run build && ./dist/bin/cli.js","docs":"npm run docs:build-ts && npm run docs:generate-md && npm run docs:clean","lint":"tsc --noEmit && eslint .","test":"npm run lint && vitest run","build":"tsup","clean":"rm -fr ./dist/* && rm -f .vltx*","commit":"commit","prepare":"husky","release":"standard-version","coverage":"vitest run --coverage","lint:fix":"eslint --fix .","test:fix":"npm run lint:fix && vitest run","debug-cli":"npm run build && node --inspect-brk ./dist/bin/cli.js","postbuild":"chmod +x dist/bin/cli.js","docs:clean":"rm -fr ./dist-docs/*","prerelease":"npm test","test:debug":"vitest --inspect-brk --no-file-parallelism","docs:build-ts":"tsc --project tsconfig.json --outDir ./dist-docs","prepublishOnly":"npm run test && npm run build","docs:generate-md":"jsdoc2md ./dist-docs/**/*.js > API.md"},"_npmUser":{"name":"brpvieira","email":"bvieira.lists@gmail.com"},"overrides":{"esbuild":"^0.28.1"},"repository":{"url":"git+https://github.com/brpvieira/vltx.git","type":"git"},"_npmVersion":"11.13.0","description":"simple secure secret storage","directories":{},"lint-staged":{"*.{js,ts,jsx,tsx}":["eslint --fix"]},"_nodeVersion":"24.16.0","dependencies":{"yargs":"^17.7.2","dotenv":"^17.4.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","jiti":"^2.7.0","tsup":"^8.5.1","husky":"^9.1.7","eslint":"^10.4.1","vitest":"^4.1.7","globals":"^17.6.0","@eslint/js":"^10.0.1","typescript":"^6.0.3","@types/node":"^25.9.1","lint-staged":"^17.0.7","@types/yargs":"^17.0.35","@commitlint/cli":"^21.0.2","standard-version":"^9.5.0","jsdoc-to-markdown":"^9.1.3","typescript-eslint":"^8.60.0","@vitest/coverage-v8":"^4.1.7","@vitest/eslint-plugin":"^1.6.18","@commitlint/prompt-cli":"^21.0.2","@commitlint/config-conventional":"^21.0.2"},"_npmOperationalInternal":{"tmp":"tmp/vltx_1.0.0_1781487704441_0.02651123858781368","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@brpvieira/vltx","version":"2.0.0","description":"simple secure secret storage","author":{"name":"Bernardo Vieira"},"keywords":["secrets","encryption","env","security","vault"],"bugs":{"url":"https://github.com/brpvieira/vltx/issues"},"homepage":"https://github.com/brpvieira/vltx?tab=readme-ov-file","repository":{"type":"git","url":"git+https://github.com/brpvieira/vltx.git"},"license":"ISC","engines":{"node":">=16"},"type":"module","main":"dist/index.cjs","module":"dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"bin":{"vltx":"dist/bin/cli.js"},"scripts":{"clean":"rm -fr ./dist/* && rm -f .vltx*","build":"tsup","postbuild":"chmod +x dist/bin/cli.js","prepublishOnly":"npm run test && npm run build","lint:fix":"eslint --fix .","lint":"tsc --noEmit && eslint .","test":"npm run lint && vitest run","test:fix":"npm run lint:fix && vitest run","coverage":"vitest run --coverage","test:debug":"vitest --inspect-brk --no-file-parallelism","prerelease":"npm test","release":"standard-version","prepare":"husky","commit":"commit","debug-cli":"npm run build && node --inspect-brk ./dist/bin/cli.js","cli":"npm run build && ./dist/bin/cli.js","docs:build-ts":"tsc --project tsconfig.json --outDir ./dist-docs","docs:generate-md":"jsdoc2md ./dist-docs/**/*.js > API.md","docs:clean":"rm -fr ./dist-docs/*","docs":"npm run docs:build-ts && npm run docs:generate-md && npm run docs:clean"},"devDependencies":{"@commitlint/cli":"^21.0.2","@commitlint/config-conventional":"^21.0.2","@commitlint/prompt-cli":"^21.0.2","@eslint/js":"^10.0.1","@types/node":"^25.9.1","@types/yargs":"^17.0.35","@vitest/coverage-v8":"^4.1.7","@vitest/eslint-plugin":"^1.6.18","eslint":"^10.4.1","globals":"^17.6.0","husky":"^9.1.7","jiti":"^2.7.0","jsdoc-to-markdown":"^9.1.3","lint-staged":"^17.0.7","standard-version":"^9.5.0","tsup":"^8.5.1","tsx":"^4.22.3","typescript":"^6.0.3","typescript-eslint":"^8.60.0","vitest":"^4.1.7"},"lint-staged":{"*.{js,ts,jsx,tsx}":["eslint --fix"]},"publishConfig":{"access":"public"},"overrides":{"esbuild":"^0.28.1"},"dependencies":{"dotenv":"^17.4.2","yargs":"^17.7.2"},"gitHead":"6539cff4be1142d961ca9a89c985e822374a1b2a","_id":"@brpvieira/vltx@2.0.0","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-z0GJGPOyK59ZSGfpiJZRu+DK2En6Hduezp43FCf7dzxLxaTEwdCpGMMlDaE05/J02L/MROpjTuAY1Vly4UbhTg==","shasum":"7a0833c00d52bd3e7aa577f99d215600dca9042a","tarball":"https://registry.npmjs.org/@brpvieira/vltx/-/vltx-2.0.0.tgz","fileCount":17,"unpackedSize":308937,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@brpvieira%2fvltx@2.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFpMiK/b7EqU7NFqO9CAS8pEzi+oxmDWqWtMDwgToT98AiBnyH6jZVn8DLvvhLXOLZ3BjQ3ttUfajVPTROnfBSm49A=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:6f32bf59-e806-46b0-92b1-003b5c853c92"}},"directories":{},"maintainers":[{"name":"brpvieira","email":"bvieira.lists@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/vltx_2.0.0_1781488590018_0.8632949586724217"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-15T01:41:44.226Z","modified":"2026-06-15T01:56:30.452Z","1.0.0":"2026-06-15T01:41:44.589Z","2.0.0":"2026-06-15T01:56:30.164Z"},"bugs":{"url":"https://github.com/brpvieira/vltx/issues"},"author":{"name":"Bernardo Vieira"},"license":"ISC","homepage":"https://github.com/brpvieira/vltx?tab=readme-ov-file","keywords":["secrets","encryption","env","security","vault"],"repository":{"type":"git","url":"git+https://github.com/brpvieira/vltx.git"},"description":"simple secure secret storage","maintainers":[{"name":"brpvieira","email":"bvieira.lists@gmail.com"}],"readme":"# vltx\n\n**Simple, secure secret storage using asymmetric RSA encryption.**\n\nStore encrypted secrets in a file you can safely commit to source control, package into a Docker image, or distribute to any environment. Secrets are unreadable without the private key — which never leaves your hands.\n\n---\n\n## How it works\n\n`vltx` generates an RSA key pair. The **public key** lives inside the vault file alongside the encrypted secrets. The **private key** stays with you (or your deployment environment). Anyone can add secrets; only the private key holder can read them.\n\n```\n┌─────────────────────────────────┐     ┌──────────────────┐\n│  .vltx  (commit to git)         │     │  .vltx.rsa       │\n│                                 │     │  (keep private)  │\n│  publicKey: \"MIICCgKCAgEA...\"   │     │                  │\n│  secrets:                       │  ←  │  4096-bit RSA    │\n│    DB_URL:  \"a8Kx2...\"          │     │  private key     │\n│    API_KEY: \"mN7pQ...\"          │     │                  │\n└─────────────────────────────────┘     └──────────────────┘\n        safe to distribute                  decrypt only\n```\n\n---\n\n## Installation\n\n```sh\nnpm install @brpvieira/vltx\n```\n\nThis gives you both the **`vltx`** command and the **`vltx`** module for use in your application.\n\n---\n\n## Managing secrets\n\n### 1. Initialize a vault\n\nCreates a vault file and generates a 4096-bit RSA key pair.\n\n```sh\nnpx vltx init\n```\n\nBy default this creates `.vltx` (the encrypted store) and `.vltx.rsa` (your private key) in the current directory. Add `.vltx.rsa` to `.gitignore` immediately.\n\n```sh\necho \".vltx.rsa\" >> .gitignore\n```\n\nTo use custom paths:\n\n```sh\nnpx vltx init --vault-file secrets/production.vault --key-file ~/.keys/prod.rsa\n```\n\nProtect the private key with a passphrase:\n\n```sh\n# Interactive prompt (passphrase is never visible in shell history):\nnpx vltx init --passphrase\n\n# Pipe it in from a password manager or clipboard:\npbpaste | npx vltx init --passphrase\n```\n\n---\n\n### 2. Add secrets\n\n```sh\nnpx vltx add DB_URL \"postgres://user:pass@host/db\"\nnpx vltx add API_KEY \"sk-live-abc123\"\nnpx vltx add SMTP_PASSWORD \"hunter2\"\n```\n\n`add` refuses to overwrite an existing key. To update a secret use `replace`:\n\n```sh\nnpx vltx replace API_KEY \"sk-live-newkey456\"\n```\n\nValues up to **430 UTF-8 bytes** are stored as RSA-OAEP-SHA-256 encrypted secrets. Larger values are stored automatically using hybrid AES-256-GCM encryption (the AES key is RSA-wrapped) — there is no upper size limit.\n\n---\n\n### 3. List keys\n\n```sh\nnpx vltx list\n```\n\n```\n.vltx  (3 secrets)\nKEY            TYPE    CREATED              MODIFIED\n─────────────────────────────────────────────────────────────────\nAPI_KEY        Secret  2025-06-14 10:30:00  2025-06-14 10:30:00\nDB_URL         Secret  2025-06-14 10:31:00  2025-06-14 10:31:00\nSMTP_PASSWORD  Secret  2025-06-14 10:32:00  2025-06-14 10:32:00\n```\n\nValues are never decrypted by `list`. Dates are UTC.\n\n---\n\n### 4. Read a secret\n\nDecrypting requires the private key:\n\n```sh\nnpx vltx get DB_URL\n# postgres://user:pass@host/db\n\n# With a non-default key file — passphrase entered at the prompt:\nnpx vltx get DB_URL --key-file ~/.keys/prod.rsa --passphrase\n```\n\n---\n\n### 5. Delete a secret\n\n```sh\nnpx vltx delete SMTP_PASSWORD\n```\n\n---\n\n### Verbosity\n\nAll commands accept a `--verbose` / `-v` flag that controls how much the library\nlogs during an operation:\n\n| Flag       | Level  | What you see                                     |\n|------------|--------|--------------------------------------------------|\n| _(default)_| `warn` | Warnings and errors only                         |\n| `-v 2`     | `info` | File reads, key loads, secret counts, and above  |\n| `-v 3`     | `debug`| Every internal step (key derivation, clears, …)  |\n| `-v 0`     | `silent`| Errors only — suppress all non-error output     |\n\n```sh\n# see every step during init\nnpx vltx init -v 3\n\n# suppress library chatter; only errors are shown\nnpx vltx get DB_URL -v 0 --key-file ~/.keys/prod.rsa\n```\n\n---\n\n### Environment variables\n\nSet these to avoid repeating paths on every command:\n\n| Variable           | Purpose                        | Default      |\n|--------------------|--------------------------------|--------------|\n| `VLTX_FILE`       | Path to the vault file         | `.vltx`      |\n| `VLTX_KEY_FILE`   | Path to the private key file   | `.vltx.rsa` |\n| `VLTX_PASSPHRASE` | Passphrase for the private key | —            |\n\nPlace them in a `.env` file at the project root — the `vltx` CLI loads it automatically.\n\n```sh\n# .env\nVLTX_FILE=secrets/production.vault\nVLTX_KEY_FILE=~/.keys/prod.rsa\n```\n\n**Passphrase options — choose the right one for your context:**\n\n| Context | Recommended approach |\n|---|---|\n| Local development | `--passphrase` flag → interactive prompt (never appears in shell history) |\n| CI / automation | `VLTX_PASSPHRASE` in environment or `.env` — never pass the value inline |\n| Scripted / piped | `pbpaste \\| vltx get KEY --passphrase` or `cat secret.txt \\| vltx get KEY --passphrase` |\n\n> [!NOTE]\n> `.env` loading is a CLI-only feature. When using the `vltx` package as a library, you may use dotenv followed by `dotenv.config()` before calling `setup()` if you rely on a `.env` file for `VLTX_FILE`, `VLTX_KEY_FILE`, or `VLTX_PASSPHRASE`.\n\n---\n\n## Using secrets in your application\n\nImport `setup` from the package and call it once at startup. It loads the vault and returns a `Vltx` instance. Use the `tagFunction` property to obtain a tagged template literal function you can assign to any identifier.\n\n### Quick start\n\n**ESM (import)**\n```js\nimport { setup } from '@brpvieira/vltx';\n\n// reads .vltx and .vltx.rsa from cwd\nconst secret = setup().tagFunction;\n```\n\n**CommonJS (require)**\n```js\nconst { setup } = require('@brpvieira/vltx');\n\nconst secret = setup().tagFunction;\n```\n\n```js\nconst db = new Database(secret`DB_URL`);\nconst client = new ApiClient(secret`API_KEY`);\n```\n\nThe tag function returns the decrypted string for a known key, or an empty string for an unknown one.\n\n---\n\n### Custom path and identifier\n\n**ESM**\n```js\nimport { setup } from '@brpvieira/vltx';\n\nconst secret = setup({ filename: 'secrets/production.vault' }).tagFunction;\n\nconst db = new Database(secret`DB_URL`);\n```\n\n**CommonJS**\n```js\nconst { setup } = require('@brpvieira/vltx');\n\nconst secret = setup({ filename: 'secrets/production.vault' }).tagFunction;\n```\n\n---\n\n### Reading secrets directly\n\n`vault.get(key)` returns the raw `AnyEntry` object (or `undefined` if the key\nis absent). To obtain the plaintext value call `vault.decrypt(key)`, which\nreturns a `Buffer` (or `undefined` if the key is absent):\n\n**ESM**\n```js\nimport { setup } from '@brpvieira/vltx';\n\nconst vault = setup();\n\nconst dbUrl  = vault.decrypt('DB_URL')?.toString('utf8');\nconst apiKey = vault.decrypt('API_KEY')?.toString('utf8');\n```\n\n**CommonJS**\n```js\nconst { setup } = require('@brpvieira/vltx');\n\nconst vault = setup();\n\nconst dbUrl  = vault.decrypt('DB_URL')?.toString('utf8');\nconst apiKey = vault.decrypt('API_KEY')?.toString('utf8');\n```\n\n---\n\n### TypeScript\n\nThe `tagFunction` property is typed automatically — no declaration file needed:\n\n```ts\nimport { setup } from '@brpvieira/vltx';\n\nconst secret = setup().tagFunction;\nconst dbUrl: string = secret`DB_URL`;\n```\n\n---\n\n### `setup()` options\n\n| Option     | Type      | Default   | Description                           |\n|------------|-----------|-----------|---------------------------------------|\n| `filename` | `string`  | env / `'./.vltx'` | Path to the vault file           |\n| `alias`    | `string`  | `'vltx'`  | Cache key for this vault instance     |\n\n`setup()` is idempotent — repeated calls with the same alias return the cached `Vltx` instance. The vault file path is resolved from `filename`, then `VLTX_FILE`, then `.vltx` in the current directory.\n\n---\n\n### Cache management\n\nBecause ESM caches modules, the vault instances created by `setup()` persist for the entire process lifetime. Two functions let you bust that cache when needed.\n\n#### `remove(alias)`\n\nRemoves one cached instance by its alias. The next `setup()` call with the same alias will create a fresh instance — useful when a vault needs to be reconfigured (e.g. a different file or key) without restarting the process.\n\n```js\nimport { setup, remove } from '@brpvieira/vltx';\n\nconst v1 = setup({ alias: 'main', filename: 'dev.vault' });\nremove('main');\nconst v2 = setup({ alias: 'main', filename: 'prod.vault' }); // fresh instance\n```\n\nReturns the removed `Vltx` instance, or `undefined` if the alias was not found.\n\n#### `clearAll()`\n\nRemoves all cached instances at once. Intended primarily for test environments that need a clean slate between test cases.\n\n```js\nimport { setup, clearAll } from '@brpvieira/vltx';\n\nafterEach(() => {\n    clearAll(); // each test starts with an empty cache\n});\n```\n\n---\n\n### Vltx class API\n\nThe `Vltx` class exposes three static factory methods and two key-lifecycle\ninstance methods. Using a factory method is the recommended approach — each\none validates its preconditions and makes the intent explicit. Full method\nsignatures and types are documented in [API.md](API.md).\n\n> [!WARNING]\n> **Map iteration yields entry objects, not plaintext.**\n>\n> `Vltx` implements `Map<string, AnyEntry>`. Iteration methods\n> (`entries()`, `values()`, `[Symbol.iterator]`, `forEach()`) always yield\n> raw `AnyEntry` objects — no decryption occurs, even when a private key is\n> loaded. Use `decrypt(key)` to obtain the plaintext for a specific key.\n>\n> ```js\n> const v = Vltx.openForReading({ filename: '.vault', privateKeyFilename: '.vault.rsa' });\n>\n> // Iteration yields AnyEntry objects (not plaintext):\n> for (const [k, entry] of v) { /* entry is AnyEntry, not a string */ }\n> [...v.values()]  // [SecretEntry { ... }, SecretEntry { ... }]\n>\n> // Use decrypt() to get the plaintext Buffer for a key:\n> const dbUrl = v.decrypt('DB_URL')?.toString('utf8');\n> ```\n>\n> To export all secrets as plaintext, iterate the keys and call `decrypt()` for\n> each one:\n>\n> ```js\n> const plain = Object.fromEntries(\n>     [...v.keys()].map(k => [k, v.decrypt(k)?.toString('utf8')])\n> );\n> ```\n\n---\n\n#### [`Vltx.openForReading(opts)`](API.md#module_core/vltx--module.exports.openForReading) — decrypt secrets\n\nOpens an existing vault file and loads the private key, enabling decryption.\nThrows if the file does not exist, no private key is supplied, the key\ncannot be parsed, or the private key does not match the vault's public key.\n\n**ESM**\n```js\nimport { Vltx } from '@brpvieira/vltx';\n\nconst v = Vltx.openForReading({\n    filename: 'secrets/production.vault',\n    privateKeyFilename: '/run/secrets/vault.rsa',\n    passphrase: process.env.VLTX_PASSPHRASE, // optional\n});\n\nconst dbUrl = v.decrypt('DB_URL')?.toString('utf8');\n```\n\n**CommonJS**\n```js\nconst { Vltx } = require('@brpvieira/vltx');\n\nconst v = Vltx.openForReading({\n    filename: 'secrets/production.vault',\n    privateKeyFilename: '/run/secrets/vault.rsa',\n    passphrase: process.env.VLTX_PASSPHRASE,\n});\n\nconst dbUrl = v.decrypt('DB_URL')?.toString('utf8');\n```\n\n---\n\n#### [`Vltx.openForWriting(opts)`](API.md#module_core/vltx--module.exports.openForWriting) — add or replace secrets\n\nOpens an existing vault file without loading a private key. The public key\nembedded in the file is loaded automatically, enabling encryption.\nNo decryption capability is available. Useful in environments that only need\nto write secrets (e.g., a CI pipeline that rotates credentials).\n\n`set` throws if the key already exists — use `replace` to overwrite.\nValues exceeding **430 UTF-8 bytes** (`MAX_SECRET_BYTES`) are stored automatically using hybrid AES-256-GCM encryption.\n\n**ESM**\n```js\nimport { Vltx } from '@brpvieira/vltx';\n\nconst v = Vltx.openForWriting({ filename: 'secrets/production.vault' });\nv.set('NEW_SECRET', 'super-secret-value');\nv.replace('API_KEY', 'sk-live-newkey456');\nv.write();\n```\n\n**CommonJS**\n```js\nconst { Vltx } = require('@brpvieira/vltx');\n\nconst v = Vltx.openForWriting({ filename: 'secrets/production.vault' });\nv.set('NEW_SECRET', 'super-secret-value');\nv.write();\n```\n\n---\n\n#### [`Vltx.open(opts)`](API.md#module_core/vltx--module.exports.open) — full control\n\nGeneric opener. Passes the full `VaultConfig` directly to the constructor.\nOnly throws if `opts.filename` is provided but does not exist. No other\nvalidation is performed — `canEncrypt` and `canDecrypt` reflect whatever\nkey material `opts` contains.\n\n**ESM**\n```js\nimport { Vltx } from '@brpvieira/vltx';\n\n// Read and write in one call\nconst v = Vltx.open({\n    filename: 'secrets/production.vault',\n    privateKeyFilename: '/run/secrets/vault.rsa',\n});\n\n// Or open with no file at all (useful for in-memory vaults)\nconst mem = Vltx.open({ publicKey: myPublicKeyPem });\n```\n\n**CommonJS**\n```js\nconst { Vltx } = require('@brpvieira/vltx');\n\nconst v = Vltx.open({\n    filename: 'secrets/production.vault',\n    privateKeyFilename: '/run/secrets/vault.rsa',\n});\n```\n\n---\n\n#### [`lock()`](API.md#module_core/vault--module.exports+lock) and [`unlock()`](API.md#module_core/vault--module.exports+unlock) — key lifecycle\n\n`lock()` discards the private key, leaving the vault in encrypt-only mode.\n`unlock(opts)` loads a new private key. Both return `this` for chaining.\nUse them to limit the window during which decryption key material is held in\nmemory.\n\n**ESM**\n```js\nimport { Vltx } from '@brpvieira/vltx';\n\nconst v = Vltx.openForReading({\n    filename: 'secrets/production.vault',\n    privateKeyFilename: '/run/secrets/vault.rsa',\n});\n\nconst dbUrl = v.decrypt('DB_URL')?.toString('utf8'); // decrypt while key is loaded\n\nv.lock(); // discard the private key\n// v.canDecrypt === false — safe to pass around read-only\n\n// Restore decryption when needed\nv.unlock({ privateKeyFilename: '/run/secrets/vault.rsa' });\n// v.canDecrypt === true again\n```\n\n**CommonJS**\n```js\nconst { Vltx } = require('@brpvieira/vltx');\n\nconst v = Vltx.openForReading({\n    filename: 'secrets/production.vault',\n    privateKeyFilename: '/run/secrets/vault.rsa',\n});\n\nv.decrypt('DB_URL');\nv.lock();\nv.unlock({ privateKeyFilename: '/run/secrets/vault.rsa' });\n```\n\n---\n\n#### Direct instantiation (advanced)\n\n`new Vltx(opts)` behaves like `Vltx.open()` but performs no validation:\na missing or unreadable vault file is silently ignored rather than thrown.\n**Using a factory method is the recommended approach.**\n\n```js\nimport { Vltx } from '@brpvieira/vltx';\n\nconst v = new Vltx({\n    filename: 'secrets/production.vault',\n    privateKeyFilename: '/run/secrets/vault.rsa',\n});\n```\n\n---\n\n## Security notes\n\n- Encryption uses **RSA-OAEP-SHA-256** (Node.js native `crypto` — no third-party crypto libraries).\n- Keys are **4096-bit**. Private keys can be protected with **AES-256-CBC** via a passphrase.\n- Each value is prepended with a 16-byte random salt before encryption, so the same plaintext always produces a different ciphertext.\n- Values up to **430 UTF-8 bytes** are RSA-OAEP-SHA-256 encrypted (the plaintext cap for a 4096-bit key: 512-byte modulus − 66-byte OAEP overhead − 16-byte random salt). Larger values are stored automatically using hybrid AES-256-GCM encryption: a fresh random AES-256 key encrypts the value, and the AES key is RSA-OAEP-SHA-256 wrapped. There is no upper size limit.\n- The vault file contains only the public key and ciphertext — it is safe to commit, distribute, or embed in container images.\n- The private key is **never** written into the vault file. Guard it as you would a production password.\n- The `--passphrase` flag **never accepts a value on the command line**. It either prompts interactively (TTY) or reads from stdin (pipe), so the passphrase is never exposed in shell history or `/proc/<pid>/cmdline`. Use `VLTX_PASSPHRASE` for non-interactive environments.\n","readmeFilename":"README.md"}