Skip to content

Latest commit

 

History

History
136 lines (101 loc) · 4.12 KB

File metadata and controls

136 lines (101 loc) · 4.12 KB

Public deployment — Cloudflare Tunnel + Access

Your memory hub binds to 127.0.0.1:8080 inside a container. To expose it publicly over HTTPS, without opening a port on your router, we front it with Cloudflare Tunnel (the outbound cloudflared client) and gate access with Cloudflare Access (email-OTP login). Your agent bearer token still protects the API surface; Access adds a human-identity layer for browsers that hit /docs or similar.

This document fills in the concrete steps that the architecture QUICKSTART intentionally abstracted.

Prerequisites

  • A domain on Cloudflare (free plan works). example.com in the snippets below — replace with yours.
  • Cloudflare account with Zero Trust enabled (free up to 50 users). Pick a team subdomain at setup; you won't need to look at it again.
  • The hub running and reachable at http://localhost:8080/healthz on the host you're deploying from.
  • cloudflared installed: brew install cloudflared on macOS, apt install cloudflared on Debian/Ubuntu, or the binary from GitHub releases.

Step 1 — authenticate cloudflared

cloudflared tunnel login

Opens a browser. Pick your domain. The command saves a cert at ~/.cloudflared/cert.pem.

Step 2 — create the tunnel

cloudflared tunnel create starshard-hub

Records the tunnel UUID. Credentials file at ~/.cloudflared/<uuid>.json should be chmod 600.

Step 3 — DNS route

cloudflared tunnel route dns starshard-hub hub.example.com

This adds a proxied CNAME hub.example.com<uuid>.cfargotunnel.com.

Step 4 — tunnel config

Create ~/.cloudflared/config.yml:

tunnel: <uuid>
credentials-file: /home/you/.cloudflared/<uuid>.json
ingress:
  - hostname: hub.example.com
    service: http://localhost:8080
  - service: http_status:404

Run it:

cloudflared tunnel run starshard-hub

Or install as a service:

sudo cloudflared service install

Step 5 — Cloudflare Access application

In the Zero Trust dashboard → Access → Applications → Add a SaaS / Self-hosted application:

  • Name: Starshard hub
  • Subdomain: hub · Domain: example.com
  • Application session duration: 24 hours
  • Identity providers: at minimum, enable "One-time PIN" (email OTP)

Add an Access policy:

  • Name: Allow primary users
  • Action: Allow
  • Rules: Emails include ["you@example.com"]

This allows browser visitors matching the allowlist. API traffic with a valid bearer token should bypass Access — add a Bypass policy with rule HTTP Headers contains "Authorization: Bearer" matching, OR use a Cloudflare Access service token. The simplest for a single-user Phase 0 is to gate the interactive endpoints only:

  • Protect path / with the user allowlist (email OTP).
  • Add a second Application for path /mcp and /memory* with a service-token policy so agents can authenticate programmatically using the CF-Access-* headers.

This dual-Application approach is the recommended Phase 0 pattern. A single-policy setup is possible but harder to reason about.

Step 6 — verify

curl -I https://hub.example.com/healthz
# Expect: HTTP/2 302 to Cloudflare Access login (browser) or HTTP/2 200 if
#         you set up bypass for /healthz.

HUB_TOKEN=...
curl -sH "Authorization: Bearer $HUB_TOKEN" https://hub.example.com/memory
# Expect: JSON array.

Security notes

  • Treat HUB_API_TOKEN like a password. Rotate on any suspected leak.
  • Access service-token credentials (CF-Access-Client-Id / CF-Access-Client-Secret) should live in your agent's secret store, not in git.
  • Keep cloudflared updated; it's the public-internet-facing component.
  • Enable Cloudflare Zero Trust audit logs for the Access Application.

Troubleshooting

  • 503 Bad Gateway: tunnel running but hub not reachable on localhost. Check docker compose ps.
  • 404 on all routes: ingress hostname: in config.yml doesn't match the DNS CNAME.
  • Browser loop: Access policy misconfigured. Use the dashboard's "Test policy" with your email to debug.
  • 401 on API calls with correct bearer: you're hitting the Access layer before the app. Add a service-token bypass for /memory* + /mcp.