Cloudflare Tunnel alternative

The open source, self-hosted alternative to Cloudflare Tunnel

Octelium is a free and open source, self-hosted zero trust access platform. A resource behind NAT is served to the Cluster over an outbound tunnel from a connected client, so it can be reached privately or published to the internet without an inbound port, on infrastructure you operate end to end.

  • Free and open source
  • No inbound ports
  • Runs on your own infrastructure
service-remote.yaml
A resource behind NATThe upstream address is resolved from the side of a connected host, so no port is opened.
A resource behind NAT. The upstream address is resolved from the side of a connected host, so no port is opened.
kind: Service
metadata:
  name: app
spec:
  mode: HTTP
  isPublic: true
  config:
    upstream:
      url: http://localhost:3000
      user: laptop
Public anonymous hosting. Anonymous access publishes a resource to the internet with authorization switched off.
kind: Service
metadata:
  name: docs
spec:
  mode: HTTP
  isPublic: true
  isAnonymous: true
  config:
    upstream:
      container:
        port: 8080
        image: ghcr.io/acme/docs:2.1.0
A Policy. For everything that is not anonymous, each request is authorized on its own.
kind: Policy
metadata:
  name: team
spec:
  rules:
    - effect: ALLOW
      condition:
        all:
          of:
            - match: ctx.user.spec.type == "HUMAN"
            - match: '"team" in ctx.user.spec.groups'
service-remote.yaml
From a laptop or a containerA connected client serves the upstream over its own outbound tunnel, with no inbound port.
From a laptop or a container. A connected client serves the upstream over its own outbound tunnel, with no inbound port.
kind: Service
metadata:
  name: app
spec:
  mode: HTTP
  isPublic: true
  config:
    upstream:
      url: http://localhost:3000
      user: laptop
Not only HTTP. Generic TCP and UDP are covered, alongside SSH, databases, Kubernetes and DNS.
kind: Service
metadata:
  name: nats
spec:
  mode: TCP
  port: 4222
  config:
    upstream:
      url: tcp://10.0.7.11:4222
Hosted by the Cluster itself. There does not have to be an upstream elsewhere. The Cluster can deploy and serve the app.
kind: Service
metadata:
  name: web
spec:
  mode: WEB
  isPublic: true
  config:
    upstream:
      container:
        port: 3000
        image: ghcr.io/acme/web:1.2.0
        replicas: 3
policy-http.yaml
The request itselfMethod, path, headers and serialized JSON body are all part of the request context.
The request itself. Method, path, headers and serialized JSON body are all part of the request context.
kind: Policy
metadata:
  name: api-read-only
spec:
  rules:
    - effect: ALLOW
      condition:
        all:
          of:
            - match: ctx.request.http.method == "GET"
            - match: ctx.request.http.path.startsWith("/v1/")
            - match: '"partners" in ctx.user.spec.groups'
Authorized anonymous access. A publicly hosted Service can still filter on path, method, headers and body content.
kind: Service
metadata:
  name: docs
spec:
  mode: HTTP
  isPublic: true
  isAnonymous: true
  config:
    upstream:
      url: http://10.0.6.30:8080
  authorization:
    enableAnonymous: true
    inlinePolicies:
      - spec:
          rules:
            - effect: ALLOW
              condition:
                match: ctx.request.http.method == "GET"
Identity and context. Device posture, session type and group membership are attributes like any other.
kind: Policy
metadata:
  name: sensitive
spec:
  rules:
    - effect: ALLOW
      condition:
        all:
          of:
            - match: ctx.user.spec.type == "HUMAN"
            - match: ctx.session.status.isBrowser
            - match: ctx.device.status.osType in ["MAC", "WINDOWS"]
http-auth.yaml
An upstream API keyThe application behind the tunnel keeps its own credential, and nobody downstream receives it.
An upstream API key. The application behind the tunnel keeps its own credential, and nobody downstream receives it.
kind: Service
metadata:
  name: internal-api
spec:
  mode: HTTP
  isPublic: true
  config:
    upstream:
      url: https://api.internal:8443
    http:
      auth:
        bearer:
          fromSecret: api-key
