Skip to content

Commit 0517a96

Browse files
StringKeclaude
andcommitted
feat: add Zero Trust CRDs and controllers
Implement comprehensive Cloudflare Zero Trust Kubernetes operator with 18 CRDs: **New CRDs:** - AccessApplication: Zero Trust application definitions - AccessGroup: Reusable access policy groups - AccessIdentityProvider: IdP configurations (OIDC, SAML, GitHub, Azure AD) - AccessServiceToken: Machine-to-machine authentication tokens - VirtualNetwork: Cloudflare virtual networks for traffic isolation - NetworkRoute: IP routes through tunnels to private networks - PrivateService: Expose K8s Services via WARP private IPs - GatewayRule: Gateway DNS/HTTP/network policies - GatewayList: Lists for gateway policy rules - GatewayConfiguration: Global gateway settings - DeviceSettingsPolicy: WARP client settings and split tunnels - DevicePostureRule: Device posture checks for Zero Trust - DNSRecord: DNS record management - WARPConnector: WARP connector deployments **Enhancements:** - Add EnableWarpRouting to Tunnel/ClusterTunnel for private network access - Add cluster-resource-namespace flag with Downward API injection (PR #178) - Store previous-hostnames in TunnelBinding annotation (PR #166) - Fix Secret finalizer order in cleanupTunnel (PR #158) **API Clients:** - Access API: Applications, Groups, Identity Providers, Service Tokens - Gateway API: Rules, Lists, Configurations - Device API: Split Tunnel, Fallback Domains, Posture Rules - Network API: Virtual Networks, Routes - DNS API: Record management 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent da0c5f0 commit 0517a96

72 files changed

Lines changed: 20767 additions & 95 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ GOLANGCI_LINT = $(LOCALBIN)/golangci-lint
215215

216216
## Tool Versions
217217
KUSTOMIZE_VERSION ?= v5.4.3
218-
CONTROLLER_TOOLS_VERSION ?= v0.16.1
218+
CONTROLLER_TOOLS_VERSION ?= v0.17.2
219219
ENVTEST_VERSION ?= release-0.19
220220
GOLANGCI_LINT_VERSION ?= v2.1.5
221221

README.md

Lines changed: 121 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<br />
88

99
<p align="center">
10-
A Kubernetes Operator to create and manage Cloudflare Tunnels and DNS records <br /> for (HTTP/TCP/UDP*) Service Resources
10+
A Kubernetes Operator for Cloudflare Zero Trust: Tunnels, Access, Gateway, and Device Management
1111
<br />
1212
<br />
1313
<a href="https://github.com/adyanth/cloudflare-operator/blob/main/docs/getting-started.md"><strong>Getting Started Guide »</strong></a>
@@ -28,33 +28,136 @@
2828

2929
> **_NOTE_**: This project is currently in Alpha
3030
31-
> UDP*: UDP support for Cloudflare Tunnels is in [Early Access](https://blog.cloudflare.com/extending-cloudflares-zero-trust-platform-to-support-udp-and-internal-dns/)
31+
## Overview
3232

33-
## Motivation
33+
The Cloudflare Operator provides Kubernetes-native management of Cloudflare Zero Trust resources. Built with `operator-sdk`, it enables declarative configuration of tunnels, access policies, gateway rules, and device settings through Custom Resources (CRDs).
3434

35-
The [Cloudflare Tunnels guide](https://developers.cloudflare.com/cloudflare-one/tutorials/many-cfd-one-tunnel) for deployment on Kubernetes provides a [manifest](https://github.com/cloudflare/argo-tunnel-examples/tree/master/named-tunnel-k8s) which is very bare bones and does not hook into Kubernetes in any meaningful way. The operator started out as a hobby project of mine to deploy applications in my home lab and expose them to the internet via Cloudflare Tunnels without doing a lot of manual work every time a new application is deployed.
35+
## Features
3636

37-
## Overview
37+
### Tunnel Management
38+
- **Tunnel / ClusterTunnel**: Create and manage Cloudflare Tunnels with scaled `cloudflared` deployments
39+
- **TunnelBinding**: Automatically configure tunnel ingress rules and DNS records for Services
40+
- **AccessTunnel**: Reference existing tunnels created outside of Kubernetes
41+
- **WARP Routing**: Enable private network access via WARP client (`enableWarpRouting`)
42+
43+
### Private Network Access (ZTNA)
44+
- **VirtualNetwork**: Manage Cloudflare virtual networks for traffic isolation
45+
- **NetworkRoute**: Configure IP routes through tunnels to private networks
46+
- **PrivateService**: Expose Kubernetes Services to WARP clients via private IPs
3847

39-
The Cloudflare Operator aims to provide a new way of dynamically deploying the [cloudflared](https://github.com/cloudflare/cloudflared) daemon on Kubernetes. Scaffolded and built using `operator-sdk`. Once deployed, this operator provides the following:
48+
### Access Control
49+
- **AccessApplication**: Define Zero Trust applications with access policies
50+
- **AccessGroup**: Create reusable access groups with include/exclude/require rules
51+
- **AccessIdentityProvider**: Configure identity providers (OIDC, SAML, GitHub, Azure AD, etc.)
52+
- **AccessServiceToken**: Manage service tokens for machine-to-machine authentication
4053

41-
* Ability to create new and use existing Tunnels for [Cloudflare for Teams](https://developers.cloudflare.com/cloudflare-one/) using Custom Resources (CR/CRD) which will:
42-
* Accept a Secret for Cloudflare API Tokens and Keys
43-
* Run a scaled (configurable) Deployment of `cloudflared`
44-
* Manage a ConfigMap for the above Deployment
45-
* Have Cluster and Namespace scoped Tunnels
46-
* A TunnelBinding controller which does the following:
47-
* Update the `cloudflared` ConfigMap to include the new Services to be served under a given Tunnel
48-
* Restart the `cloudflared` Deployment to make the configuration change take effect
49-
* Add a DNS entry in Cloudflare for the specified domain to be a [proxied CNAME to the referenced tunnel](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/routing-to-tunnel/dns)
50-
* Reverse the above when the TunnelBinding is deleted using Finalizers
54+
### Gateway & Security
55+
- **GatewayRule**: Configure Cloudflare Gateway DNS, HTTP, and network policies
56+
- **GatewayList**: Manage lists (URLs, hostnames, IPs) for use in gateway rules
57+
- **GatewayConfiguration**: Global gateway settings and configurations
5158

52-
## Bird's eye view
59+
### Device Management
60+
- **DeviceSettingsPolicy**: Configure WARP client settings, split tunnels, and fallback domains
61+
- **DevicePostureRule**: Define device posture checks for Zero Trust access
62+
63+
### DNS & Connectivity
64+
- **DNSRecord**: Manage Cloudflare DNS records
65+
- **WARPConnector**: Deploy WARP connectors for site-to-site connectivity
66+
67+
## Architecture
5368

5469
Here is how the operator and the Tunnel Resource fit into your deployment.
5570

5671
![Operator Architecture](./docs/images/OperatorArchitecture.png#center)
5772

58-
There is more detailed information on this architecture and the thought process behind it in my [blog post](https://adyanth.site/posts/migration-compose-k8s/cloudflare-tunnel-operator-architecture/).
73+
## Quick Start
74+
75+
### Prerequisites
76+
- Kubernetes cluster (v1.28+)
77+
- Cloudflare account with Zero Trust enabled
78+
- Cloudflare API Token with appropriate permissions
79+
80+
### Installation
81+
82+
```bash
83+
# Install CRDs
84+
kubectl apply -f https://github.com/adyanth/cloudflare-operator/releases/latest/download/cloudflare-operator.crds.yaml
85+
86+
# Install operator
87+
kubectl apply -f https://github.com/adyanth/cloudflare-operator/releases/latest/download/cloudflare-operator.yaml
88+
```
89+
90+
### Create a Tunnel
91+
92+
```yaml
93+
apiVersion: networking.cfargotunnel.com/v1alpha2
94+
kind: Tunnel
95+
metadata:
96+
name: my-tunnel
97+
namespace: default
98+
spec:
99+
cloudflare:
100+
accountId: <your-account-id>
101+
domain: example.com
102+
secret: cloudflare-api-secret
103+
enableWarpRouting: true # Enable private network access
104+
```
105+
106+
### Expose a Service
107+
108+
```yaml
109+
apiVersion: networking.cfargotunnel.com/v1alpha2
110+
kind: TunnelBinding
111+
metadata:
112+
name: my-service-binding
113+
namespace: default
114+
spec:
115+
tunnelRef:
116+
name: my-tunnel
117+
subjects:
118+
- name: my-service
119+
spec:
120+
fqdn: app.example.com
121+
protocol: http
122+
target: my-service:8080
123+
```
124+
125+
## CRD Reference
126+
127+
| CRD | Scope | Description |
128+
|-----|-------|-------------|
129+
| `Tunnel` | Namespaced | Cloudflare Tunnel with managed cloudflared deployment |
130+
| `ClusterTunnel` | Cluster | Cluster-wide Cloudflare Tunnel |
131+
| `TunnelBinding` | Namespaced | Bind Services to Tunnels with DNS records |
132+
| `AccessTunnel` | Namespaced | Reference to external tunnel |
133+
| `VirtualNetwork` | Cluster | Cloudflare virtual network |
134+
| `NetworkRoute` | Cluster | IP route through tunnel |
135+
| `PrivateService` | Namespaced | Expose Service via WARP private IP |
136+
| `AccessApplication` | Namespaced | Zero Trust application |
137+
| `AccessGroup` | Namespaced | Access policy group |
138+
| `AccessIdentityProvider` | Namespaced | Identity provider configuration |
139+
| `AccessServiceToken` | Namespaced | Service token for M2M auth |
140+
| `GatewayRule` | Namespaced | Gateway policy rule |
141+
| `GatewayList` | Namespaced | List for gateway policies |
142+
| `GatewayConfiguration` | Cluster | Global gateway settings |
143+
| `DeviceSettingsPolicy` | Cluster | WARP client settings |
144+
| `DevicePostureRule` | Namespaced | Device posture check |
145+
| `DNSRecord` | Namespaced | DNS record management |
146+
| `WARPConnector` | Namespaced | WARP connector deployment |
147+
148+
## Documentation
149+
150+
- [Getting Started Guide](docs/getting-started.md)
151+
- [API Reference (v1alpha2)](docs/v1alpha2.md)
152+
- [Migration from v1alpha1](docs/migration/v1alpha2.md)
153+
- [Examples](docs/examples/)
154+
155+
## Contributing
156+
157+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.
158+
159+
## License
160+
161+
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
59162

60163
> **_NOTE_**: This is **NOT** an official operator provided/backed by Cloudflare Inc. It utilizes their [v4 API](https://api.cloudflare.com/) and their [`cloudflared`](https://github.com/cloudflare/cloudflared) to automate setting up of tunnels on Kubernetes.

api/cloudflare/v1alpha1/doc.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
Copyright 2025 Adyanth H.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package v1alpha1 contains shared API types for Cloudflare Zero Trust resources.
18+
// These types are used across multiple CRDs to provide consistent interfaces
19+
// for Cloudflare credentials, resource references, and status reporting.
20+
//
21+
// Key types include:
22+
// - CloudflareRef: Unified reference to Cloudflare credentials and account
23+
// - CloudflareCredentials: API authentication configuration
24+
// - CommonStatus: Standard status fields with conditions
25+
// - TunnelReference: Reference to Tunnel/ClusterTunnel resources
26+
// - VirtualNetworkReference: Reference to VirtualNetwork resources
27+
//
28+
// +kubebuilder:object:generate=true
29+
// +groupName=cloudflare.com
30+
package v1alpha1
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
Copyright 2025 Adyanth H.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Package v1alpha1 contains API Schema definitions for the cloudflare.com v1alpha1 API group.
18+
// This package provides shared types for Cloudflare Zero Trust resources.
19+
// +kubebuilder:object:generate=true
20+
// +groupName=cloudflare.com
21+
package v1alpha1
22+
23+
import (
24+
"k8s.io/apimachinery/pkg/runtime/schema"
25+
"sigs.k8s.io/controller-runtime/pkg/scheme"
26+
)
27+
28+
var (
29+
// GroupVersion is group version used to register these objects.
30+
GroupVersion = schema.GroupVersion{Group: "cloudflare.com", Version: "v1alpha1"}
31+
32+
// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
33+
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
34+
35+
// AddToScheme adds the types in this group-version to the given scheme.
36+
AddToScheme = SchemeBuilder.AddToScheme
37+
)

0 commit comments

Comments
 (0)