# Scale & the edge

seekrit is globally distributed by construction. Because encryption and decryption are the
client's job, the server never holds anything but ciphertext — and stateless ciphertext storage is
the easiest thing in the world to spread across the planet. There is no region to choose, no
cluster to size, and no secret material to replicate.

## Runs on Cloudflare's edge

The API is a single [Cloudflare Worker](/docs/concepts/architecture) backed by D1, served from
Cloudflare's global network. Requests are handled close to wherever they originate — a laptop in
Berlin, a CI runner in `us-east`, an agent sandbox anywhere — without you provisioning or operating
a thing.

## The hot path: resolving secrets

Every running workload — a container, a CI job, an AI agent — calls `GET /v1/resolve` on startup to
fetch the secrets for its environment. This is by far the busiest route: one organization can drive
tens of thousands of resolves a day. seekrit is built to serve it cheaply and correctly.

The route is split across two roles inside the same Worker:

- A **gateway** that always runs: it authenticates the caller, decides which org and environment are
  in play, and meters the read for usage and billing.
- A **resolver** that owns the cache: it does the database work — gathering the encrypted secret
  layers and the caller's individually-wrapped data key — and caches the result at the edge.

## Caching that stays zero-knowledge

Resolved responses are cached **at the edge**, so repeat boots of the same workload are served
without touching the database. Two properties keep this safe:

- **Only ciphertext is cached.** Encrypted secret values and already-wrapped data keys — never
  plaintext. The zero-knowledge invariant is unchanged: a cache, like the database, holds nothing
  readable.
- **The cache key includes the caller's identity.** A caller's principal, org, environment, and any
  overrides are folded into the cache key. Two principals never share an entry, and no one can be
  served another principal's wrapped key. Identity is verified on every request by the gateway, cache
  hit or miss — it is never bypassed by a warm cache.

> **Note:** A wrapped data key is only useful to the principal it was wrapped for — decrypting it still requires that principal's private key, which never leaves their machine. Edge caching moves ciphertext closer to the caller; it never moves the ability to read it.

## Staying correct: tag-scoped invalidation

Speed is worthless if it serves stale secrets. Each cached response is tagged with every
environment it read (an app environment plus any composed groups). Any change that could alter the
result — writing or rotating a secret, granting or revoking a key, changing composition, deleting an
environment — purges exactly those tags. Unaffected environments keep their warm caches; the ones
that changed are refreshed on the next read. A short backstop lifetime bounds staleness if a purge
is ever missed.

## Metering, not per-read audit

Mutations are always [audited](/docs/concepts/security) synchronously to an append-only trail.
Successful resolves are the deliberate exception: at tens of thousands a day they are **metered** to
an analytics pipeline (fire-and-forget, sampled) for usage and billing rather than written to the
durable audit log. Metadata only — never ciphertext, never plaintext. Denied resolves *are* audited
durably, because those are the security-significant events.

## The bottom line

The same design decision that makes seekrit private — encryption belongs to the client — is what
lets it scale. A stateless, ciphertext-only server distributes trivially across the edge, caches
safely close to your workloads, and grows from a single developer to a fleet of agents with no
infrastructure on your side.