A database at the other end. A database behind NAT is reached without the password ever leaving the Cluster.
kind: Service
metadata:
  name: pg-edge
spec:
  mode: POSTGRES
  port: 5432
  config:
    upstream:
      url: postgres://pg.home.local
      user: homelab
    postgres:
      user: app
      database: app
      auth:
        password:
          fromSecret: pg-password
A private registry. Deployed containers pull from private registries using credentials held as Cluster Secrets.
kind: Service
metadata:
  name: web
spec:
  mode: WEB
  isPublic: true
  config:
    upstream:
      container:
        port: 3000
        image: ghcr.io/acme/web:1.2.0
        credentials:
          usernamePassword:
            username: ghcr-user
            password:
              fromSecret: ghcr-token
idp.yaml
Secretless workload identityWorkloads authenticate with OIDC assertions issued by the platform running them.
Secretless workload identity. Workloads authenticate with OIDC assertions issued by the platform running them.
kind: IdentityProvider
metadata:
  name: github-actions
spec:
  oidcIdentityToken:
    issuerURL: https://token.actions.githubusercontent.com
    audience: https://example.com
A workload User. The host serving a resource is itself a User, with its own Session and audit trail.
kind: User
metadata:
  name: laptop
spec:
  type: WORKLOAD
  groups:
    - serving
An MCP gateway. An MCP server on a laptop can be published the same way, with tool calls authorized individually.
kind: Service
metadata:
  name: tools-mcp
spec:
  mode: MCP
  isPublic: true
  config:
    upstream:
      url: http://localhost:8080
      user: laptop
    mcp:
      endpoint: /mcp
Visibility and auditing

Real-time visibility at the application layer

OpenTelemetry-ready, application-layer aware, structured auditing and visibility emitted to your OpenTelemetry OTLP receivers, where they can be exported to your log management and SIEM tools.

Read about visibility and auditing
AccessLogOTLP
ALLOWlinus@acme.compg-prod.dbPOSTGRESquery: select id, email from users limit 50
ALLOWci-runnerprod-k8sKUBERNETESverb=list resource=pods namespace=production
DENYagent-07tools-mcpMCPtools/call name=transfer policy=mcp-tools
ALLOWjane@acme.combastionSSHsession recorded, upstream user=deploy
ALLOWagent-07openaiLLMCHAT_COMPLETIONS model=gpt-5-mini tokens=1284
octeliumctl
octeliumctl apply ./cluster
$ octeliumctl apply ./cluster
Secret: ghcr-token Updated
Secret: api-key Updated
IdentityProvider: github Updated
Policy: team Created
Group: team Created
Group: serving Updated
Service: app Created
Service: docs Created
Service: web Created
Namespace: public Created
Cluster Core resources successfully applied
 7 resources created
 3 resources updated

 ClusterConfig updated
Comparison

Octelium and Cloudflare Tunnel, capability by capability

Both products are described from the same structured capability dataset used across this site, with the same evidentiary standard applied to each. Emerging and experimental features are marked as partial regardless of vendor.

Capability comparison

Dataset reviewed August 2026

A curated view of the dataset, weighted here towards tunneling, publishing and hosting. It includes the rows where Octelium is stronger, the rows where it is not, and the rows where the two are equivalent. The complete capability matrix, with search and filters, is one click away.

Architecture

Architecture

Octelium
Kubernetes-native identity-aware proxy/gateway architecture in which policy evaluation is separated from enforcement, with client-based WireGuard/QUIC access, clientless BeyondCorp access, declarative resources, and self-hosted control/data planes.
Cloudflare Access / Tunnel
SaaS edge proxy/SASE architecture. cloudflared connectors and/or WARP clients connect private resources and users to Cloudflare's global network. Access policies apply at Cloudflare-controlled edge/control plane.

Authentication

Anonymous / Public Access

Octelium
Yes
Cloudflare Access / Tunnel
No

Authorization & Policy

Policy-as-Code

Octelium
CEL + OPA
Cloudflare Access / Tunnel
Terraform/API; not a CEL/OPA product-native policy runtime

