{"id":19122911,"url":"https://github.com/digitalbazaar/edv-client","last_synced_at":"2026-02-27T14:42:06.976Z","repository":{"id":34763478,"uuid":"179759688","full_name":"digitalbazaar/edv-client","owner":"digitalbazaar","description":"An Encrypted Data Vault Client","archived":false,"fork":false,"pushed_at":"2025-09-18T03:16:36.000Z","size":547,"stargazers_count":14,"open_issues_count":13,"forks_count":9,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-10-25T02:47:52.307Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/digitalbazaar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-05T21:55:41.000Z","updated_at":"2025-10-08T20:43:15.000Z","dependencies_parsed_at":"2024-06-18T19:56:57.285Z","dependency_job_id":"580ee212-e34a-4404-b22c-9dd478bee595","html_url":"https://github.com/digitalbazaar/edv-client","commit_stats":{"total_commits":502,"total_committers":11,"mean_commits":45.63636363636363,"dds":0.5657370517928286,"last_synced_commit":"bece780aa49007818a4b46f997102a5cd47a90af"},"previous_names":["digitalbazaar/secure-data-hub-client"],"tags_count":54,"template":false,"template_full_name":null,"purl":"pkg:github/digitalbazaar/edv-client","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fedv-client","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fedv-client/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fedv-client/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fedv-client/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalbazaar","download_url":"https://codeload.github.com/digitalbazaar/edv-client/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fedv-client/sbom","scorecard":{"id":342346,"data":{"date":"2025-08-11","repo":{"name":"github.com/digitalbazaar/edv-client","commit":"f9b46f8daef0b2b43071e755f3e247ecd574f3cb"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Code-Review","score":1,"reason":"Found 3/16 approved changesets -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/digitalbazaar/edv-client/main.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/digitalbazaar/edv-client/main.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:29: update your workflow using https://app.stepsecurity.io/secureworkflow/digitalbazaar/edv-client/main.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/digitalbazaar/edv-client/main.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/digitalbazaar/edv-client/main.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/digitalbazaar/edv-client/main.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/digitalbazaar/edv-client/main.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yaml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/digitalbazaar/edv-client/main.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/main.yaml:70: update your workflow using https://app.stepsecurity.io/secureworkflow/digitalbazaar/edv-client/main.yaml/main?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/main.yaml:19","Warn: npmCommand not pinned by hash: .github/workflows/main.yaml:35","Warn: npmCommand not pinned by hash: .github/workflows/main.yaml:51","Warn: npmCommand not pinned by hash: .github/workflows/main.yaml:67","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   4 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 19 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-18T06:11:05.773Z","repository_id":34763478,"created_at":"2025-08-18T06:11:05.773Z","updated_at":"2025-08-18T06:11:05.773Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29900054,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T14:30:36.354Z","status":"ssl_error","status_checked_at":"2026-02-27T14:30:01.989Z","response_time":57,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T05:23:30.747Z","updated_at":"2026-02-27T14:42:06.957Z","avatar_url":"https://github.com/digitalbazaar.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JavaScript Encrypted Data Vault Client _(@digitalbazaar/edv-client)_\n\n\u003e A JavaScript library for Web and node.js apps for interfacing with a remote\n\u003e Encrypted Data Vault server\n\n## Table of Contents\n\n- [Background](#background)\n- [Install](#install)\n- [Usage](#usage)\n- [API](#api)\n- [Contribute](#contribute)\n- [License](#license)\n\n## Background\n\nThis library provides a client that Web and node.js apps can use to interface\nwith remote Encrypted Data Vault (EDV) servers.\n\nIt consists of one main class:\n\n* **`EdvClient`** - instances provide a CRUD (+ find) interface to a specific\n  configured Encrypted Data Vault server and ensure appropriate database\n  indexes are set up. Static methods allow for the creation of EDVs with a\n  remote storage service, e.g.\n  Encrypted Data Vault storage servers.\n\n#### Encrypted Data Vault storage servers:\n* MongoDB-based - https://github.com/digitalbazaar/bedrock-edv-storage\n* PouchDB-based - https://github.com/digitalbazaar/bedrock-web-pouch-edv\n\n## Install\n\n- Browsers and Node.js 18+ are supported.\n- [Streams API][] required. Older browsers must use a polyfill.\n- [Web Crypto API][] required. Older browsers must use a polyfill.\n\nTo install from NPM:\n\n```sh\nnpm install @digitalbazaar/edv-client\n```\n\nTo install locally (for development):\n\n```sh\ngit clone https://github.com/digitalbazaar/edv-client.git\ncd edv-client\nnpm install\n```\n\n## Usage\n\n### Creating and registering an Encrypted Data Vault (EDV)\n\nFirst, create a key agreement key and an HMAC (hash-based message authentication\ncode) key for encrypting your documents and blinding any indexed attributes in\nthem. This requires creating some cryptographic key material which can be done\nlocally or via a KMS system. The current example shows using a KMS system\n(TODO: show a simpler local example):\n\n```js\nimport {CapabilityAgent, KeystoreAgent, KmsClient} from 'webkms-client';\nimport {EdvClient} from 'edv-client';\n```\nAlthough Encrypted Data Vaults are not bound to any particular key management\nsystem, we recommend that you set up a Key Management Service using an\nimplementation such as\n[`webkms-switch`](https://github.com/digitalbazaar/webkms-switch)\nwhich you can connect to using\n[`webkms-client`](https://github.com/digitalbazaar/webkms-client).\n\nOptional:\n\n```js\n// create a CapabilityAgent (for invoking zcaps)\nconst capabilityAgent = await CapabilityAgent.fromSecret({secret, handle});\n\n// create a keystore and an agent for working with it\n// the baseUrl can be set to a dev API or production API\nconst kmsBaseUrl = `${config.server.baseUri}/kms`;\nconst keystore = KmsClient.createKeystore({\n  // the url for the keystore is configurable\n  url: `${kmsBaseUrl}/keystores`,\n  config: {\n    // on init the sequence must be 0\n    sequence: 0,\n    controller: capabilityAgent.id,\n    invoker: capabilityAgent.id,\n    // this allows the capabilityAgent to delegate zCaps\n    delegator: capabilityAgent.id\n  },\n  /**\n   * optional `httpsAgent`,\n   * usually not applicable for front-end (you may use axios),\n   * for back-end use cases a nodejs `https.Agent`\n   * may be used to allow the use of self signed certificates using\n   * the `rejectUnauthorized: false` flag in the contructor.\n  */\n  httpsAgent\n});\nconst keystoreAgent = new KeystoreAgent({keystore, capabilityAgent});\n\n// use the keystore agent to create key agreement and HMAC keys\nconst keyAgreementKey = await keystoreAgent.generateKey({type: 'keyAgreement'});\nconst hmac = await keystoreAgent.generateKey({type: 'hmac'});\n```\n\nNow you can create and register a new EDV configuration:\n\n```js\n// TODO: explain EDV service must be able to authenticate user\nconst controller = 'account id goes here';\n\nconst config = {\n  // on init the sequence must be 0 and is required\n  sequence: 0,\n  controller,\n  // TODO: Explain what 'referenceId' is\n  referenceId: 'primary',\n  keyAgreementKey: {id: keyAgreementKey.id, type: keyAgreementKey.type},\n  hmac: {id: hmac.id, type: hmac.type}\n};\n\n// sends a POST request to the remote service to create an EDV\nconst remoteConfig = await EdvClient.createEdv({config});\n\n// connect to the new EDV via a `EdvClient`\nconst client = new EdvClient({id: remoteConfig.id, keyAgreementKey, hmac});\n// to only use fips-compliant key agreement and encryption algorithms:\nconst client = new EdvClient(\n  {id: remoteConfig.id, keyAgreementKey, hmac, cipherVersion: 'fips'});\n```\n\nYou can specify a url when you create and register a new EDV configuration:\n\n```js\n// TODO: explain EDV service must be able to authenticate user\nconst controller = 'account id (or DID if using zcaps) goes here';\n\nconst config = {\n  // on init the sequence must be 0 and is required\n  sequence: 0,\n  controller,\n  // TODO: Explain what 'referenceId' is\n  referenceId: 'primary',\n  keyAgreementKey: {id: keyAgreementKey.id, type: keyAgreementKey.type},\n  hmac: {id: hmac.id, type: hmac.type}\n};\n\n// sends a POST request to the remote service to create an EDV\nconst remoteConfig = await EdvClient.createEdv({\n  url: 'https://server.example/edvs',\n  config,\n  // must pass `invocationSigner` and optional `capability` if `controller`\n  // is a DID\n  /* invocationSigner, capability */\n});\n\n// connect to the new EDV via a `EdvClient`\nconst client = new EdvClient({id: remoteConfig.id, keyAgreementKey, hmac});\n```\n\n\n### Loading a saved EDV config\n\nIf you have previously registered an EDV config (via `createEdv()`),\nand you know its `id`, you can fetch its config via `get()`:\n\n```js\n// registered config\nconst {id} = await EdvClient.createEdv({config});\n\n// later, it can be fetched via the id\nconst remoteConfig = await EdvClient.getConfig({id});\n\n// connect to the existing EDV via an `EdvClient` instance\nconst client = new EdvClient({id: remoteConfig.id, keyAgreementKey, hmac});\n```\n\nIf you know a controller/`accountId` but do not know a specific EDV `id`, you\ncan create a client for an EDV by a controller-scoped custom `referenceId`:\n\n```js\n// get the account's 'primary' EDV config to connect to the EDV\n// note that a referenceId can be any string but must be unique per controller\nconst config = await EdvClient.findConfig(\n  {controller: accountId, referenceId: 'primary'});\nconst client = new EdvClient({id: config.id, keyAgreementKey, hmac});\n```\n\n### Using a EdvClient instance for document storage\n\nSee the API section below.\n\n## API\n\n### `EdvClient`\n\n#### `constructor`\n\n#### `insert`\n\n#### `get`\n\n#### `update`\n\n#### `delete`\n\n#### `find`\n\n#### `ensureIndex`\n\n#### `updateIndex`\n\n## Contribute\n\nPlease follow the existing code style.\n\nPRs accepted.\n\nIf editing the Readme, please conform to the\n[standard-readme](https://github.com/RichardLitt/standard-readme) specification.\n\n## License\n\n[BSD-3-Clause](LICENSE) Copyright 2019-2025 Digital Bazaar, Inc.\n\nCommercial support is available by contacting\n[Digital Bazaar](https://digitalbazaar.com/) \u003csupport@digitalbazaar.com\u003e.\n\n[Streams API]: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API\n[Web Crypto API]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbazaar%2Fedv-client","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalbazaar%2Fedv-client","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbazaar%2Fedv-client/lists"}