Keyring

What is Keyring

Test mode for your API, as one SDK middleware and one dashboard, verified in your own process.

Keyring is everything a public API needs between the key and the handler: test mode, API keys, rate limits, idempotency and usage, as one middleware in your process and one dashboard for you and your customers.

The headline is test mode. 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, and it is what makes Keyring's downtime not your downtime. 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/core, @keyring/cache, @keyring/sdk
Express, Fastify, NestJS, Next.js adapters@keyring/express, @keyring/fastify, @keyring/nest, @keyring/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/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

  • The packages are not on npm. Every adapter installs from a tarball you build from the repository. Start in 5 minutes shows how.
  • 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/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, and the same recipe runs on your own Coolify server.

Where to go next

On this page