new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Better Auth · Plugins · all subjects

api-key/storage

8 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Storage modes for API keys: database, secondary-storage, and fallback

The API key plugin supports three storage modes: "database" (default, stores keys only in the database adapter), "secondary-storage" (stores keys only in secondary storage like Redis with no database fallback), and "secondary-storage" with fallbackToDatabase: true (checks secondary storage first, then database if not found, with automatic cache warming and writes to both layers).

Custom storage methods for API keys

You can provide custom storage methods specifically for API keys via the customStorage option, overriding the global secondaryStorage configuration. The customStorage object has three methods: get(key), set(key, value, ttl), and delete(key). This allows API keys to use different storage than other Better Auth data.

API Key plugin storage option

The storage option specifies the storage backend for API keys. It accepts "database" or "secondary-storage" as values, with default being "database". When set to "database", API keys are stored in the database adapter. When set to "secondary-storage", API keys are stored in the configured secondary storage such as Redis.

API Key plugin fallbackToDatabase option

The fallbackToDatabase option is a boolean that enables fallback to database if key is not found in secondary storage when storage is set to "secondary-storage". The default value is false.

API Key secondary storage key-value patterns

When storage is set to "secondary-storage", API keys are stored using key-value patterns: api-key:${hashedKey} is used for primary lookup by hashed key; api-key:by-id:${id} is used for lookup by ID; api-key:by-ref:${referenceId} is used for the reference's API key list (user or organization). If an API key has an expiration date (expiresAt), a TTL is automatically set in secondary storage to ensure automatic cleanup.

API Key plugin customStorage option

The customStorage option accepts custom storage methods for API keys with three properties: get (function taking a key string and returning Promise<unknown> or unknown), set (function taking key string, value string, and optional ttl number, returning Promise<void|null|unknown> or void), and delete (function taking a key string and returning Promise<void|null|string> or void). If provided, these methods are used instead of ctx.context.secondaryStorage. Custom methods take precedence over global secondary storage.

Secondary storage configuration example for API Key plugin

Example of configuring secondary storage with Redis for API keys: import { betterAuth } from "better-auth"; import { apiKey } from "@better-auth/api-key"; export const auth = betterAuth({ secondaryStorage: { get: async (key) => { return await redis.get(key); }, set: async (key, value, ttl) => { if (ttl) await redis.set(key, value, { EX: ttl }); else await redis.set(key, value); }, delete: async (key) => { await redis.del(key); }, }, plugins: [ apiKey({ storage: "secondary-storage", }), ], });

Custom storage configuration example for API Key plugin

Example of configuring custom storage specifically for API keys: import { betterAuth } from "better-auth"; import { apiKey } from "@better-auth/api-key"; export const auth = betterAuth({ plugins: [ apiKey({ storage: "secondary-storage", customStorage: { get: async (key) => await customStorage.get(key), set: async (key, value, ttl) => await customStorage.set(key, value, ttl), delete: async (key) => await customStorage.delete(key), }, }), ], });

Give your agent this brain