Skip to content
v0.4.1Released November 1, 2026

Cloudflare, managed from Kubernetes

kflare is an open-source operator that manages Cloudflare through custom resources: zones, DNS records, tunnels, Workers and their storage, WAF rules and the Rules products.

Keep Cloudflare's configuration in git next to the workloads it serves, apply it with Helm, Argo CD or Flux like everything else, and kflare keeps Cloudflare matching it.

Kubernetes
1.34 or newer
Helm
3.8 or newer
Images
amd64, arm64
License
MIT
hello.yaml
apiVersion: kflare.dev/v1alpha1
kind: Tunnel
metadata:
  name: hello-tunnel
spec:
  name: hello
  accountRef:
    name: my-account
  credentialsSecretRef:
    name: hello-tunnel-token
---
apiVersion: kflare.dev/v1alpha1
kind: DNSRecord
metadata:
  name: hello
spec:
  zoneRef:
    name: my-zone
  name: hello.example.com
  type: CNAME
  tunnelRef:
    name: hello-tunnel
$ kubectl apply -f hello.yaml
tunnel.kflare.dev/hello-tunnel created
dnsrecord.kflare.dev/hello created
$ kubectl wait --for=condition=Ready dnsrecord/hello
dnsrecord.kflare.dev/hello condition met
  • 20 resource kinds

    DNS, tunnels, Workers, storage, the WAF and Rules

  • Tested live

    Every kind, against a real Cloudflare account

  • Signed releases

    cosign signatures, SBOMs and provenance

  • GitOps-ready

    Installs with Helm, Argo CD or Flux

What it manages

One operator for the Cloudflare you already use

20 kinds in kflare.dev/v1alpha1, across DNS, tunnels, Workers and their storage, security and the Rules products. Grant a token only the permissions of the kinds you use.

Accounts

  • CloudflareAccount

    The credentials every other resource uses, cluster-scoped

DNS

  • Zone

    A zone, created or adopted, with its name servers and status

  • DNSRecord

    A DNS record, or a hostname pointed at a Tunnel

Tunnels

  • Tunnel

    A Cloudflare Tunnel, its token written to a Secret for cloudflared

  • TunnelConfiguration

    A tunnel's routes, from hostname to Service

Workers and storage

  • WorkerScript

    A Worker, from inline code or a ConfigMap, with its bindings

  • WorkerRoute

    A route from a URL pattern to a Worker

  • KVNamespace

    A Workers KV namespace

  • R2Bucket

    An R2 bucket; kflare never deletes its objects

  • D1Database

    A D1 database

Security

  • WAFCustomRule

    One WAF custom rule in a zone

  • RateLimitRule

    One rate limiting rule in a zone

  • ManagedRuleset

    A managed ruleset deployed to a zone, with overrides

  • IPList

    An IP list that rule expressions use as $name

Rules

  • TransformRule

    One URL rewrite or header transform rule

  • RedirectRule

    One single redirect

  • CacheRule

    One cache rule

  • ConfigurationRule

    One configuration rule: SSL mode, security level and more

  • OriginRule

    One origin rule: the origin's destination port

Zone settings

  • ManagedTransform

    A zone's managed transforms, the headers Cloudflare adds or removes

How it behaves

Built for platform teams

kflare shares the Cloudflare account with the people and tools already using it, and runs like the rest of your cluster.

Never takes over what it didn't create

Nobody starts with an empty Cloudflare account. An existing object is used only when its resource asks, with the kflare.dev/adoption-policy annotation. Otherwise the resource reports AlreadyExists and changes nothing.

Deletion is deliberate

Deleting a resource deletes what kflare created and keeps what it adopted. kflare.dev/deletion-policy keeps any object, for zones and storage that must outlive a manifest.

References, not copied IDs

Resources point at each other by name. A DNS record follows its tunnel when the tunnel is recreated with a new ID, and resources can be deleted in any order: parents wait for the ones that need them.

One Ready condition says why

Every resource reports a single Ready condition with a reason, and records each change as a Kubernetes Event. kubectl describe names the missing Secret or the permission Cloudflare refused.

A platform component like any other

Install it with Helm, Argo CD or Flux. The chart manages the CRDs and runs under the restricted Pod Security Standard, with leader election, standby replicas, a PodDisruptionBudget and metrics over HTTPS.

Teams manage their own

API tokens stay in Secrets, so External Secrets Operator and Sealed Secrets work, and a rotated token is picked up straight away. Only cluster admins create accounts; the namespaced kinds join the built-in edit and admin roles.

Pause for an incident

