authhero 8.2.1 → 8.3.0

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.
@@ -1,4 +1,19 @@
1
1
  import { DataAdapters } from "@authhero/adapter-interfaces";
2
+ import { KeyRing } from "../utils/field-encryption";
3
+ /**
4
+ * Resolves which key id (if any) a tenant's secrets are encrypted under.
5
+ * Returning `undefined` uses the ring's default key and produces legacy,
6
+ * untagged `enc:v1:` ciphertext — byte-compatible with the single-key adapter.
7
+ *
8
+ * The canonical use: tag rows owned by the control plane tenant with a
9
+ * control-plane-only key id, so the same database can hold a tenant's own
10
+ * secrets (default key) alongside inherited control plane secrets the tenant
11
+ * operator cannot decrypt.
12
+ */
13
+ export type EncryptKeyIdResolver = (tenantId: string) => string | undefined;
14
+ interface EncryptionOptions {
15
+ resolveEncryptKeyId?: EncryptKeyIdResolver;
16
+ }
2
17
  /**
3
18
  * Wraps a DataAdapters instance so that sensitive credential fields are
4
19
  * transparently encrypted on write and decrypted on read. Only the adapters
@@ -16,3 +31,28 @@ import { DataAdapters } from "@authhero/adapter-interfaces";
16
31
  * Private keys (keys.pkcs7, dkim_private_key) are intentionally NOT covered.
17
32
  */
18
33
  export declare function createEncryptedDataAdapter(data: DataAdapters, key: CryptoKey): DataAdapters;
34
+ /**
35
+ * Like {@link createEncryptedDataAdapter}, but encrypts each tenant's secrets
36
+ * under a key selected from a {@link KeyRing}. On read, the key is chosen from
37
+ * the id embedded in the ciphertext, so a single database can mix values
38
+ * encrypted under different keys.
39
+ *
40
+ * `options.resolveEncryptKeyId(tenantId)` decides which key id new ciphertext is
41
+ * tagged with. Return `undefined` for the ring's default key (legacy untagged
42
+ * form). The intended use is to tag control plane tenant rows with a
43
+ * control-plane-only key id so an inheriting tenant can hold the inherited
44
+ * secrets at rest without being able to decrypt them.
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const adapters = createEncryptedDataAdapterWithKeyRing(base, {
49
+ * default: tenantKey,
50
+ * keys: { cp: controlPlaneKey },
51
+ * }, {
52
+ * resolveEncryptKeyId: (tenantId) =>
53
+ * tenantId === CONTROL_PLANE_TENANT_ID ? "cp" : undefined,
54
+ * });
55
+ * ```
56
+ */
57
+ export declare function createEncryptedDataAdapterWithKeyRing(data: DataAdapters, ring: KeyRing, options?: EncryptionOptions): DataAdapters;
58
+ export {};
@@ -1,3 +1,5 @@
1
1
  export * from "./cache";
2
- export { createEncryptedDataAdapter } from "./createEncryptedDataAdapter";
3
- export { loadEncryptionKey, encryptField, decryptField, isEncrypted, } from "../utils/field-encryption";
2
+ export { createEncryptedDataAdapter, createEncryptedDataAdapterWithKeyRing, } from "./createEncryptedDataAdapter";
3
+ export type { EncryptKeyIdResolver } from "./createEncryptedDataAdapter";
4
+ export { loadEncryptionKey, encryptField, decryptField, encryptFieldWithRing, decryptFieldWithRing, parseKeyId, isEncrypted, } from "../utils/field-encryption";
5
+ export type { KeyRing } from "../utils/field-encryption";