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`.