This note covers exposing a local server to the internet via a [[Cloudflare]] Tunnel, secured with Cloudflare Access and GitHub OAuth. ## Setup 1. Install `cloudflared`: `brew install cloudflared` 2. Authenticate: `cloudflared tunnel login` (select the target DNS zone) 3. Create a named tunnel: `cloudflared tunnel create <name>` 4. Route DNS: `cloudflared tunnel route dns <name> <subdomain.domain.com>` 5. Create `~/.cloudflared/config.yml`: ```yaml tunnel: <TUNNEL_UUID> credentials-file: ~/.cloudflared/<TUNNEL_UUID>.json ingress: - hostname: <subdomain.domain.com> service: http://localhost:<port> - service: http_status:404 ``` 6. Run the tunnel: `cloudflared tunnel run <name>` ## Securing with Cloudflare Access The tunnel alone only proxies traffic. To restrict who can access the service: 1. In the [Zero Trust dashboard](https://one.dash.cloudflare.com), go to **Integrations** → **Identity providers** and add **GitHub** as a login method (requires a GitHub OAuth App). 2. Go to **Access** → **Applications** → **Add an application** → **Self-hosted**, and set the application domain to the tunnel hostname. 3. Create a policy that allows only specific emails or GitHub accounts. This adds a GitHub OAuth gate in front of the service, before any application-level authentication. ## Notes - Cloudflare handles TLS automatically; the local service can be plain HTTP. - `cloudflared tunnel ingress validate` checks the config before running. - For persistence on [[macOS]]: `cloudflared service install`.