Skip to main content
The Confidence Cloudflare resolver enables feature flag evaluation at the edge using Cloudflare Workers. Built on the Confidence Resolver, a Rust-based resolver, it evaluates flags as close to your users as possible. You can then use the Confidence SDKs to resolve from the Cloudflare resolver, either via service binding or regular calls from clients.

Features

  • Edge evaluation: Flag rules evaluate at Cloudflare’s edge locations worldwide
  • Ultra-low latency: Evaluation happens close to users, minimizing latency
  • Rust-based resolver: High-performance flag evaluation powered by the Confidence Resolver
  • Deployer-driven sync: Run the deployer to fetch the latest flag rules from Confidence and re-deploy the Worker

Service binding vs HTTP calls

When integrating with the Cloudflare resolver, you have two options for how your services communicate with it: Service binding (recommended): Cloudflare’s service bindings allow Workers to call other Workers directly within Cloudflare’s network. This internal routing bypasses the public internet, resulting in ultra-low latency. Use service bindings when your application runs on Cloudflare Workers. HTTP calls: Standard HTTP requests to the resolver endpoint. This involves normal network routing with typically higher latency. Use this approach when calling from external services or client applications. For the best performance in Cloudflare-based architectures, configure service bindings between your application Worker and the Confidence resolver Worker.

Deployment

The Cloudflare resolver is deployed using a Docker-based deployer that handles building and publishing the Worker to your Cloudflare account.

Prerequisites

  • Docker installed
  • Cloudflare API token with the following permissions:
    • Account > Workers Scripts > Edit
    • Account > Workers Queues > Edit (needed for the first deploy)
  • Confidence client secret (must be type BACKEND)

Deploy to Cloudflare

On the first deploy, create the required Cloudflare Queue:
CLOUDFLARE_API_TOKEN='your-cloudflare-api-token' npx wrangler queues create flag-logs-queue
Then run the deployer image with your credentials:
docker run -it \
    -e CLOUDFLARE_API_TOKEN='your-cloudflare-api-token' \
    -e CONFIDENCE_CLIENT_SECRET='your-confidence-client-secret' \
    ghcr.io/spotify/confidence-cloudflare-deployer:latest
The deployer automatically detects:
  • Cloudflare account ID from your API token
  • Resolver state from Confidence CDN
  • Existing deployment to avoid unnecessary re-deploys
The deployer does not poll for changes. Each run fetches the current state from Confidence, deploys the Worker if the state has changed, and then exits. To keep the Worker up to date, run the deployer on a schedule (for example, via a cron job) or trigger it when flag rules or targeting changes are made in Confidence.

Optional configuration

VariableDescription
CLOUDFLARE_ACCOUNT_IDRequired only if API token has access to multiple accounts
CONFIDENCE_RESOLVER_STATE_URLCustom resolver state URL (overrides CDN)
CONFIDENCE_RESOLVER_ALLOWED_ORIGINConfigure allowed origins for CORS
FORCE_DEPLOYForce re-deploy regardless of state changes
NO_DEPLOYBuild only, skip deployment

Using the resolver with service bindings

This section shows how to call the Confidence resolver from your own Cloudflare Worker using a service binding.

Set up the project

npm create cloudflare@latest my-worker
cd my-worker
npm install @spotify-confidence/sdk

Configure the service binding

Add a service binding to your wrangler.json to connect your Worker to the resolver:
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2025-02-04",
  "services": [
    {
      "binding": "ConfidenceBinding",
      "service": "confidence-cloudflare-resolver"
    }
  ]
}

Resolve flags in your Worker

Use the @spotify-confidence/sdk package and route resolve requests through the service binding with fetchImplementation:
import { Confidence } from '@spotify-confidence/sdk';

interface Env {
  CONFIDENCE_CLIENT_SECRET: string;
  ConfidenceBinding: {
    fetch: (request: Request) => Promise<Response>;
  };
}

export default {
  async fetch(request, env, ctx): Promise<Response> {
    const confidence = Confidence.create({
      clientSecret: env.CONFIDENCE_CLIENT_SECRET,
      environment: 'backend',
      fetchImplementation: (req: Request) => env.ConfidenceBinding.fetch(req),
      timeout: 1000,
    });

    const flag = await confidence
      .withContext({ targeting_key: 'user-123' })
      .evaluateFlag('flags/my-flag', {});

    return new Response(JSON.stringify({ flag }), {
      headers: { 'Content-Type': 'application/json' },
    });
  },
} satisfies ExportedHandler<Env>;
  • fetchImplementation routes resolve requests through the service binding instead of the public internet.
  • environment: 'backend' is required for server-side usage.
  • withContext() passes your evaluation context for flag targeting.
The Cloudflare resolver also works with the @spotify-confidence/openfeature-server-provider, if you prefer using the OpenFeature API.

Deploy

npx wrangler deploy

Limitations

  • Sticky assignments: Not currently supported with the Cloudflare resolver. Flags with sticky assignment rules will return “flag not found”.

Resources