---
title: "API Key Management"
description:
  "Hashed-at-rest, edge-replicated API keys with self-serve issuance, rolling
  rotation, custom metadata, and GitHub leak detection — validated in
  single-digit milliseconds across 300+ data centers."
canonicalUrl: "https://zuplo.com/features/api-key-management"
sourceUrl: "https://zuplo.com/features/api-key-management"
pageType: "feature"
generatedAt: "2026-10-08"
---

# Stripe-quality API keys, fully managed

> Building API keys yourself means owning issuance, rotation, leak response, and
> validation forever. Give customers secure, self-serve keys — issued, rotated,
> and validated for you — with no key service to operate.

## Why this matters: hand-rolled API key services age badly

Every API team builds an API key system. Every one of them is incomplete in a
different place — leak detection, rotation, edge validation, self-serve, audit.
The fast path forward is to stop building and start using one that already does
all of it.

- **Auth service nobody asked you to build** — Hashing, rotation, storage,
  validation — all the parts of an API key system you'd rather not own. So your
  homegrown version skips one of them, and the postmortem references it by name.
- **Customers waiting on you to issue keys** — Every signup is a Slack ping, a
  back-and-forth, a key emailed in plaintext. Sales-led when it should be
  self-serve. Trial users abandon before you respond.
- **Keys leaked, no one notices** — A customer commits a key to a public repo.
  You find out three months later from a Stripe dispute or a usage spike. By
  then, the bot has been at it for a while.
- **Key rotation = scheduled downtime** — Rolling a key means every customer
  needs to update their integration the same day. So you don't rotate. So when a
  leak happens, you're rotating in production at 3am.

## A complete API key service, on day one

- **Edge-fast validation** — Format check + checksum validate in microseconds
  with no network call. Cache hits land in single-digit ms in the same data
  center as the request. The slow path — first call, fresh cache — is still
  under 50ms.
- **Self-serve, branded** — Customers create, view, roll, and delete their own
  keys via the included developer portal — or embed the open-source React
  component in your own app for a fully branded flow. Your team stops being the
  bottleneck.
- **Leak detection on every plan** — Zuplo is a GitHub secret-scanning partner.
  Committed `zpka_` keys are auto-detected and flagged within minutes — you get
  the key, the repo, the commit. One click revokes and rolls.

## Single-digit-ms validation — and a leak alert before the breach

Format check, checksum validation, edge cache lookup, key service — in that
order. Garbage strings reject in microseconds without touching a database. Cache
hits land in milliseconds in the same data center. Leaked keys get flagged by
GitHub before the attacker does anything with them.

Validation pipeline (`zpka_xxx_yyy`), average 5ms:

| Stage       | Time   | Detail                    |
| ----------- | ------ | ------------------------- |
| Format      | 0.1 ms | `zpka_` prefix verified   |
| Checksum    | 0.2 ms | instant validation, no DB |
| Edge cache  | 1.2 ms | TTL 60s, same data center |
| Key service | 4.8 ms | globally replicated       |

- 300+ edge data centers
- GitHub partner for leak detection
- Roll key API, no downtime

## Three ways to put keys in your customers' hands

Use the included developer portal for instant self-serve, embed the open-source
React component in your own dashboard, or call the Developer API for fully
programmatic issuance. All three flow through the same hashed-at-rest,
edge-replicated key store.

Issue a consumer + key with the Developer API:

```bash
curl -X POST "https://dev.zuplo.com/v1/accounts/$ACCOUNT/key-buckets/$BUCKET/consumers?with-api-key=true" \
  -H "Authorization: Bearer $ZUPLO_DEVELOPER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "acme",
    "description": "Acme Corp production",
    "metadata": { "plan": "pro", "orgId": 456 },
    "tags": { "externalId": "cust_abc" }
  }'
```

Roll key with a 7-day grace period:

