You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
mcp.internetcomputer.org is currently served directly by Caddy on the production host, with a single DNS-only A record. That means no Cloudflare WAF or DDoS protection in front of it, and the origin address is publicly visible. PfOps have asked for the hostname to be protected by Cloudflare, which is reasonable and is the right end state; this issue tracks the work that has to happen first.
The record was deliberately set to DNS-only rather than Proxied when the endpoint was brought up, for two reasons:
Caddy issues its own certificate. It uses the TLS-ALPN-01 (443) or HTTP-01 (80) challenge, and a proxied record terminates both at Cloudflare's edge, so the challenge never reaches the origin and no certificate is ever issued. This was not hypothetical — it is the state the hostname was in before, serving nothing behind a proxied record.
The service is an MCP server on the Streamable HTTP transport (rmcp with transport-streamable-http-server), so text/event-stream responses and long-lived sessions. /version reports active_sessions and live_sessions, so session longevity is load-bearing rather than incidental.
Enabling the proxy without addressing both would break certificate issuance outright and risk intermittent stream truncation.
Describe the solution you'd like
Two pieces, in order.
Origin certificate. Install a Cloudflare Origin CA certificate on the host and set the zone's SSL mode to Full (strict). Origin CA certs are free, long-lived, and trusted by Cloudflare only, which is exactly the trust relationship wanted here. Concretely this means shipping a cert and key to the host and pointing the Caddyfile at them with an explicit tls directive instead of letting Caddy manage ACME for this site. The cert and key become deploy inputs, so they need somewhere to live alongside the existing PROD_DEPLOY_* secrets, and deploy/native/deploy.sh needs to place them.
SSE compatibility test, before flipping the proxy. Confirm that a proxied request survives a long-lived text/event-stream response. The specific risks are Cloudflare's idle-connection timeout (100 seconds outside Enterprise) and response buffering. Worth testing with a session held open past that timeout with and without traffic, and checking whether events arrive incrementally or are buffered — buffering would break the transport's streaming semantics even where the connection survives. Do this on a proxied test hostname pointed at the same origin rather than by flipping production and watching.
Only enable the proxy on mcp.internetcomputer.org once both are done. Keep DNS-only as the documented fallback if the SSE test finds the proxy unsuitable, and record that outcome here either way — it is the kind of finding that gets rediscovered expensively.
Alternatives considered
DNS-01 challenge via the Cloudflare plugin. Keeps a publicly-trusted certificate on the origin while proxied. Rejected as the primary approach: deploy.sh installs a stock Caddy static binary, and DNS-01 needs a custom build with caddy-dns/cloudflare plus a Cloudflare API token on the host. More moving parts and a bespoke binary to maintain, for no benefit over Origin CA given only Cloudflare needs to trust the origin.
SSL mode Flexible (Cloudflare to origin over plain HTTP). Rejected: the origin leg would be unencrypted, and Caddy's HTTP→HTTPS redirect would cause a redirect loop.
SSL mode Full, not strict (any origin certificate accepted, including self-signed). Works, and Caddy's internal CA would satisfy it, but it leaves the Cloudflare-to-origin leg unauthenticated. Origin CA with Full (strict) is barely more work.
Leave it DNS-only permanently. The status quo, and acceptable on reachability grounds, but it declines the WAF and DDoS protection PfOps asked for and leaves the origin address exposed.
Additional context
Context and the exchange with PfOps are in Deploy production on release-* tags #81, which documents the production public path and why the record ended up DNS-only. The A record points at an Elastic IP on a second ENI in a public subnet; the previous address sat in a NAT-routed subnet and could never receive inbound traffic.
The AAAA record was deleted when the A record was corrected, so the endpoint is IPv4-only. That is fine — IPv4 reaches effectively everyone, and IPv6-only clients reach it via NAT64/DNS64 — but it is worth knowing before changing anything here, because putting Cloudflare in front would restore dual-stack for clients as a side effect.
Staging is in the same subnet with the same NAT-routed IPv4, so if its hostname is DNS-only it is currently IPv4-dark. Worth confirming separately; it may want the same second-ENI treatment, and any Cloudflare decision here probably wants to apply to both.
Is your feature request related to a problem?
mcp.internetcomputer.orgis currently served directly by Caddy on the production host, with a single DNS-onlyArecord. That means no Cloudflare WAF or DDoS protection in front of it, and the origin address is publicly visible. PfOps have asked for the hostname to be protected by Cloudflare, which is reasonable and is the right end state; this issue tracks the work that has to happen first.The record was deliberately set to DNS-only rather than Proxied when the endpoint was brought up, for two reasons:
rmcpwithtransport-streamable-http-server), sotext/event-streamresponses and long-lived sessions./versionreportsactive_sessionsandlive_sessions, so session longevity is load-bearing rather than incidental.Enabling the proxy without addressing both would break certificate issuance outright and risk intermittent stream truncation.
Describe the solution you'd like
Two pieces, in order.
Origin certificate. Install a Cloudflare Origin CA certificate on the host and set the zone's SSL mode to Full (strict). Origin CA certs are free, long-lived, and trusted by Cloudflare only, which is exactly the trust relationship wanted here. Concretely this means shipping a cert and key to the host and pointing the
Caddyfileat them with an explicittlsdirective instead of letting Caddy manage ACME for this site. The cert and key become deploy inputs, so they need somewhere to live alongside the existingPROD_DEPLOY_*secrets, anddeploy/native/deploy.shneeds to place them.SSE compatibility test, before flipping the proxy. Confirm that a proxied request survives a long-lived
text/event-streamresponse. The specific risks are Cloudflare's idle-connection timeout (100 seconds outside Enterprise) and response buffering. Worth testing with a session held open past that timeout with and without traffic, and checking whether events arrive incrementally or are buffered — buffering would break the transport's streaming semantics even where the connection survives. Do this on a proxied test hostname pointed at the same origin rather than by flipping production and watching.Only enable the proxy on
mcp.internetcomputer.orgonce both are done. Keep DNS-only as the documented fallback if the SSE test finds the proxy unsuitable, and record that outcome here either way — it is the kind of finding that gets rediscovered expensively.Alternatives considered
deploy.shinstalls a stock Caddy static binary, and DNS-01 needs a custom build withcaddy-dns/cloudflareplus a Cloudflare API token on the host. More moving parts and a bespoke binary to maintain, for no benefit over Origin CA given only Cloudflare needs to trust the origin.Additional context
AAAArecord was deleted when theArecord was corrected, so the endpoint is IPv4-only. That is fine — IPv4 reaches effectively everyone, and IPv6-only clients reach it via NAT64/DNS64 — but it is worth knowing before changing anything here, because putting Cloudflare in front would restore dual-stack for clients as a side effect.