{"id":45073714,"url":"https://github.com/cfgate/cfgate","last_synced_at":"2026-05-16T01:02:38.024Z","repository":{"id":339375346,"uuid":"1161269369","full_name":"cfgate/cfgate","owner":"cfgate","description":"Gateway API-native Kubernetes operator for Cloudflare Tunnel, DNS, and Access","archived":false,"fork":false,"pushed_at":"2026-05-14T23:08:13.000Z","size":1788,"stargazers_count":16,"open_issues_count":4,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-14T23:35:56.934Z","etag":null,"topics":["access-policy","cloudflare","cloudflare-tunnel","controller","dns","gateway-api","go","kubernetes","kubernetes-operator","operator","tunnel","zero-trust"],"latest_commit_sha":null,"homepage":"https://cfgate.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cfgate.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-18T23:17:58.000Z","updated_at":"2026-05-14T21:51:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"85177447-dbad-44d6-ad42-6ab5fc26c581","html_url":"https://github.com/cfgate/cfgate","commit_stats":null,"previous_names":["cfgate/cfgate"],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/cfgate/cfgate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfgate%2Fcfgate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfgate%2Fcfgate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfgate%2Fcfgate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfgate%2Fcfgate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cfgate","download_url":"https://codeload.github.com/cfgate/cfgate/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cfgate%2Fcfgate/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33085116,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T20:25:35.270Z","status":"ssl_error","status_checked_at":"2026-05-15T20:25:34.732Z","response_time":103,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["access-policy","cloudflare","cloudflare-tunnel","controller","dns","gateway-api","go","kubernetes","kubernetes-operator","operator","tunnel","zero-trust"],"created_at":"2026-02-19T13:05:55.562Z","updated_at":"2026-05-16T01:02:38.014Z","avatar_url":"https://github.com/cfgate.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cfgate\n\n[![Latest Release](https://img.shields.io/github/v/release/cfgate/cfgate?style=flat)](https://github.com/cfgate/cfgate/releases/latest) [![Image](https://img.shields.io/github/v/release/cfgate/cfgate?style=flat\u0026label=image\u0026logo=docker\u0026logoColor=white\u0026color=2496ED)](https://github.com/orgs/cfgate/packages/container/package/cfgate) [![Helm Chart](https://img.shields.io/badge/chart-GHCR-0F1689?style=flat\u0026logo=helm\u0026logoColor=white)](https://github.com/orgs/cfgate/packages/container/package/charts%2Fcfgate) [![Artifact Hub](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/cfgate)](https://artifacthub.io/packages/container/cfgate/cfgate)\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/cfgate/cfgate/ci.yml?branch=main\u0026style=flat)](https://github.com/cfgate/cfgate/actions/workflows/ci.yml) [![Coverage](https://codecov.io/gh/cfgate/cfgate/branch/main/graph/badge.svg)](https://codecov.io/gh/cfgate/cfgate) [![Go Report Card](https://goreportcard.com/badge/github.com/cfgate/cfgate)](https://goreportcard.com/report/github.com/cfgate/cfgate) [![Go Reference](https://pkg.go.dev/badge/github.com/cfgate/cfgate.svg)](https://pkg.go.dev/cfgate.io/cfgate/)\n\ncfgate is a Kubernetes operator that manages Cloudflare Tunnels, DNS records, reusable Access policies, and Access application bindings through custom resources. It uses [Gateway API](https://gateway-api.sigs.k8s.io/), the CNCF standard replacing Ingress, so routing configuration works the same as Envoy, Istio, or Cilium. Clusters running cfgate need no public IP, no ingress controller, and no load balancer. Traffic reaches services through Cloudflare Tunnels: outbound-only connections from the cluster to Cloudflare's edge.\n\nGateway API is the Kubernetes successor to Ingress. If you're coming from Ingress, see the [Gateway API Primer](docs/gateway-api-primer.md).\n\n### Why cfgate?\n\n- **Composable CRDs for tunnels, DNS, and access.** CloudflareTunnel, CloudflareDNS, CloudflareAccessPolicy, and CloudflareAccessApplication each manage a distinct piece of Cloudflare infrastructure as Kubernetes resources. Tunnels, DNS records, reusable policies, and app bindings all live in version-controlled YAML instead of the Cloudflare dashboard.\n- **Outbound-only tunnel connections.** Cloudflare Tunnels establish outbound-only connections from the cluster to Cloudflare's edge. Services are never exposed via public IP or load balancer.\n- **Built on Gateway API.** Uses the [Gateway API](https://gateway-api.sigs.k8s.io/) standard, not a proprietary abstraction. Existing community operators use the deprecated Ingress API and lack Access policy management.\n- **Independent, composable resources.** Each CRD operates independently. Use the resources together or pick the ones you need: a tunnel without DNS sync, DNS without Access, Access policies without app bindings, or the full stack.\n\n## How It Works\n\n![How cfgate works](docs/images/how-it-works.svg)\n\nDefine a CloudflareTunnel, point a Gateway at it, and attach HTTPRoutes to the Gateway. cfgate reconciles each resource against the Cloudflare API: it creates the tunnel, deploys cloudflared pods, syncs DNS records, syncs reusable Access policies, and binds Access Applications to route host/path targets. Traffic flows from Cloudflare's edge through the tunnel directly to in-cluster services. The cluster needs no public IP, no ingress controller, and no load balancer.\n\n## Getting Started\n\n### Install\n\n**Kustomize**\n\n```bash\nkubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.5.1/standard-install.yaml\n\nkubectl apply -f https://github.com/cfgate/cfgate/releases/latest/download/install.yaml\n```\n\n**Helm**\n\n```bash\nhelm install cfgate oci://ghcr.io/cfgate/charts/cfgate \\\n  --namespace cfgate-system --create-namespace\n```\n\n\u003e Both methods create the `cfgate-system` namespace. CloudflareTunnel and CloudflareDNS resources typically live here. Routes and services can be in any namespace.\n\n### Quick Start\n\n#### 1. Create credentials\n\n```bash\nkubectl create secret generic cloudflare-credentials \\\n  -n cfgate-system \\\n  --from-literal=CLOUDFLARE_API_TOKEN=\u003cyour-token\u003e\n```\n\n#### 2. Create a tunnel\n\n```yaml\napiVersion: cfgate.io/v1alpha1\nkind: CloudflareTunnel\nmetadata:\n  name: my-tunnel\n  namespace: cfgate-system\nspec:\n  tunnel:\n    name: my-tunnel\n  cloudflare:\n    accountId: \"\u003caccount-id\u003e\"\n    secretRef:\n      name: cloudflare-credentials\n  cloudflared:\n    replicas: 2\n```\n\n#### 3. Create GatewayClass and Gateway\n\n```yaml\napiVersion: gateway.networking.k8s.io/v1\nkind: GatewayClass\nmetadata:\n  name: cfgate\nspec:\n  controllerName: cfgate.io/cloudflare-tunnel-controller\n---\napiVersion: gateway.networking.k8s.io/v1\nkind: Gateway\nmetadata:\n  name: cloudflare-tunnel\n  namespace: cfgate-system\n  annotations:\n    cfgate.io/tunnel-ref: cfgate-system/my-tunnel\nspec:\n  gatewayClassName: cfgate\n  listeners:\n    - name: http\n      protocol: HTTP\n      port: 80\n      allowedRoutes:\n        namespaces:\n          from: All\n```\n\nGatewayClass declares the controller (`cfgate.io/cloudflare-tunnel-controller`). Gateway is the runtime instance that binds to a specific CloudflareTunnel via the `cfgate.io/tunnel-ref` annotation. Both are required.\n\n#### 4. Set up DNS sync\n\n```yaml\napiVersion: cfgate.io/v1alpha1\nkind: CloudflareDNS\nmetadata:\n  name: my-dns\n  namespace: cfgate-system\nspec:\n  tunnelRef:\n    name: my-tunnel\n  zones:\n    - name: example.com\n  source:\n    gatewayRoutes:\n      enabled: true\n```\n\nThe presence of `source.gatewayRoutes` enables route discovery. With `enabled: true` and no `annotationFilter`, cfgate syncs DNS records for all routes attached to the referenced tunnel's Gateways. Explicit-only CloudflareDNS resources do not watch routes. To sync specific routes only, use the `annotationFilter` field. See [CloudflareDNS reference](docs/cloudflare-dns.md#specsourcegatewayroutes).\n\n#### 5. Expose a service\n\n```yaml\napiVersion: gateway.networking.k8s.io/v1\nkind: HTTPRoute\nmetadata:\n  name: my-app\n  namespace: default\nspec:\n  parentRefs:\n    - name: cloudflare-tunnel\n      namespace: cfgate-system\n  hostnames:\n    - app.example.com\n  rules:\n    - backendRefs:\n        - name: my-service\n          port: 80\n```\n\ncfgate automatically:\n- Creates a CNAME record `app.example.com` → `{tunnelId}.cfargotunnel.com`\n- Adds a cloudflared ingress rule routing `app.example.com` → `http://my-service.default.svc:80`\n- Manages ownership TXT records for safe multi-cluster deployments\n\n## CRDs\n\n**CloudflareTunnel** manages tunnel lifecycle and cloudflared deployment. A single tunnel serves any number of domains across zones. → [Full reference](docs/cloudflare-tunnel.md)\n\n**CloudflareDNS** syncs DNS records independently from tunnel lifecycle, with multi-zone support and ownership tracking. → [Full reference](docs/cloudflare-dns.md)\n\n**CloudflareAccessPolicy** manages reusable account-level Cloudflare Access policies. → [Full reference](docs/cloudflare-access-policy.md)\n\n**CloudflareAccessApplication** binds reusable policies to `Gateway` and `HTTPRoute` host/path targets. → [Full reference](docs/cloudflare-access-application.md)\n\nPer-route configuration (origin protocol, TLS settings, timeouts, DNS TTL) is set via annotations on Gateway API HTTPRoute resources. → [Full reference](docs/annotations.md)\n\n## Documentation\n\n| Document | Description |\n|----------|-------------|\n| [Gateway API Primer](docs/gateway-api-primer.md) | Gateway API concepts for Ingress users |\n| [CloudflareTunnel](docs/cloudflare-tunnel.md) | Full CRD reference |\n| [CloudflareDNS](docs/cloudflare-dns.md) | Full CRD reference, annotationFilter, ownership |\n| [CloudflareAccessPolicy](docs/cloudflare-access-policy.md) | Reusable Access policy reference, rule types, service tokens |\n| [CloudflareAccessApplication](docs/cloudflare-access-application.md) | Gateway API target binding, path rules, policyRefs |\n| [Annotations](docs/annotations.md) | Complete annotation reference |\n| [Service Mesh](docs/service-mesh.md) | Istio, Envoy Gateway, and Kiali integration |\n| [Troubleshooting](docs/troubleshooting.md) | Diagnostic steps and solutions |\n| [Testing](docs/TESTING.md) | Unit and E2E test strategy |\n| [Contributing](CONTRIBUTING.md) | Development setup and workflow |\n| [Changelog](CHANGELOG.md) | Release history |\n\n## Examples\n\n| Example | Description |\n|---------|-------------|\n| [basic](examples/basic) | Single tunnel + gateway + DNS sync |\n| [multi-service](examples/multi-service) | Multiple services, one tunnel, reusable Access policies and app bindings |\n| [with-rancher](examples/with-rancher) | Rancher 2.14+ integration |\n| [external-target](examples/external-target) | A/AAAA records via ExternalTarget (no tunnel) |\n\n## Requirements\n\n### Cloudflare API Token\n\nCreate a token at [Cloudflare Dashboard → API Tokens](https://dash.cloudflare.com/profile/api-tokens) with:\n\n| Scope | Permission | Used By |\n|-------|------------|---------|\n| Account | Cloudflare Tunnel: Edit | CloudflareTunnel |\n| Account | Access: Apps and Policies: Edit | CloudflareAccessPolicy, CloudflareAccessApplication |\n| Account | Access: Service Tokens: Edit | CloudflareAccessPolicy |\n| Account | Account Settings: Read | CloudflareTunnel (accountName only)* |\n| Zone | DNS: Edit | CloudflareDNS |\n\n*Only required when using `spec.cloudflare.accountName` instead of `accountId`.\n\n### Kubernetes\n\n- Kubernetes 1.26+\n- Gateway API v1.5.1+ CRDs installed\n- cluster-admin access for CRD installation\n\n## Related Repositories\n\n| Repository | Description |\n|------------|-------------|\n| [cfgate/helm-chart](https://github.com/cfgate/helm-chart) | Helm chart for cfgate |\n| [cfgate/cfgate.io](https://github.com/cfgate/cfgate.io) | Project website |\n\n## Development\n\n```bash\nbrew install mise\nmise install\nmise tasks\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for full development setup, secrets configuration, and contribution guidelines.\n\nSee [docs/TESTING.md](docs/TESTING.md) for the unit-only CI coverage model, local-only E2E bootstrap paths, environment variables, and test execution.\n\n## License\n\n[Apache 2.0](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcfgate%2Fcfgate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcfgate%2Fcfgate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcfgate%2Fcfgate/lists"}