Problem
The component ships with built-in API key auth (requireApiKey, timing-safe comparison, key storage in config table, key masking in configGetAll). This couples transport security to the analytics engine. Every consumer has different auth needs (Clerk, custom JWT, API keys, none).
Built-in auth is an anti-pattern for reusable Convex components — the consumer should own auth at the HTTP layer.
Solution
Remove from component
requireApiKey() function in http.ts
api_keys config key handling (storage, masking in configGetAll, MUTABLE_CONFIG_KEYS)
timingSafeEqual() utility
- All
requireApiKey calls from HTTP endpoint handlers
Add auth hook
HTTP endpoints become unprotected by default. Consumer wires auth when mounting:
// Consumer's convex/http.ts
import { analytics } from "@vllnt/convex-analytics";
import { requireApiKey } from "@vllnt/convex-api-keys"; // or their own auth
const http = httpRouter();
// Mount analytics routes with consumer-provided auth middleware
analytics.mountRoutes(http, {
auth: async (ctx, request) => {
// Return null if authorized, Response if rejected
return requireApiKey(ctx, request);
},
});
Alternative (simpler, less flexible): expose raw httpAction handlers and let consumer wrap them:
import { trackEndpoint, timeseriesEndpoint } from "@vllnt/convex-analytics/http";
http.route({ path: "/api/analytics/track", method: "POST", handler: withAuth(trackEndpoint) });
Update docs
docs/quick-start.md — remove API key setup, add "bring your own auth" section
docs/api-reference.md — remove x-api-key references, document auth hook
README.md — update REST API section
- Recommend
@vllnt/convex-api-keys as one auth option
Files to change
packages/convex-analytics/src/component/http.ts — remove requireApiKey, timingSafeEqual, all auth calls
packages/convex-analytics/src/component/mutations.ts — remove api_keys from config (if referenced)
packages/convex-analytics/src/component/queries.ts — remove configGetAll key masking
packages/convex-analytics/src/client/index.ts — remove apiKeys from ConvexAnalyticsConfig
docs/ + README.md + llms-full.txt — update auth documentation
Supersedes
Depends on
- Nothing — can be done independently
Blocks
Problem
The component ships with built-in API key auth (
requireApiKey, timing-safe comparison, key storage in config table, key masking in configGetAll). This couples transport security to the analytics engine. Every consumer has different auth needs (Clerk, custom JWT, API keys, none).Built-in auth is an anti-pattern for reusable Convex components — the consumer should own auth at the HTTP layer.
Solution
Remove from component
requireApiKey()function inhttp.tsapi_keysconfig key handling (storage, masking in configGetAll, MUTABLE_CONFIG_KEYS)timingSafeEqual()utilityrequireApiKeycalls from HTTP endpoint handlersAdd auth hook
HTTP endpoints become unprotected by default. Consumer wires auth when mounting:
Alternative (simpler, less flexible): expose raw httpAction handlers and let consumer wrap them:
Update docs
docs/quick-start.md— remove API key setup, add "bring your own auth" sectiondocs/api-reference.md— remove x-api-key references, document auth hookREADME.md— update REST API section@vllnt/convex-api-keysas one auth optionFiles to change
packages/convex-analytics/src/component/http.ts— remove requireApiKey, timingSafeEqual, all auth callspackages/convex-analytics/src/component/mutations.ts— remove api_keys from config (if referenced)packages/convex-analytics/src/component/queries.ts— remove configGetAll key maskingpackages/convex-analytics/src/client/index.ts— remove apiKeys from ConvexAnalyticsConfigdocs/+README.md+llms-full.txt— update auth documentationSupersedes
Depends on
Blocks