Secret Manager

convex-secret-manager provides encrypted secret vaults and issued API key lifecycle management with per-ownerId multi-tenant tenancy in a single Convex componen

Installation

npm install convex-secret-manager

About Secret Manager

Secret Manager is a Convex component that combines encrypted secret vaults and issued API key lifecycle management into a single package with per-ownerId tenancy. The vault module stores third-party credentials encrypted at rest using envelope encryption with KEK rotation support, while the issued keys module handles machine token creation, validation, refresh, revocation, and audit trails. It targets multi-tenant backends where a single owner entity needs to hold both external credentials and issued machine tokens.

Benefits

Use cases

how to store encrypted API keys per tenant in Convex

convex-secret-manager provides a Vault module that stores user-supplied credentials encrypted at rest using envelope encryption with AAD. Secrets are scoped to an ownerId (org, user, or deployment) plus a namespace and name path, making it suitable for multi-tenant SaaS backends. Use vault.putPlaintext to write and vault.getResult to retrieve secrets in a typed ok/error result shape.

how to issue and revoke machine tokens in a Convex app

The issued keys module in convex-secret-manager lets you create sm_ prefixed tokens with issued.create, validate them with a side-effect-free query, and rotate them with issued.refresh using a configurable grace period. Tokens are stored as hashes only, and you can revoke individual keys or all keys for an owner with issued.revoke and issued.revokeAll.

Convex component for multi-tenant secret management with KEK rotation

convex-secret-manager supports envelope encryption with versioned KEKs defined via defineKeys in convex.config.ts. You can run vault KEK rotation using vaultRotate.rotate and check drain progress with isRotationComplete, allowing zero-downtime key rotation across all stored secrets for a given deployment.

single Convex component to replace convex-secret-store and convex-api-keys

convex-secret-manager combines the functionality of gaganref/convex-secret-store and gaganref/convex-api-keys into one package. The key difference is per-ownerId tenancy, meaning both vault secrets and issued machine tokens are scoped to the same owner identifier, which is useful when one entity needs to hold both third-party credentials and issued tokens simultaneously.

Frequently asked questions

What is the difference between convex-secret-manager and the gaganref convex-secret-store and convex-api-keys packages?

convex-secret-manager combines both gaganref packages into one component and adds per-ownerId tenancy so that vault secrets and issued machine tokens share the same owner scope. The gaganref packages use a namespace plus name path model, while convex-secret-manager uses an ownerId plus namespace plus name path. Use convex-secret-manager when a single owner entity needs to hold both third-party credentials and issued API keys.

How does convex-secret-manager handle encryption for stored secrets?

convex-secret-manager uses envelope encryption with versioned Key Encryption Keys (KEKs) defined via the defineKeys helper in your convex.config.ts. Secrets are encrypted at rest with Additional Authenticated Data (AAD). KEK rotation is supported through vaultRotate.rotate and isRotationComplete, allowing you to drain and re-encrypt secrets under a new key version without downtime. A legacy single-key mode is also supported via the SECRET_MANAGER_ENCRYPTION_KEY environment variable.

How are issued API keys stored and validated in convex-secret-manager?

convex-secret-manager stores only the hash of issued sm_ prefixed tokens, never the plaintext. Validation is performed via a query function (side-effect free), which means it can be called without triggering mutations. The issued keys module also supports token refresh with a grace period, individual and bulk revocation, and paginated listing with effectiveStatus.

Does convex-secret-manager handle cleanup of expired secrets and keys automatically?

Yes. convex-secret-manager includes built-in hourly cron jobs that sweep for expired and idle issued keys, as well as expired vault secrets. Internal jobs cleanupKeys and cleanupEvents handle token and audit event cleanup respectively, and vaultCleanup.cleanupSecrets handles expired secret removal. These crons are registered automatically when you install the component.

How do I set up convex-secret-manager in an existing Convex app?

Install the package with npm install convex-secret-manager, then import and register the component in your convex/convex.config.ts using app.use(secretManager) with your KEK material passed via defineKeys. Instantiate SecretManager in a Convex module file by passing components.secretManager, then set the SECRET_MANAGER_KEYS environment variable on your Convex deployment in the format 1:<kek-material>. See the example directory in the GitHub repository for a minimal Convex plus Vite dashboard walkthrough.

Links