```bash
curl -X POST "https://dev.zuplo.com/v1/accounts/$ACCOUNT/key-buckets/$BUCKET/consumers/$CONSUMER/keys/roll" \
  -H "Authorization: Bearer $ZUPLO_DEVELOPER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "expiresOn": "2026-05-13T00:00:00Z"
  }'
# New key minted, old keys expire on the date.
# Both keys validate during the transition window.
```

Key format: `zpka_<random>_<checksum>`

- Custom metadata per consumer
- Tags for management filtering
- Buckets shared across projects
- Open-source React component
- Auth0 / Okta / Clerk auto-provision

[Read the Developer API Docs](https://zuplo.com/docs/articles/api-key-api)

## The key isn't just authentication — it's identity context

Attach plan, tenant, partner ID, allowed regions — anything you need — to a
consumer when you issue the key. Read it on every request via
`request.user.data`. Inject it into rate limits, monetization meters, custom
authorization, observability tags, and backend headers — without a second
database call.

Per-partner authorization custom policy (partner key has metadata
`{ partnerId, allowedStores }`):

```ts
export default async function (request, context) {
  const { partnerId, allowedStores } = request.user.data;
  const requestedStore = request.params.storeId;

  if (!allowedStores.includes(requestedStore)) {
    return new Response("Forbidden", { status: 403 });
  }

  // Forward partner identity to backend
  request.headers.set("x-partner-id", partnerId);
  return request;
}
```

Issue a partner key with authorization context:

```bash
curl -X POST "https://dev.zuplo.com/v1/.../consumers?with-api-key=true" \
  -H "Authorization: Bearer $ZUPLO_DEVELOPER_API_KEY" \
  -d '{
    "name": "acme-partner",
    "metadata": {
      "partnerId": "acme",
      "plan": "enterprise",
      "allowedStores": ["sf", "nyc", "lon"],
      "tenantId": "t_842"
    }
  }'
```

- Read on every request via `request.user.data`
- Drives custom RBAC and authorization
- Per-tenant rate limits and quotas
- Forward to backend as trusted headers
- Tag every log line with the consumer
- Update metadata, no key rotation

## Built like a key service, runs like a gateway

- **GitHub leak detection by default** — Zuplo is an official GitHub
  secret-scanning partner. The `zpka_` prefix and checksum let committed keys be
  detected and reported automatically — every plan, no opt-in. Custom enterprise
  key formats trade this off.
- **Roll key with grace period** — POST one endpoint, get a new key minted, and
  have an `expiresOn` date stamped on every existing key. Both work during the
  window. Customers migrate when they're ready. Zero downtime, zero scripting.
- **Edge replication, no central DB** — Keys validate at 300+ data centers in
  single-digit ms because the result is cached locally. The key service itself
  is globally replicated, so even cache misses don't cross continents. Billions
  of validations per day, low-latency worldwide.
- **Rich metadata, full Management API** — Attach arbitrary JSON to each
  consumer (plan, tenant, customer ID); read it on every request via
  `request.user.data`. Or use tags for management-only filtering. The Developer
  API exposes Buckets / Consumers / API Keys for issuance, querying, rotation,
  and revocation.

## What teams use this for

> "We want self-serve trial keys without a sales conversation."

Stand up the included developer portal, point it at your Auth0 (or any IdP).
Customers sign up, click "Create key," and they're calling your API in 60
seconds — with `metadata.plan = "trial"` attached so your rate-limit policy
throttles them appropriately.

> "A customer just leaked a key on GitHub. What now?"

You'll know first — Zuplo's GitHub secret-scanning integration alerts you with
the key and the public repo URL. POST to the roll endpoint to mint a fresh one
and put a 7-day expiry on the leaked key. Customer updates on their schedule;
the leaked key stops working when the window closes.

> "Each B2B partner can only access their own subset of stores."

Stash the partner's allowed store IDs on the API key as metadata
(`{ partnerId: "acme", allowedStores: ["sf", "nyc"] }`). A short custom policy
reads `request.user.data` and rejects any path or query that asks for a store
outside the list. No extra lookup, no second auth call — the key is the
authorization context.

> "Backend needs to know who's calling, without a second auth round-trip."

The gateway already validated the key. Forward the consumer ID, plan, and any
metadata you need as headers (`x-consumer-id`, `x-plan`, `x-tenant`) before the
request hits your origin. Your backend trusts the gateway, not the public
network — no second JWT verification, no shared database lookup.

## Frequently Asked Questions

### How do API keys work?

An API key is a long, random string a client sends with every request to
identify itself. The gateway validates the key, looks up which customer it
belongs to, checks what they're allowed to do, and forwards the request — or
rejects it. Zuplo handles all of this at the edge in single-digit milliseconds,
with the key hashed at rest and validated globally across 300+ data centers. You
get the developer-friendly experience of Stripe-style keys without operating a
key service yourself.

### What's the best way to manage API keys for customers?

Customers should manage their own keys — issuing, rotating, and revoking —
without filing a support ticket. Zuplo gives you three options: the included
developer portal (drop-in self-serve UI), an open-source React component you
embed in your existing dashboard, or a Management API for fully programmatic
control. All three flow through the same hashed-at-rest, edge-replicated key
store. Your support team stops being a key vending machine.

### How do I rotate an API key without breaking customer integrations?

Use a grace-period rotation: mint a new key, set an expiry on the old one, and
let both work during the transition window. Customers update on their own
schedule and the old key stops working at the deadline. Zuplo's roll endpoint
does this with one API call — your customers never see downtime, and you don't
need a one-off migration script. The whole flow is also built into the developer
portal so customers can self-rotate.

### How do I detect leaked API keys?

Watch for keys that show up in public repos, log dumps, and pastebins, and
revoke them before someone else uses them. Zuplo is an official GitHub
secret-scanning partner — the moment a Zuplo-issued key is committed to any
public GitHub repo, you get an alert with the key and repo URL. Combine that
with edge-replicated revocation that propagates in seconds, and a leaked key is
contained before it can be exploited.

### How do I attach plan, tenant, or partner info to an API key?

Store it as metadata on the consumer who owns the key. Any JSON works — plan
tier, tenant ID, partner ID, allowed regions, feature flags. On every request,
your gateway policies read the metadata and use it for rate limiting,
monetization meters, RBAC, observability tags, or trusted headers to your
backend. The key isn't just authentication — it's the identity context for
everything downstream.

### How do I let B2B partners issue and manage their own API keys?

Run the Zuplo developer portal on your subdomain (e.g. partners.acme.com) with
your branding and single-sign-on. Each partner organization gets a consumer
record; assign team members as managers and they can self-serve keys for their
org without ever talking to your team. The same key store powers your retail
self-serve users, internal teams, and partner accounts — one source of truth,
three audience experiences.

### Can I use a custom API key format like sk-acme-?

Yes. Zuplo issues keys in a default `zpka_` format (which qualifies for GitHub
leak detection), and Enterprise customers can use a custom prefix and format
that matches their brand. The trade-off: custom formats can't be auto-detected
by GitHub's secret scanner because they don't match the registered partner
pattern. Most teams use `zpka_` for the security upside; some Enterprise
customers run custom formats for white-label reasons.

### What's the best API gateway for self-serve API keys?

Look for hashed-at-rest storage, edge-replicated validation, self-serve
issuance, leak detection, and rich metadata for downstream authorization —
without making you operate a key service. Zuplo is built for this exact shape:
single-digit-ms validation across 300+ POPs, GitHub secret-scanning by default,
an embeddable open-source React component, and a Management API. AccuWeather,
BlockDaemon, and dozens of other API companies run their key program on it.

## Next steps

- [Start for Free](https://portal.zuplo.com/signup) — free Zuplo project, drop
  in `api-key-inbound`, and your customers self-serve their own keys today.
- [Talk to a Solutions Engineer](/schedule-call)
- [Read the docs](https://zuplo.com/docs/articles/api-key-management)
