UsefulKey
Additional info

API Reference

Public exports and method signatures.

Factory

usefulkey(config: UsefulKeyConfig, options?: { plugins?: UsefulKeyPlugin[] }): UsefulKey & PluginExtensions

UsefulKeyConfig highlights:

  • keyPrefix?: string
  • disablePrefix?: boolean
  • defaultKeyKind?: KeyKind
  • adapters?: { keyStore?: KeyStoreAdapter; rateLimitStore?: RateLimitStoreAdapter; analytics?: AnalyticsAdapter }
  • crypto?: Partial<CryptoProvider> | CryptoLike | NodeCryptoLike
  • secret?: string | Uint8Array
  • customHashKey?: (key: string) => string
  • customGenerateKey?: (kind?: KeyKind) => string
  • customIdGenerator?: () => string
  • autoDeleteExpiredKeys?: boolean

Methods

uk.createKey(): Promise<Result<CreateKeyResult>>
uk.createKey(input: CreateKeyInput): Promise<Result<CreateKeyResult>>
uk.verifyKey(input: VerifyOptions, returnMetadata?: boolean): Promise<Result<VerifyResult>>
uk.getKey(key: string): Promise<Result<KeyRecord | null>>
uk.getKeyById(id: KeyId): Promise<Result<KeyRecord | null>>
uk.revokeKey(id: KeyId): Promise<Result<void>>
uk.hardRemoveKey(id: KeyId): Promise<Result<void>>
uk.extendKeyExpiry(id: KeyId, additionalMs: number): Promise<Result<{ expiresAt: number } | null>>
uk.sweepExpired(input?: { batchSize?: number; olderThan?: number; strategy?: "soft_then_hard" | "hard" }): Promise<Result<{ processed: number; revoked: number; hardRemoved: number; remainingHint?: number }>>

All core types and ErrorCodes are exported from the package root. Rate-limit types are also re-exported at the root.

Instance property

uk.ready: Promise<void>

Adapters export

// Import constructors directly from the package root
import {
  ConsoleAnalytics,
  NoopAnalytics,
  // Keystore adapters
  MemoryKeyStore,
  D1KeyStore,
  DrizzleKeyStore,
  HttpKeyStore,
  MysqlKeyStore,
  PostgresKeyStore,
  RedisKeyStore,
  SqliteKeyStore,
  // Rate limit store adapters
  CloudflareKvRateLimitStore,
  MemoryRateLimitStore,
  MysqlRateLimitStore,
  PostgresRateLimitStore,
  RedisRateLimitStore,
  SqliteRateLimitStore,
} from "usefulkey";

Plugins export

// Import plugins directly from the package root
import {
  ratelimit,
  ipAccessControlStatic,
  ipAccessControlMemory,
  usageLimitsPerKeyPlugin,
  enableDisablePlugin,
  permissionsScopesPlugin,
} from "usefulkey";

Utilities

import {
  // Key helpers and hashing
  KEY,
  renderKey,
  hashKey,
  hashKeyWithConfig,
  // Crypto provider configuration
  configureCryptoProvider,
} from "usefulkey";

KEY helpers

Declarative constructors for KeyKind used to render plaintext keys:

  • KEY.UUID(prefix?): UUID v4 with optional custom prefix
  • KEY.URLSafe(length = 32, prefix?): URL-safe alphabet [A-Za-z0-9-_]
  • KEY.HEX(length = 64, prefix?): lowercase hex digits
  • KEY.Base32(length = 26, prefix?): Crockford Base32 [0-9ABCDEFGHJKMNPQRSTVWXYZ]

Examples:

// Generate with a custom default kind
const uk = usefulkey({ defaultKeyKind: KEY.URLSafe(40, "svc") });

// Override kind per-call
await uk.createKey({ keyKind: KEY.UUID("app") });

renderKey(kind, defaultPrefix?, includePrefix?)

Materialize a plaintext key string from a KeyKind.

  • defaultPrefix: used when the kind does not carry a prefix (default: "uk")
  • includePrefix: when false, omits the "prefix_" part entirely
renderKey(KEY.URLSafe(16, "svc"));           // => "svc_X1Y2..."
renderKey(KEY.URLSafe(16), "my", false);     // => "X1Y2..." (no prefix)

Note: When using the class API, the instance respects config.disablePrefix and config.keyPrefix automatically.

hashKey vs hashKeyWithConfig

  • hashKey(key): SHA-256 hash (hex). Useful when you do not need instance-aware behavior.
  • hashKeyWithConfig(key, config): honors config.secret (HMAC-SHA256) and config.customHashKey.
// Basic hashing
const digest = hashKey("plaintext"); // sha256 hex

// Instance-aware hashing (with secret → HMAC-SHA256)
const digest2 = hashKeyWithConfig("plaintext", { secret: "s3cr3t" });

Avoid persisting plaintext keys. Store keyHash instead; the core does this for you when creating keys.

configureCryptoProvider(provider)

Swap hashing and randomness primitives. Accepts one of:

  • NodeCryptoLike: pass Node's crypto (classic or webcrypto)
  • CryptoLike: Web Crypto-like object with getRandomValues and optional randomUUID
  • Partial<CryptoProvider>: override specific functions

Examples:

// Node.js: prefer built-in crypto
import crypto from "node:crypto";
configureCryptoProvider(crypto);

// Edge/runtime with Web Crypto
configureCryptoProvider(globalThis.crypto);

// Partial overrides (tests/dev only)
configureCryptoProvider({
  randomUUID: () => "00000000-0000-4000-8000-000000000000",
});

Important: In production, ensure a secure RNG is available. If getRandomValues is missing and no provider is configured, a non-secure fallback is used only for non-production environments.