Skip to content

Concepts

The nouns below are in dependency order, and what each one owns decides where a setting lives.

Organisation

A tenant. Owns zones, users and tokens, and may carry a storage quota across all of them. Created by the operator with cdn create org, because there is no self-service signup.

Zone

A zone is the unit of URL, configuration and statistics. Its name is the first path segment of every object in it, and names are global: they are part of a public URL, so two organisations cannot both hold assets.

A zone is one of two kinds. A storage zone holds what you upload to it and is the origin. A pull zone holds nothing of its own: it mirrors an origin you already run, fetching a path the first time someone asks for it and serving the copy until it expires. The names describe where the bytes come from: a storage zone is the right answer for release tarballs you publish, a pull zone for putting a cache in front of a site that already exists.

A zone never changes kind: the two keep their bytes in different places, and switching would strand whichever copy the old kind owned. See Mirroring an origin.

Object

An object is a file inside a storage zone, addressed by path. The database row is the authoritative index (path, size, content type, etag, timestamps, storage key, and any per-object caching override), while S3 holds the bytes.

Objects are not versioned. A PUT to an existing path replaces it and a DELETE removes it; both leave an audit entry.

Token

A machine credential, cdn_<key id>_<secret> on the wire. Only a hash of the secret is stored. The secret is 160 bits from the system RNG, so there is no dictionary to slow down and a password KDF would only add latency to every request.

A token carries:

  • scopes: read, write, delete, purge, stats;
  • an optional zone restriction, limiting it to one zone;
  • an optional path prefix, limiting it to paths under that prefix.

The prefix covers reads and listings as well as writes. A restriction that stopped at writes would let a deploy key for releases/ list every path in the zone anyway, which is a restriction in name only.

Authorization is decided once, at the request boundary, producing a principal the rest of the request can trust.

Cached entry

A cached entry is a file on the local disk plus a metadata sidecar. It is not a database row and not durable: losing the cache directory costs latency, never data. Entries are keyed by zone id, so renaming a zone does not strand its cache.

Stat bucket

A stat bucket is one counter: how much of one path of one zone went out in one period, at hourly or daily granularity. Those dimensions are its identity, so a counter that could exist twice for the same ones would be a lost increment. See Knowing what is downloaded.

Audit entry

An audit entry records who did what, to what, from where. It is append-only and kept a year.

The actor is described as well as referenced: a token that has since been revoked still has to have a name against the entries it left, or the log stops answering the question it exists for. The address recorded is the peer that sent the request, which behind a proxy is the proxy. The client's own address would need a trusted-proxy configuration this service does not have.

Reads are not recorded. That is what the statistics are for, and a log with a line per download is one nobody reads.

Roles

what it may do
member use the zones and tokens of their organisation
owner also invite people, and empty a whole zone's cache
admin Abilian staff; sees every organisation

URL layout

https://cdn.example.com/<zone>/<path>      delivery
https://assets.acme.com/<path>             delivery, via a zone's own hostname
https://cdn.example.com/_/ui/…             the browser UI
https://cdn.example.com/_/api/v1/…         the HTTP API
https://cdn.example.com/_/s3/<zone>/<path> the S3 endpoint
https://cdn.example.com/_/health           the health check

Everything the service exposes for its own sake sits under the reserved /_/ prefix, because the top-level namespace outside it belongs to zone names.