Per-Request Authz

For L7 products, this means each HTTP/gRPC/API/K8s request can be evaluated. For overlays, session/connection policy is not counted as per-request. This modeling choice structurally favors L7 gateways over network overlays.

Octelium
Yes
Cloudflare Access / Tunnel
For Access-protected HTTP/MCP/web flows; not equivalent for all private network flows

L7-Aware Policies

Octelium
HTTP, gRPC, K8s, DB, SSH, mTLS-related context
Cloudflare Access / Tunnel
Strong HTTP/web policy; not DB/K8s query/verb semantics

L7 Protocol Awareness & Secretless Access

HTTP / HTTPS

Octelium
L7-aware + secretless credential injection
Cloudflare Access / Tunnel
Access / reverse proxy

gRPC

Octelium
Native L7 mode
Cloudflare Access / Tunnel
Transport/web proxy patterns; not general gRPC semantic authz

SSH

Octelium
Secretless / embedded SSH patterns
Cloudflare Access / Tunnel
Browser/CLI access patterns

PostgreSQL

Octelium
Secretless + query-aware policy/logging
Cloudflare Access / Tunnel
Private network/proxy connectivity; not query-aware secretless DB gateway

MySQL

Octelium
Secretless + query-aware policy/logging
Cloudflare Access / Tunnel
Private network/proxy connectivity; not query-aware secretless DB gateway

Kubernetes

Octelium
Secretless + verb/resource/namespace policy
Cloudflare Access / Tunnel
Can protect access paths; not native K8s verb/resource authz gateway

RDP

Octelium
with clientless secretless browser access
Cloudflare Access / Tunnel
Browser-based RDP and client modes

DNS

Octelium
Native private DNS mode
Cloudflare Access / Tunnel
Gateway DNS filtering / private networking DNS patterns

Raw TCP / UDP

Octelium
TCP and UDP
Cloudflare Access / Tunnel
Private network access through WARP/Tunnel

HTTP Manipulation

Octelium
With native plugins including Lua, Envoy ExtProc, JSON schema validation, cache, rate limits
Cloudflare Access / Tunnel
Transform Rules/WAF/Workers depending on product composition

Transport & Networking

WireGuard Data Plane

Whether the product's own client/data plane is built on WireGuard, versus a proprietary or TLS-based transport.

Octelium
Kernel / userspaceWireGuard via kernel module, TUN, or unprivileged userspace (wireguard-go) implementations.
Cloudflare Access / Tunnel
WARPWARP uses a WireGuard-derived transport (BoringTun) alongside MASQUE/HTTP3; not a standard WireGuard mesh.

QUIC Transport

Product-native QUIC transport/tunneling. Experimental or internal-only QUIC is marked partial.

Octelium
Full QUIC-based tunneling mode
Cloudflare Access / Tunnel
QUIC / HTTP3 / MASQUEQUIC and HTTP/3 are first-class across Cloudflare's edge and WARP transport.

IPv6 Support

Octelium
Dual-stackDefaults to IPv6, with selectable IPv4-only or dual-stack cluster network ranges.
Cloudflare Access / Tunnel
Yes

NAT Traversal

Octelium
Via GatewaysReaches resources behind NAT through Cluster Gateways; client-to-Gateway path rather than a direct P2P mesh.
Cloudflare Access / Tunnel
PartialEdge-terminated through Cloudflare's network, not a P2P data path.

Visibility, Auditing & Observability

OpenTelemetry-Native

Octelium
Yes
Cloudflare Access / Tunnel
No

L7-Aware Access Logs

Octelium
HTTP/gRPC/K8s/DB/SSH identity-aware logs
Cloudflare Access / Tunnel
HTTP/access/gateway logs; not DB query logs

SSH Session Recording

Octelium
Yes
Cloudflare Access / Tunnel
No

SIEM Integration

Octelium
Via OTLP / OTel Collector
Cloudflare Access / Tunnel
Logpush / SIEM integrations

Access Methods

Client-Based VPN / Overlay

Octelium
WireGuard / QUIC
Cloudflare Access / Tunnel
WARP client

Clientless Browser Access

