Cloudflare mutual TLS

Blocked at the edge.
Proven in code.

The public route establishes a baseline. The protected route reaches Hono only when Cloudflare accepts the client certificate and the WAF rule allows the request.

  1. 1
    ClientPresents a certificate or not
  2. 2
    Cloudflare edgeValidates mTLS and evaluates WAF
  3. 3
    Hono WorkerRuns only after edge admission

Test the request path

Each button calls a real route on this Worker using your browser's current TLS session.

GET /api/health

Public baseline

Confirms the hostname and Worker are reachable without proving client identity.

GET /api/mtls

Protected endpoint

No or invalid certificate: WAF blocks. Valid certificate: this Hono route returns JSON.

Select a route to begin

Idle
The HTTP status and response body will appear here.

The complete proof boundary

The Worker stays simple because certificate rejection belongs to Cloudflare's edge.

worker.jsExecutable Hono routes
app.get('/api/health', (c) => {
  return c.json({
    ok: true,
    route: '/api/health',
    message: 'Worker is reachable',
  });
});

app.get('/api/mtls', (c) => {
  return c.json({
    ok: true,
    route: '/api/mtls',
    message: 'Valid client certificate accepted',
  });
});
WAF custom ruleAction: Block
http.host eq "mtls.oskarcode.com"
and http.request.uri.path eq "/api/mtls"
and (
  not cf.tls_client_auth.cert_verified
  or cf.tls_client_auth.cert_revoked
)

You will configure the client CA association and this rule manually. The revoked check matters because Cloudflare documents that a revoked certificate can still have cert_verified set to true.

Use two client contexts

Without a valid certificate

Call /api/mtls. Expect a WAF block and no Hono success JSON.

With the valid certificate

Use a certificate-enabled browser profile or curl --cert --key. Expect HTTP 200.