Keyring

What is Keyring

Stop rewriting API key management. Keys, rotation, rate limits, idempotency and usage for your public API, plus a real test mode, as one SDK middleware and one dashboard.

Every SaaS that exposes an API, AI-powered or not, ends up rebuilding the same layer: hash and verify keys, rotate them, rate-limit, dedupe retries, and log enough to answer a support ticket. Keyring is that layer as one middleware in your process and one dashboard for you and your customers, plus the two parts that rarely get built: a real test mode and idempotent retries.

A kr_test_ key and a kr_live_ key hit the same endpoint, and the middleware tells your handler which environment it is in and hands it the matching resources. There is no boolean to mis-set: the environment is inside the key's own hashed material.

app.use(
  keyring({ resources: { orders: { live: liveOrders, test: testOrders } } }),
);

app.get('/v1/orders', (req, res) => res.json(req.keyring?.orders));

In your process, never in front of it

Keyring is an SDK, not a gateway or a proxy. Verification is a SHA-256, a map lookup and a constant-time compare against a policy set the SDK keeps in memory and polls every 5 seconds. There is no network call on the request path. Keyring.handle() is synchronous, and so is the policy store underneath it, so a remote lookup on the hot path is not even expressible.

That is the claim the whole architecture protects: verification never leaves your process. A control-plane outage does stop rotations and revocations from landing, and it refuses any request carrying Idempotency-Key unless that mode is set to open. When Keyring is down says exactly what happens then, row by row, including the case that fails open.

What ships today

You getWhere it lives
Test and live keys, verified in-process@keyring-dev/core, @keyring-dev/cache, @keyring-dev/sdk
Express, Fastify, NestJS, Next.js adapters@keyring-dev/express, @keyring-dev/fastify, @keyring-dev/nest, @keyring-dev/next
Rate limits, per key or per tenantOn the policy feed, enforced by the SDK against a central counter
Idempotency with Stripe's semanticsIdempotency-Key, scoped per tenant so rotation cannot double-charge
Rotate with overlap, revoke and waitPOST /v1/keys/:id/rotate, POST /v1/keys/:id/revoke?wait=true
Usage per key and per tenantThe SDK's telemetry batches, the dashboard's charts, GET /v1/keys/:id/usage
An embeddable "Manage API keys" component@keyring-dev/react, talking only to the tenant-scoped embed plane
A hash-chained audit logEvery mutation, written in the same transaction, verifiable from the dashboard's Activity page

The SDK packages are MIT. The control plane, the dashboard and the hashing pepper are closed.

What is not there yet

  • There is no per-request explorer. Usage is per key per day and per tenant per month. Request logs shows exactly what you can see.
  • The edge runtime is refused, not degraded. @keyring-dev/next runs on the Node runtime only, by design.

EU only, in EUR

The hosted control plane runs in the EU. There is no US control plane, no US replica and no US failover. That is architectural, not a deployment option.

Where to go next

On this page