Cloudflare

SkillCloud & infra

Cloudflare Tunnel and Access configuration for exposing K3s services externally.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Cloudflare skill

What this skill tells your AI

The instructions your AI receives, as published by gilesknap/tpi-k3s-ansible in .claude/skills/cloudflare/SKILL.md and read by ahel’s review.

Architecture

  • Cloudflare Tunnel: runs as a pod in the cluster, exposes services externally
  • Cloudflare Access: wildcard policy on *.gkcluster.org — all subdomains protected
  • Flow: Internet → Cloudflare edge → Tunnel pod → NGINX Ingress → Service

Exposed Services

Services exposed via tunnel: grafana, headlamp, open-webui, oauth2-proxy, argocd, echo, supabase (Studio + API)

Supabase Endpoints

  • supabase.gkcluster.org — Studio UI (behind OAuth)
  • supabase-api.gkcluster.org — Kong API gateway (x-brain-key auth, NOT behind OAuth)

Gotchas

  • Tunnel hostname config is managed in Cloudflare dashboard — NOT in this repo
  • DNS resolution: nodes use local DNS (192.168.1.1), not Cloudflare DNS
    • ws03 had systemd-resolved overridden to 1.1.1.1 which broke node01.lan resolution
    • Fix: sudo resolvectl dns enp5s0 192.168.1.1
  • Adding new services requires both: ingress in repo + tunnel hostname in Cloudflare dashboard
  • Cloudflare tunnel sends http:// redirect_uri — services behind the tunnel with ssl_redirect: false generate http:// OAuth callbacks. Dex static clients must list both http:// and https:// redirect URIs.
  • Tunnel routes must go through the ingress — route all tunnel hostnames to http://ingress-ingress-nginx-controller.ingress-nginx.svc.cluster.local. Direct-to-service routes (e.g. http://home.home.svc.cluster.local) bypass the ingress controller and oauth2-proxy entirely, so auth headers like X-Auth-Request-Email will be empty. Cloudflare Access still authenticates (using Google identity), but oauth2-proxy features (email headers, sign-out) won't work.
  • Cloudflare Access uses Google identity — not GitHub. If you see a Google OTP prompt, that's Cloudflare Access. The GitHub auth prompt comes from oauth2-proxy (after traffic reaches the ingress).
  • MCP / non-browser hosts need an Access bypass — services that speak their own OAuth (open-brain-mcp, thoth's MCP endpoint) or use a shared-key API (supabase-api.gkcluster.org) cannot solve Google SSO. Add a Cloudflare Access Application of type Bypass for that hostname. Policy order matters: the bypass must evaluate before the wildcard *.gkcluster.org Access app, otherwise the wildcard wins and challenges every request. Confirm order in the dashboard after adding. Reference precedent: brain.gkcluster.org.

Key Files

  • kubernetes-services/values.yaml — cloudflared toggle and config
  • kubernetes-services/additions/ingress/ — ingress definitions for tunneled services

Signals

GitHub stars
32
Forks
5
Last commit
Sep 2026
Hacker News mentions
20

ahel review

  • S4info
    community integration — published by gilesknap, not cloudflare

Automated review, not a security audit. Ruleset v1.

Advanced
Catalog kind
skill
Gateway key
cloudflare-gilesknap
Source
github.com/gilesknap/tpi-k3s-ansible