Annotate a resource with kflare.dev/paused: "true" and kflare leaves its Cloudflare object alone, for an incident or a migration done by hand, until the annotation is removed.

Drift put back

A change made in the Cloudflare dashboard is put back on the next reconcile. By default that can be hours away; the chart's driftCheckInterval checks every resource on a schedule.

Signed releases

The image and the Helm chart are signed with cosign, keyless, and the image ships with SBOMs and provenance, so an admission policy or Flux can verify them before they run.

Get started

A Service on the internet in four steps

The quickstart puts a demo Service on hello.your-domain.com through a Cloudflare Tunnel, with no public IP, load balancer or open inbound port. You need a domain on your Cloudflare account.

  1. Create an API token

    In the Cloudflare dashboard, create a token with these permissions, the zone ones limited to your domain:

    • Account · Account Settings · Read
    • Account · Cloudflare Tunnel · Edit
    • Zone · Zone · Read
    • Zone · DNS · Edit

    Note your account ID, shown on the account's overview page.

  2. Install kflare

    The Helm chart installs the CRDs and the controller, which runs under the restricted Pod Security Standard.

    Install the chart
    helm install kflare oci://ghcr.io/jonathangraniero/charts/kflare \
      --version 0.4.1 --namespace kflare-system --create-namespace
    kubectl -n kflare-system rollout status deployment/kflare
  3. Connect your account

    The token goes in a Secret, and a cluster-scoped CloudflareAccount points at it. Every other resource refers to the account by name.

    Point kflare at the token
    kubectl -n kflare-system create secret generic cloudflare-token \
      --from-literal=CF_API_TOKEN=<your API token>
    
    kubectl apply -f - <<'EOF'
    apiVersion: kflare.dev/v1alpha1
    kind: CloudflareAccount
    metadata:
      name: my-account
    spec:
      accountID: <your account ID>
      tokenSecretRef:
        name: cloudflare-token
        namespace: kflare-system
    EOF
  4. Expose a Service

    The example holds a demo app, a Zone that adopts your domain, a Tunnel, its TunnelConfiguration, a DNSRecord pointing hello at the tunnel, and the cloudflared Deployment that connects it.

    Deleting the namespace deletes the record and the tunnel, and keeps your zone, because kflare adopted it rather than creating it.

    Apply the example
    curl -sSL https://raw.githubusercontent.com/JonathanGraniero/kflare/v0.4.1/examples/expose-a-service/expose-a-service.yaml \
      | sed 's/example\.com/your-domain.com/g' | kubectl apply -f -
    
    kubectl -n kflare-example wait --for=condition=Ready dnsrecords.kflare.dev/hello --timeout=5m
    curl https://hello.your-domain.com

The full quickstartRunning kflare in production

How it's built

Tested against the real Cloudflare API

kflare is developed with AI assistance (Claude Code). This is what keeps it honest.

Live end-to-end tests

A suite in GitHub Actions runs every resource kind against a real Cloudflare account on the Free plan, and checks Cloudflare's copy after each step. Its token holds only the permissions the deploy guide lists.

Mutation testing

Deliberate bugs are injected into the controllers, and the tests have to catch every one.

Fuzz tests

On the code that reads input kflare doesn't control: the metrics endpoint's authentication and the reading of Cloudflare's errors.

Cloudflare checked first

What the API accepts, refuses and stores is probed live before code relies on it, and recorded in ARCHITECTURE.md.

Known vulnerabilities checked

The code and the image are scanned on every pull request, and the latest release's image every week.

OpenSSF Scorecard

The repository's security practices are scored by the Open Source Security Foundation's Scorecard.

What was verified, and known limitationsOpenSSF ScorecardSecurity policy

Roadmap

Where it's going

kflare is in alpha: its API is v1alpha1, and fields can still change between releases. What people ask for decides the order of what comes next.

In the next release

Merged since v0.4.1

  • Each API token kept within Cloudflare's rate limit, so an account past its limit holds up no other
  • Accounts that limit which namespaces may use them
  • Health checks for Argo CD and Flux, so an application turns Degraded when Cloudflare refuses a resource
  • kflare's own metrics: calls to Cloudflare, readiness and drift, with the cf-ray ID of each failure
Changelog

Next

More of Cloudflare that a Free account can use and test

  • Zone settings: SSL mode, Always Use HTTPS, minimum TLS version and HSTS
  • Queues and Vectorize indexes for Workers
  • Turnstile widgets, with the widget's secret written to a Secret
  • Workers custom domains, next to WorkerRoute
  • Hyperdrive connections, with the database password read from a Secret
  • Bulk redirects
  • Managed ruleset exceptions
The full roadmap