Keyring

@keyring-dev/fastify

Fastify 5 plugin.

Generated from packages/fastify/src/index.ts and the declarations it exports, by packages/docs/tools/generate-reference.mjs. Every signature below is printed from the source; the prose is the source's own doc comment.
@keyring-dev/fastify is on npm under the MIT license: npm install @keyring-dev/fastify, on Node 22 or later. Questions: hello@keyringdev.com.

Interfaces

KeyringOptions

Re-exported from @keyring-dev/sdk.

export interface KeyringOptions<R extends ResourceMap = ResourceMap> {
    /**
     * A `krsk_` vendor secret key. Never a tenant's `kr_` key.
     * Defaults to `KEYRING_SECRET_KEY`.
     */
    readonly secretKey?: string;
    /** Defaults to `KEYRING_PROJECT_ID`. */
    readonly projectId?: string;
    /**
     * The control plane's URL. No default: pass it, or set `KEYRING_BASE_URL`.
     */
    readonly baseUrl?: string;
    /**
     * Unset means one endpoint serves both environments and routes on the key,
     * which is the shape the docs lead with. Set it only for a deployment that
     * serves one environment and should refuse the other outright.
     */
    readonly env?: Environment;
    /** The tenants this node serves, so the cache is narrowed by tenant rather than by project. */
    readonly tenantIds?: readonly string[];
    readonly maxCachedKeys?: number;
    /**
     * How far the SDK may raise `maxCachedKeys` by itself before it refuses to
     * serve a project that does not fit. `DEFAULT_MAX_AUTO_CACHED_KEYS` (38,000,
     * ~32 MiB of heap on a three-scope, two-rule key; ~46 MiB on a heavier one)
     * unless set, and never below `maxCachedKeys`.
     */
    readonly maxAutoCachedKeys?: number;
    /**
     * What to do when a node that has **never served** finds the project has more
     * live keys than it can cache and no `tenantIds` narrows it.
     *
     * The default throws it, which crashes the process at boot with the actionable
     * message -- that is what "refuse to start" means, and it is deliberate. Such
     * a node can never hold a complete cache, and an incomplete cache under the
     * `stale-then-open` default admits *any* well-formed key, unverified and
     * unscoped, for the life of the process. A deploy that cannot verify keys
     * should not take traffic.
     *
     * It is **not** called on a node that is already serving when its project
     * outgrows the cache. That one keeps serving and keeps polling, reports the
     * same error through `onError` on every poll, and reports
     * `stats().policyCache.scopeTooLarge` -- the readiness predicate to drain it
     * on. Killing it instead is a fleet-wide outage of your own API one vendor
     * `PATCH` away, and stopping its poller is worse still: the node then never
     * learns another revocation.
     *
     * Set this to handle the boot case yourself -- to page, to fail a readiness
     * probe, to exit with your own code. A no-op leaves the node serving on the
     * store it has, which at boot is an empty one: every well-formed key is
     * admitted unverified until the first successful poll, and there will not be
     * one. The fail-open table in the README says what that admits.
     */
    readonly onScopeTooLarge?: (error: PolicyScopeTooLargeError) => void;
    readonly policyRefreshMs?: number;
    readonly maxStalenessMs?: number;
    readonly onUnavailable?: UnavailableMode;
    /**
     * What a request does when the *counter store* cannot be reached, which is
     * a different question from what it does when the *policy* cannot be.
     * `open` by default; see `limits/limiter.ts` for why, and why idempotency's
     * default is the opposite.
     */
    readonly rateLimitOnUnavailable?: RateLimitUnavailableMode;
    /** The legacy pre-standard header triple. On, because clients read it. */
    readonly legacyRateLimitHeaders?: boolean;
    readonly rateLimitTimeoutMs?: number;
    /**
     * `false` disables the feature; an object configures it. Enabled by
     * default -- a mutating request with no `Idempotency-Key` costs nothing,
     * and the header is how a caller opts in.
     */
    readonly idempotency?: boolean | Omit<IdempotencyOptions, 'baseUrl' | 'secretKey' | 'fetch' | 'onError'>;
    readonly routes?: RouteRules;
    readonly scopes?: readonly string[];
    /** Resolved per request from the key's env. */
    readonly resources?: R;
    readonly cacheDir?: string;
    readonly persist?: boolean;
    readonly nodeId?: string;
    /** Set false to send nothing at all. */
    readonly telemetry?: boolean;
    readonly bufferSize?: number;
    readonly flushIntervalMs?: number;
    readonly flushEvents?: number;
    readonly maxEventsPerSecond?: number;
    readonly handleSignals?: boolean;
    readonly lazyFill?: boolean | OnDemandFillOptions;
    readonly sdkName?: string;
    readonly fetch?: FetchLike & ShipperFetch & ControlPlaneFetch;
    readonly onWarn?: (message: string, detail?: unknown) => void;
    /** Injectable so a test can exercise the environment defaults. */
    readonly processEnv?: Record<string, string | undefined>;
    readonly onError?: (error: unknown) => void;
    /** Escape hatch for tests: a store to use instead of the polled cache. */
    readonly store?: PolicyStore;
    readonly now?: () => number;
}

KeyringPluginOptions

export interface KeyringPluginOptions extends Partial<KeyringOptions> {
  /** An already-constructed instance, when one process runs several. */
  readonly instance?: Keyring<ResourceMap>;
}

Types

KeyringContext

Re-exported from @keyring-dev/sdk.

export type KeyringContext<R extends ResourceMap = ResourceMap> = KeyringContextBase & ResolvedResources<R>;

Constants

default

const keyringPlugin: FastifyPluginCallback<KeyringPluginOptions>;

keyringPlugin

const keyringPlugin: FastifyPluginCallback<KeyringPluginOptions>;

On this page