FabricFabricExperiments
Concepts

Manifests and signing

Delivery manifests are signed, versioned, tenant-scoped, and served from Cloudflare KV.

A manifest is the delivery artifact consumed by SDKs. It contains the experiments, variants, audience rules, and execution metadata needed for assignment.

Signing

Manifests are signed with tenant-scoped Ed25519 keys. Public keys are exposed through JWKS:

GET /.well-known/jwks/{orgId}

The Cloudflare manifest worker can proxy JWKS to the API and cache it at the edge.

An unknown organization can return an empty {"keys":[]} set. That response does not establish trust: SDK verification fails closed unless a matching active key validates the manifest or preview token.

The browser and server SDK fetch paths verify all of the following before a manifest can influence assignment:

  • strict delivery schema and supported schema version,
  • tenant, experiment, and variant identifier integrity,
  • unique identifiers, valid references, and weight totals,
  • SHA-256 content hash over the canonical payload,
  • Ed25519 signature against the tenant JWKS,
  • active key status and optional maximum manifest age.

Fetched manifests are verified by default. requireSignedManifest: false is a test-only escape hatch. Direct createClient(manifest, ...) and NodeClient.setManifest() calls are trusted injection boundaries; verify any network-delivered value before using those APIs.

Publishing

The API publishes signed manifests to Cloudflare via:

POST /admin/publish

In staging/production this path is HMAC-protected with timestamp and nonce headers to reduce replay risk. Customer tenants publish with a tenant-specific HMAC provisioned during provider onboarding. A registered tenant cannot fall back to the provider-global HMAC, so a customer release never needs or receives the provider credential.

Revocation

Revoked manifest versions are served from:

GET /.well-known/revocations/{orgId}

The record is JSON with a unique non-negative integer list:

{ "versions": [41, 42] }

Both fetched-manifest SDK paths consult this record on initial load and every refresh, and reject a listed manifestVersion. The edge response uses a 15-second cache TTL with mandatory revalidation, so emergency revocations stop new SDK refreshes within that cache interval. A static origin that returns 404 is treated as having no revocation service; governed deployments should expose the endpoint or pass an explicit manifestRevocationsUrl.

On this page