---
name: bijection-convex-secret-manager
description: "Evaluate and integrate the Secret Manager component with Bijection."
---

# Secret Manager

Convex component for encrypted secret vaults and issued API key lifecycle

This is an upstream package. It has not been adapted or qualified for Bijection.

- Package: convex-secret-manager
- Source: https://github.com/phantasy-bot/convex-secret-manager
- npm: https://www.npmjs.com/package/convex-secret-manager
- Directory: https://bijection.com/components/convex-secret-manager

Read the upstream README for setup, license, and compatibility before using it.

## Integration workflow

1. Read the source README and package manifest at the recorded revision.
2. Confirm the required SDK, dependency availability, and runtime compatibility.
3. Follow the component's documented setup and configuration. Never invent an npm install command from a catalog package name.
4. Keep credentials in the project's existing secret store.
5. Follow the project's execution rules for verification and report what was actually checked.

## Original upstream skill

The following guidance describes convex-secret-manager. Its installation commands and APIs refer to the upstream package. Evaluate compatibility with the Bijection source separately.


> Agents: read this skill fully before writing code that uses Secret Manager. Follow the installation and configuration steps exactly.

# Secret Manager

## Instructions

Use Secret Manager to convex-secret-manager provides encrypted secret vaults and issued api key lifecycle management with per-ownerid multi-tenant tenancy in a single convex component. This Convex component integrates directly with your backend.

### Installation

```bash
npm install convex-secret-manager
```

Current npm version: `convex-secret-manager@0.2.0`

### Capabilities

- Store third-party credentials (OpenAI, webhooks, etc.) encrypted at rest using envelope encryption with KEK rotation support
- Issue and manage machine tokens with hash-only storage, refresh with grace periods, revocation, and paginated audit trails
- Replace two separate gaganref packages with one component that links vault secrets and issued keys under a shared ownerId namespace
- Get built-in hourly sweep crons for expired and idle key cleanup without writing your own scheduled functions

## Examples

### 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.

## When NOT to use

- When a simpler built-in solution exists for your specific use case
- If you are not using Convex as your backend
- When the functionality provided by Secret Manager is not needed

## Troubleshooting

**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.

## Resources

- [npm package](https://www.npmjs.com/package/convex-secret-manager)
- [GitHub repository](https://github.com/phantasy-bot/convex-secret-manager)
- [Live demo](https://github.com/phantasy-bot/convex-secret-manager/tree/main/example)
- [Convex Components Directory](https://www.convex.dev/components/convex-secret-manager)
- [Convex documentation](https://docs.convex.dev)