UsefulKey

HTTP

Call out to an external HTTP API to persist and read keys.

Overview

  • Delegates CRUD to a remote HTTP API with configurable routes, headers, and auth.
  • Can transform payloads with serializeRecord/deserializeRecord to fit your API.

Usage

import { HttpKeyStore, usefulkey } from "betterkey";

const keyStore = new HttpKeyStore({
  baseUrl: process.env.KEY_API_URL!,
  apiKey: process.env.KEY_API_TOKEN!,
  headers: { "X-Service": "usefulkey" },
  request: { timeoutMs: 10000 },
  apiKeyHeader: { header: "X-API-Key" },
  routes: {
    createKey: "/v1/keys",
    findKeyById: (id) => `/v1/keys/${id}`,
    findKeyByHash: (hash) => `/v1/keys/by-hash/${hash}`,
    updateKey: (id) => `/v1/keys/${id}`,
    revokeKeyById: (id) => `/v1/keys/${id}/revoke`,
    hardRemoveKeyById: (id) => `/v1/keys/${id}`,
  },
  serializeRecord: (r) => ({ ...r, metadata: r.metadata ?? {} }),
  deserializeRecord: (p) => p as any,
  revokeMethod: "PATCH",
});

const uk = usefulkey({ adapters: { keyStore } });

Default endpoints

  • POST /keys
  • GET /keys/:id
  • GET /keys/by-hash/:keyHash
  • PUT /keys/:id
  • POST /keys/:id/revoke
  • DELETE /keys/:id
  • GET /keys/expired?olderThan=:ms&limit=:n

Override via routes and customize headers or auth.

Options

OptionTypeDefaultDescription
baseUrlstringBase URL of your key API.
apiKeystringSecret used to authenticate requests. Sets Authorization: Bearer <apiKey> unless overridden.
headersRecord<string,string>{}Extra headers sent with every request.
request.timeoutMsnumber10000Per-request timeout in milliseconds (0 disables).
request.headersRecord<string,string>{}Additional default headers. Merged with headers.
apiKeyHeader{ header: string; scheme?: string }Authorization: BearerAlternate header for apiKey, e.g. { header: "X-API-Key" }.
routesPartial<HttpKeyStoreRoutes>REST defaultsOverride endpoint paths.
serializeRecord(record: KeyRecord) => unknownidentityTransform record before sending.
deserializeRecord(payload: unknown) => KeyRecordcastTransform response into KeyRecord.
revokeMethod`'POST''PATCH'`POST