Skip to content

Allow passing a keyset to encrypt/decrypt operations, not just at init #561

Description

@coderdan

Summary

Today a keyset can only be supplied at client initialization (Encryption({ config: { keyset } })), which binds the client to a single keyset for its lifetime. For multi-tenant applications this forces one Encryption() client per tenant. We should also allow passing a keyset to the individual encrypt / decrypt (and bulk / model) operations, so a single client can operate across keysets.

Motivation

  • Multi-tenant services currently have to build and cache a client per tenant. A per-operation keyset override would let one client serve many tenants.
  • It mirrors how .withLockContext(...) already layers per-operation identity binding on top of a client — a per-operation keyset would be the analogous knob for keyspace selection.

Proposed shape (to be refined)

Allow an optional keyset in the encrypt/decrypt options, overriding the client-level default when present:

await client.encrypt("alice@example.com", {
  column: users.email,
  table: users,
  keyset: { name: "tenant-a" }, // or { id: "<uuid>" }
})

await client.decrypt(ciphertext, { keyset: { name: "tenant-a" } })

Resolution rule: per-operation keyset wins over config.keyset, which in turn falls back to the workspace default.

Scope / things to work through

  • Which operations get it: encrypt, decrypt, encryptQuery, and the bulk / model variants.
  • How it flows through to protect-ffi (init currently maps KeysetIdentifier via toFfiKeysetIdentifier{ Name } | { Uuid }; confirm the FFI encrypt/decrypt calls accept a per-op keyset).
  • UUID validation currently happens once in Encryption(); per-op keysets would need validation at the operation boundary too.
  • Interaction with lock context and authStrategy (should be independent).
  • Docs / TypeDoc updates once implemented.

Context

Came out of the strategyauthStrategy rename + keysets TypeDoc work. The Encryption() TypeDoc now documents keysets as an init-only, one-client-per-tenant concept (packages/stack/src/encryption/index.ts); this issue tracks lifting that restriction.

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions