@noy-db/at-azure-keyvault 0.4.0-pre.4 → 0.4.0-pre.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @noy-db/at-azure-keyvault
2
2
 
3
- **Azure Key Vault sealing key provider for noy-db [managed-passphrase mode](https://github.com/vLannaAi/noy-db/issues/14).**
3
+ **Azure Key Vault sealing key provider for noy-db [managed-secret mode](https://github.com/vLannaAi/noy-db/issues/14).**
4
4
 
5
- An `at-*` provider that seals and unseals the hub-generated random passphrase via Azure Key Vault Encrypt / Decrypt. Every seal and unseal is an authenticated Key Vault API call — giving you an Azure Monitor / Key Vault audit-log-backed access record of every time a user's vault is opened, with no additional instrumentation required.
5
+ An `at-*` provider that seals and unseals the hub-generated random secret via Azure Key Vault Encrypt / Decrypt. Every seal and unseal is an authenticated Key Vault API call — giving you an Azure Monitor / Key Vault audit-log-backed access record of every time a user's vault is opened, with no additional instrumentation required.
6
6
 
7
7
  Like all `at-*` providers, this is a *trusted host* provider: the host you deploy it on CAN decrypt what it unseals. The security boundary is your Azure RBAC / Key Vault access policy — access is controlled by which managed identities or service principals hold the `encrypt` + `decrypt` key permissions on the Key Vault key, not by a secret the host keeps in memory.
8
8
 
@@ -41,7 +41,7 @@ import { shamirRecoveryProvider } from '@noy-db/on-shamir'
41
41
  const db = await createNoydb({
42
42
  store,
43
43
  user: 'alice',
44
- passphraseMode: 'managed',
44
+ secretMode: 'managed',
45
45
  sealingKey: azureKeyVaultSealingProvider({
46
46
  keyId: 'https://my-noydb-vault.vault.azure.net/keys/noydb-sealing/<version>',
47
47
  }),
@@ -50,7 +50,7 @@ const db = await createNoydb({
50
50
 
51
51
  const vault = await db.openVault('acme')
52
52
  // Hub generated a 256-bit random on first open, sealed it via Key Vault Encrypt,
53
- // and persisted to _meta/sealed-passphrase. The user never sees a passphrase.
53
+ // and persisted to _meta/sealed-secret. The user never sees a secret.
54
54
  // On reopen, at-azure-keyvault calls Key Vault Decrypt transparently.
55
55
  // Azure Key Vault audit logs record every Encrypt/Decrypt call with caller
56
56
  // identity + key identifier.
@@ -71,13 +71,13 @@ const vault = await db.openVault('acme')
71
71
 
72
72
  **Azure RSA decrypt is version-bound.** Unlike AWS/GCP symmetric KMS — where the key version travels inside the ciphertext blob — Azure's `CryptographyClient` resolves the key version at construction time and every decrypt call is pinned to that version. This has a critical consequence:
73
73
 
74
- - **Always use a versioned `keyId`** (`https://<vault>.vault.azure.net/keys/<name>/<version>`). The version in the URL is your guarantee that every sealed passphrase can be decrypted by the exact key material used to encrypt it.
75
- - **Do NOT enable Key Vault auto-rotation on a versionless `keyId`.** If the key rotates while you are using a versionless URL, the `CryptographyClient` will resolve to the new version, and every passphrase sealed under the previous version becomes **permanently undecryptable** — every managed-mode vault is locked out with no recovery path.
74
+ - **Always use a versioned `keyId`** (`https://<vault>.vault.azure.net/keys/<name>/<version>`). The version in the URL is your guarantee that every sealed secret can be decrypted by the exact key material used to encrypt it.
75
+ - **Do NOT enable Key Vault auto-rotation on a versionless `keyId`.** If the key rotates while you are using a versionless URL, the `CryptographyClient` will resolve to the new version, and every secret sealed under the previous version becomes **permanently undecryptable** — every managed-mode vault is locked out with no recovery path.
76
76
 
77
77
  **To rotate your sealing key** (e.g. for scheduled cryptographic hygiene):
78
78
 
79
79
  1. Create a new key version (or a new key) in Key Vault.
80
- 2. For each vault, call `unseal` with the old versioned `keyId` to recover the plaintext passphrase.
80
+ 2. For each vault, call `unseal` with the old versioned `keyId` to recover the plaintext secret.
81
81
  3. Call `seal` with a provider configured for the **new** versioned `keyId` to produce a new ciphertext.
82
82
  4. Persist the new sealed blob and update your app configuration to the new versioned `keyId`.
83
83
 
@@ -95,7 +95,7 @@ function azureKeyVaultSealingProvider(opts: {
95
95
 
96
96
  Never pass raw Azure credentials in the options — inject a pre-configured `CryptographyClient` for non-default auth. The default builds a `CryptographyClient` with `DefaultAzureCredential`.
97
97
 
98
- Returns a [`SealingKeyProvider`](../hub/src/team/managed-passphrase.ts) — the contract `@noy-db/hub`'s managed-passphrase mode consumes.
98
+ Returns a [`SealingKeyProvider`](../hub/src/team/managed-secret.ts) — the contract `@noy-db/hub`'s managed-secret mode consumes.
99
99
 
100
100
  ## License
101
101
 
package/dist/index.d.ts CHANGED
@@ -3,10 +3,10 @@ import { RsaEncryptParameters, EncryptResult, RsaDecryptParameters, DecryptResul
3
3
 
4
4
  /**
5
5
  * **@noy-db/at-azure-keyvault** — Azure Key Vault sealing key provider for noy-db
6
- * managed-passphrase mode.
6
+ * managed-secret mode.
7
7
  *
8
8
  * An `at-*` provider that seals and unseals the hub-generated random
9
- * passphrase via Azure Key Vault Encrypt / Decrypt. Every seal and unseal is
9
+ * secret via Azure Key Vault Encrypt / Decrypt. Every seal and unseal is
10
10
  * an authenticated Key Vault API call, giving you an Azure Monitor / Key Vault
11
11
  * audit-log-backed access record of every time a user's vault is opened —
12
12
  * no additional instrumentation required.
@@ -48,7 +48,7 @@ import { RsaEncryptParameters, EncryptResult, RsaDecryptParameters, DecryptResul
48
48
  * const db = await createNoydb({
49
49
  * store,
50
50
  * user: 'alice',
51
- * passphraseMode: 'managed',
51
+ * secretMode: 'managed',
52
52
  * sealingKey: azureKeyVaultSealingProvider({
53
53
  * keyId: 'https://my-noydb-vault.vault.azure.net/keys/noydb-sealing/<version>',
54
54
  * }),
@@ -73,7 +73,7 @@ interface AzureKeyVaultSealingProviderOptions {
73
73
  * Azure RSA decrypt is version-bound: the `CryptographyClient` resolves the
74
74
  * key version at construction time and every decrypt call is pinned to it.
75
75
  * A versionless URL (`.../keys/<name>`) resolves to "latest" — if the key
76
- * auto-rotates, all passphrases sealed under the previous version become
76
+ * auto-rotates, all secrets sealed under the previous version become
77
77
  * **permanently undecryptable**. Always pin to an explicit version.
78
78
  */
79
79
  readonly keyId: string;
package/dist/index.js CHANGED
@@ -8,8 +8,8 @@ function azureKeyVaultSealingProvider(opts) {
8
8
  const client = opts.cryptographyClient ?? new CryptographyClient(opts.keyId, new DefaultAzureCredential());
9
9
  return {
10
10
  id: `azure-kv:${opts.keyId}`,
11
- async seal(passphrase) {
12
- const res = await client.encrypt({ algorithm, plaintext: passphrase });
11
+ async seal(secret) {
12
+ const res = await client.encrypt({ algorithm, plaintext: secret });
13
13
  const c = res?.result;
14
14
  if (!c) throw new Error("@noy-db/at-azure-keyvault: Key Vault encrypt returned no result");
15
15
  return c instanceof Uint8Array ? c : new Uint8Array(c);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * **@noy-db/at-azure-keyvault** — Azure Key Vault sealing key provider for noy-db\n * managed-passphrase mode.\n *\n * An `at-*` provider that seals and unseals the hub-generated random\n * passphrase via Azure Key Vault Encrypt / Decrypt. Every seal and unseal is\n * an authenticated Key Vault API call, giving you an Azure Monitor / Key Vault\n * audit-log-backed access record of every time a user's vault is opened —\n * no additional instrumentation required.\n *\n * ## When to use\n *\n * - Compliance regimes requiring auditable key access logs (FedRAMP, HIPAA\n * with managed-encryption requirements, SOC 2 Type II).\n * - Workloads already running on Azure where a Key Vault RSA key costs less\n * than engineering an equivalent audit trail.\n * - Any case where you need an auditable, Azure-native key custody record\n * for every vault open.\n *\n * ## Setup\n *\n * ```bash\n * # 1. Create a Key Vault and an RSA key (one-time):\n * az keyvault create --name my-noydb-vault --resource-group my-rg --location eastus\n * az keyvault key create --vault-name my-noydb-vault --name noydb-sealing --kty RSA --size 2048\n * # Note the full key identifier URL from the output (id field).\n *\n * # 2. Grant the host's managed identity or service principal the\n * # encrypt + decrypt (or wrapKey + unwrapKey) permissions on the key:\n * az keyvault set-policy --name my-noydb-vault \\\n * --object-id <MANAGED_IDENTITY_OBJECT_ID> \\\n * --key-permissions encrypt decrypt\n * # Credentials are resolved automatically via DefaultAzureCredential:\n * # managed identity attached to the Azure host, AZURE_CLIENT_ID /\n * # AZURE_TENANT_ID / AZURE_CLIENT_SECRET env vars, or `az login` for\n * # local dev.\n * ```\n *\n * ```ts\n * // 3. In your app:\n * import { createNoydb } from '@noy-db/hub'\n * import { azureKeyVaultSealingProvider } from '@noy-db/at-azure-keyvault'\n * import { shamirRecoveryProvider } from '@noy-db/on-shamir'\n *\n * const db = await createNoydb({\n * store,\n * user: 'alice',\n * passphraseMode: 'managed',\n * sealingKey: azureKeyVaultSealingProvider({\n * keyId: 'https://my-noydb-vault.vault.azure.net/keys/noydb-sealing/<version>',\n * }),\n * shamirRecovery: shamirRecoveryProvider(),\n * })\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { SealingKeyProvider } from '@noy-db/hub'\nimport {\n CryptographyClient,\n type EncryptResult,\n type DecryptResult,\n type RsaEncryptParameters,\n type RsaDecryptParameters,\n} from '@azure/keyvault-keys'\nimport { DefaultAzureCredential } from '@azure/identity'\n\n/** Minimal client surface required by {@link azureKeyVaultSealingProvider}. */\ninterface CryptoLike {\n encrypt(params: RsaEncryptParameters): Promise<EncryptResult>\n decrypt(params: RsaDecryptParameters): Promise<DecryptResult>\n}\n\n/** Options for {@link azureKeyVaultSealingProvider}. */\nexport interface AzureKeyVaultSealingProviderOptions {\n /**\n * Full **versioned** key identifier URL, e.g.\n * `https://<vault>.vault.azure.net/keys/<name>/<version>`.\n *\n * Azure RSA decrypt is version-bound: the `CryptographyClient` resolves the\n * key version at construction time and every decrypt call is pinned to it.\n * A versionless URL (`.../keys/<name>`) resolves to \"latest\" — if the key\n * auto-rotates, all passphrases sealed under the previous version become\n * **permanently undecryptable**. Always pin to an explicit version.\n */\n readonly keyId: string\n /** RSA encryption algorithm. Defaults to `'RSA-OAEP-256'`. */\n readonly algorithm?: 'RSA-OAEP-256' | 'RSA-OAEP'\n /**\n * Optional pre-built CryptographyClient (DI for tests).\n * Default: builds one with `DefaultAzureCredential`.\n * Never pass raw Azure credentials in these options.\n */\n readonly cryptographyClient?: CryptoLike\n}\n\n/**\n * Build a {@link SealingKeyProvider} backed by Azure Key Vault Encrypt / Decrypt.\n *\n * Credentials are resolved via `DefaultAzureCredential` — managed identities\n * on Azure hosts, `AZURE_CLIENT_ID` / `AZURE_TENANT_ID` / `AZURE_CLIENT_SECRET`\n * env vars, or `az login` for local dev. Never pass raw credentials in the\n * options; inject a pre-configured `CryptographyClient` for non-default auth\n * instead.\n *\n * @throws Error when Key Vault returns no result (guards against unexpected\n * SDK-response shapes). Any Key Vault API error (Forbidden, NotFound, etc.)\n * propagates as-is.\n */\nexport function azureKeyVaultSealingProvider(opts: AzureKeyVaultSealingProviderOptions): SealingKeyProvider {\n const algorithm = opts.algorithm ?? 'RSA-OAEP-256'\n const client: CryptoLike = opts.cryptographyClient\n ?? new CryptographyClient(opts.keyId, new DefaultAzureCredential())\n\n return {\n id: `azure-kv:${opts.keyId}`,\n\n async seal(passphrase) {\n const res = await client.encrypt({ algorithm, plaintext: passphrase })\n const c = res?.result\n if (!c) throw new Error('@noy-db/at-azure-keyvault: Key Vault encrypt returned no result')\n return c instanceof Uint8Array ? c : new Uint8Array(c)\n },\n\n async unseal(sealed) {\n const res = await client.decrypt({ algorithm, ciphertext: sealed })\n const p = res?.result\n if (!p) throw new Error('@noy-db/at-azure-keyvault: Key Vault decrypt returned no result')\n return p instanceof Uint8Array ? p : new Uint8Array(p)\n },\n }\n}\n"],"mappings":";AA2DA;AAAA,EACE;AAAA,OAKK;AACP,SAAS,8BAA8B;AA4ChC,SAAS,6BAA6B,MAA+D;AAC1G,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,SAAqB,KAAK,sBAC3B,IAAI,mBAAmB,KAAK,OAAO,IAAI,uBAAuB,CAAC;AAEpE,SAAO;AAAA,IACL,IAAI,YAAY,KAAK,KAAK;AAAA,IAE1B,MAAM,KAAK,YAAY;AACrB,YAAM,MAAM,MAAM,OAAO,QAAQ,EAAE,WAAW,WAAW,WAAW,CAAC;AACrE,YAAM,IAAI,KAAK;AACf,UAAI,CAAC,EAAG,OAAM,IAAI,MAAM,iEAAiE;AACzF,aAAO,aAAa,aAAa,IAAI,IAAI,WAAW,CAAC;AAAA,IACvD;AAAA,IAEA,MAAM,OAAO,QAAQ;AACnB,YAAM,MAAM,MAAM,OAAO,QAAQ,EAAE,WAAW,YAAY,OAAO,CAAC;AAClE,YAAM,IAAI,KAAK;AACf,UAAI,CAAC,EAAG,OAAM,IAAI,MAAM,iEAAiE;AACzF,aAAO,aAAa,aAAa,IAAI,IAAI,WAAW,CAAC;AAAA,IACvD;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * **@noy-db/at-azure-keyvault** — Azure Key Vault sealing key provider for noy-db\n * managed-secret mode.\n *\n * An `at-*` provider that seals and unseals the hub-generated random\n * secret via Azure Key Vault Encrypt / Decrypt. Every seal and unseal is\n * an authenticated Key Vault API call, giving you an Azure Monitor / Key Vault\n * audit-log-backed access record of every time a user's vault is opened —\n * no additional instrumentation required.\n *\n * ## When to use\n *\n * - Compliance regimes requiring auditable key access logs (FedRAMP, HIPAA\n * with managed-encryption requirements, SOC 2 Type II).\n * - Workloads already running on Azure where a Key Vault RSA key costs less\n * than engineering an equivalent audit trail.\n * - Any case where you need an auditable, Azure-native key custody record\n * for every vault open.\n *\n * ## Setup\n *\n * ```bash\n * # 1. Create a Key Vault and an RSA key (one-time):\n * az keyvault create --name my-noydb-vault --resource-group my-rg --location eastus\n * az keyvault key create --vault-name my-noydb-vault --name noydb-sealing --kty RSA --size 2048\n * # Note the full key identifier URL from the output (id field).\n *\n * # 2. Grant the host's managed identity or service principal the\n * # encrypt + decrypt (or wrapKey + unwrapKey) permissions on the key:\n * az keyvault set-policy --name my-noydb-vault \\\n * --object-id <MANAGED_IDENTITY_OBJECT_ID> \\\n * --key-permissions encrypt decrypt\n * # Credentials are resolved automatically via DefaultAzureCredential:\n * # managed identity attached to the Azure host, AZURE_CLIENT_ID /\n * # AZURE_TENANT_ID / AZURE_CLIENT_SECRET env vars, or `az login` for\n * # local dev.\n * ```\n *\n * ```ts\n * // 3. In your app:\n * import { createNoydb } from '@noy-db/hub'\n * import { azureKeyVaultSealingProvider } from '@noy-db/at-azure-keyvault'\n * import { shamirRecoveryProvider } from '@noy-db/on-shamir'\n *\n * const db = await createNoydb({\n * store,\n * user: 'alice',\n * secretMode: 'managed',\n * sealingKey: azureKeyVaultSealingProvider({\n * keyId: 'https://my-noydb-vault.vault.azure.net/keys/noydb-sealing/<version>',\n * }),\n * shamirRecovery: shamirRecoveryProvider(),\n * })\n * ```\n *\n * @packageDocumentation\n */\n\nimport type { SealingKeyProvider } from '@noy-db/hub'\nimport {\n CryptographyClient,\n type EncryptResult,\n type DecryptResult,\n type RsaEncryptParameters,\n type RsaDecryptParameters,\n} from '@azure/keyvault-keys'\nimport { DefaultAzureCredential } from '@azure/identity'\n\n/** Minimal client surface required by {@link azureKeyVaultSealingProvider}. */\ninterface CryptoLike {\n encrypt(params: RsaEncryptParameters): Promise<EncryptResult>\n decrypt(params: RsaDecryptParameters): Promise<DecryptResult>\n}\n\n/** Options for {@link azureKeyVaultSealingProvider}. */\nexport interface AzureKeyVaultSealingProviderOptions {\n /**\n * Full **versioned** key identifier URL, e.g.\n * `https://<vault>.vault.azure.net/keys/<name>/<version>`.\n *\n * Azure RSA decrypt is version-bound: the `CryptographyClient` resolves the\n * key version at construction time and every decrypt call is pinned to it.\n * A versionless URL (`.../keys/<name>`) resolves to \"latest\" — if the key\n * auto-rotates, all secrets sealed under the previous version become\n * **permanently undecryptable**. Always pin to an explicit version.\n */\n readonly keyId: string\n /** RSA encryption algorithm. Defaults to `'RSA-OAEP-256'`. */\n readonly algorithm?: 'RSA-OAEP-256' | 'RSA-OAEP'\n /**\n * Optional pre-built CryptographyClient (DI for tests).\n * Default: builds one with `DefaultAzureCredential`.\n * Never pass raw Azure credentials in these options.\n */\n readonly cryptographyClient?: CryptoLike\n}\n\n/**\n * Build a {@link SealingKeyProvider} backed by Azure Key Vault Encrypt / Decrypt.\n *\n * Credentials are resolved via `DefaultAzureCredential` — managed identities\n * on Azure hosts, `AZURE_CLIENT_ID` / `AZURE_TENANT_ID` / `AZURE_CLIENT_SECRET`\n * env vars, or `az login` for local dev. Never pass raw credentials in the\n * options; inject a pre-configured `CryptographyClient` for non-default auth\n * instead.\n *\n * @throws Error when Key Vault returns no result (guards against unexpected\n * SDK-response shapes). Any Key Vault API error (Forbidden, NotFound, etc.)\n * propagates as-is.\n */\nexport function azureKeyVaultSealingProvider(opts: AzureKeyVaultSealingProviderOptions): SealingKeyProvider {\n const algorithm = opts.algorithm ?? 'RSA-OAEP-256'\n const client: CryptoLike = opts.cryptographyClient\n ?? new CryptographyClient(opts.keyId, new DefaultAzureCredential())\n\n return {\n id: `azure-kv:${opts.keyId}`,\n\n async seal(secret) {\n const res = await client.encrypt({ algorithm, plaintext: secret })\n const c = res?.result\n if (!c) throw new Error('@noy-db/at-azure-keyvault: Key Vault encrypt returned no result')\n return c instanceof Uint8Array ? c : new Uint8Array(c)\n },\n\n async unseal(sealed) {\n const res = await client.decrypt({ algorithm, ciphertext: sealed })\n const p = res?.result\n if (!p) throw new Error('@noy-db/at-azure-keyvault: Key Vault decrypt returned no result')\n return p instanceof Uint8Array ? p : new Uint8Array(p)\n },\n }\n}\n"],"mappings":";AA2DA;AAAA,EACE;AAAA,OAKK;AACP,SAAS,8BAA8B;AA4ChC,SAAS,6BAA6B,MAA+D;AAC1G,QAAM,YAAY,KAAK,aAAa;AACpC,QAAM,SAAqB,KAAK,sBAC3B,IAAI,mBAAmB,KAAK,OAAO,IAAI,uBAAuB,CAAC;AAEpE,SAAO;AAAA,IACL,IAAI,YAAY,KAAK,KAAK;AAAA,IAE1B,MAAM,KAAK,QAAQ;AACjB,YAAM,MAAM,MAAM,OAAO,QAAQ,EAAE,WAAW,WAAW,OAAO,CAAC;AACjE,YAAM,IAAI,KAAK;AACf,UAAI,CAAC,EAAG,OAAM,IAAI,MAAM,iEAAiE;AACzF,aAAO,aAAa,aAAa,IAAI,IAAI,WAAW,CAAC;AAAA,IACvD;AAAA,IAEA,MAAM,OAAO,QAAQ;AACnB,YAAM,MAAM,MAAM,OAAO,QAAQ,EAAE,WAAW,YAAY,OAAO,CAAC;AAClE,YAAM,IAAI,KAAK;AACf,UAAI,CAAC,EAAG,OAAM,IAAI,MAAM,iEAAiE;AACzF,aAAO,aAAa,aAAa,IAAI,IAAI,WAAW,CAAC;AAAA,IACvD;AAAA,EACF;AACF;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@noy-db/at-azure-keyvault",
3
- "version": "0.4.0-pre.4",
4
- "description": "Azure Key Vault sealing key provider for noy-db managed-passphrase mode.",
3
+ "version": "0.4.0-pre.6",
4
+ "description": "Azure Key Vault sealing key provider for noy-db managed-secret mode.",
5
5
  "license": "MIT",
6
6
  "author": "vLannaAi <vicio@lanna.ai>",
7
7
  "homepage": "https://github.com/vLannaAi/noy-db/tree/main/packages/at-azure-keyvault#readme",
@@ -34,15 +34,15 @@
34
34
  "peerDependencies": {
35
35
  "@azure/keyvault-keys": "^4.0.0",
36
36
  "@azure/identity": "^4.0.0",
37
- "@noy-db/hub": "0.4.0-pre.4"
37
+ "@noy-db/hub": "0.4.0-pre.6"
38
38
  },
39
39
  "devDependencies": {
40
40
  "@types/node": "^22.0.0",
41
41
  "@azure/keyvault-keys": "^4.0.0",
42
42
  "@azure/identity": "^4.0.0",
43
- "@noy-db/on-shamir": "0.4.0-pre.4",
44
- "@noy-db/hub": "0.4.0-pre.4",
45
- "@noy-db/to-memory": "0.4.0-pre.4"
43
+ "@noy-db/hub": "0.4.0-pre.6",
44
+ "@noy-db/to-memory": "0.4.0-pre.6",
45
+ "@noy-db/on-shamir": "0.4.0-pre.6"
46
46
  },
47
47
  "keywords": [
48
48
  "noy-db",
@@ -50,7 +50,7 @@
50
50
  "azure-keyvault",
51
51
  "kms",
52
52
  "sealing-key-provider",
53
- "managed-passphrase",
53
+ "managed-secret",
54
54
  "encryption",
55
55
  "zero-knowledge"
56
56
  ],