Octelium
Yes
Cloudflare Access / Tunnel
Yes

Private DNS

Octelium
Yes
Cloudflare Access / Tunnel
Private DNS/Gateway patterns, not MagicDNS-style product focus

Dynamic Configuration

Dynamic Upstream Routing

Octelium
Yes
Cloudflare Access / Tunnel
Partial

GitOps / Declarative Config

Octelium
Kubernetes-like resources / YAML
Cloudflare Access / Tunnel
Terraform/API

SaaS / Public Cloud API Access

Secretless SaaS API Access

Octelium
Yes
Cloudflare Access / Tunnel
No

AI / MCP / Agent Compatibility

Deploy Containers / PaaS

Octelium
Yes
Cloudflare Access / Tunnel
No

Gateway Capabilities

API Gateway

Octelium
Rate limit, cache, schema validation, Lua, ExtProc
Cloudflare Access / Tunnel
WAF/Rules/Workers/API Shield composition

Kubernetes Ingress / Gateway

Octelium
Yes
Cloudflare Access / Tunnel
No

Reverse Proxy / Tunneling

Octelium
Yes
Cloudflare Access / Tunnel
Yes

Scalability & Cloud-Nativeness

Kubernetes-Native

Octelium
Built on Kubernetes
Cloudflare Access / Tunnel
SaaS edge; deploys connectors/operators but not K8s-native product

High Availability

Octelium
K8s-native HA model
Cloudflare Access / Tunnel
Global edge

Openness & Self-Hosting

Fully Self-Hosted

Octelium
Yes
Cloudflare Access / Tunnel
No

Server Code Open Source

Octelium
Yes
Cloudflare Access / Tunnel
No

No Mandatory Proprietary Cloud

Octelium
Yes
Cloudflare Access / Tunnel
No

Data Sovereignty

Octelium
Yes
Cloudflare Access / Tunnel
NoTraffic/control plane depend on Cloudflare's network for core workflows.
Questions

Frequently asked

How does a resource behind NAT get reached without an inbound port?
A Service upstream can be an address that is only reachable from the side of a connected client. That client, running octelium connect with the --serve or --serve-all flag, announces that it is willing to serve the Service, and the Cluster forwards requests to it over the client's own outbound tunnel. Nothing has to be opened on the network the resource sits on, which covers laptops, containers, Kubernetes pods in other clusters, private clouds and IoT devices.
Where does traffic terminate?
On your own Cluster. Octelium is designed for single-tenant self-hosting: the control plane and the data plane both run on Kubernetes that you operate, on the cloud provider or on-premise infrastructure of your choice. There is no vendor edge in the path, and no third party terminates TLS for your traffic.
Can it host something publicly, not just protect it?
Yes. A Service can be published anonymously, which switches off authentication and authorization for that Service and makes it an ordinary public endpoint, suitable for a website or a public API. Anonymous authorization can then still be enabled, so the Service can filter on path, method, headers, query parameters and body content while remaining publicly reachable.
Is it only for HTTP?
No. Alongside HTTP, WEB and gRPC, a Service can run in SSH, PostgreSQL, MySQL, Kubernetes, DNS, SOCKS5, browser-based RDP, MCP and LLM modes, or in generic TCP and UDP mode for anything else. The application-layer modes add per-request authorization, secretless upstream credentials and protocol-aware auditing on top of the tunnel.
Does the Cluster need to reach the resource at all?
Not necessarily. Besides serving through a connected client, the Cluster can also deploy the application itself: managed containers run a container image as the Service upstream, scheduled on the Cluster's own data plane nodes, with environment variables from Secrets, replica counts, resource limits, volumes and health probes.
Is Octelium free and open source?
Yes. Octelium is free and open source and is designed for single-tenant self-hosting. There is no proprietary cloud-based control plane, and it is not a limited edition of a separate paid product. An enterprise package is available for organizations that need capabilities such as a web console, SCIM provisioning and secret encryption at rest, and it is free for personal, homelab and evaluation use.
Get started

Deploy Octelium on your own infrastructure in minutes

Free and open source. Self-hosted. No vendor lock-in.