Skip to main content

A Managed Edge in Front of Your App: Custom Domains, TLS, Cache, and a WAF

· 5 min read
FoundryDB Team
Engineering @ FoundryDB

App Hosting runs your container next to your data and gives it a URL at https://{name}.foundrydb.com. That is enough to ship, but production wants more in front of the origin: your own domain, a real certificate that renews itself, a cache so repeat requests never touch your container, a rate limit so one client cannot drown the rest, and a first line of defense against the obvious injection attempts. Until now each of those was something you bolted on yourself.

FoundryDB now runs that layer for you. The edge gateway is a managed HTTP front end that sits between the public internet and your app's origin. You turn on the pieces you want through one settings call, point a domain at us, and the platform handles certificates, caching, limits, inspection, and the analytics that tell you what is happening.

What shipped

Every app service can now be fronted by a fleet of platform-owned edge nodes, one per EU point of presence (Stockholm, Helsinki, Frankfurt). The edge terminates TLS, applies your policy, and proxies to your origin. Four things became available:

  • Custom domains with automatic certificates. Add a domain, point its DNS at us, and the edge issues and renews a Let's Encrypt certificate on demand. No certificate upload, no renewal cron.
  • Edge caching with per-path rules. Responses under a path prefix are cached for a TTL you choose. Writes and authenticated requests bypass the cache by design.
  • Rate limiting per client IP (or per key), with a configurable rate and burst.
  • A detect-only WAF built on the engine's SQL-injection and cross-site-scripting detectors. Matches are logged and counted, not blocked, so you can see what the rules would catch before you ever turn on blocking.

All of it is observable: request rate, status classes, cache hit ratio, request latency percentiles, rate-limit events, and WAF detections land in your console.

Turning it on

Edge settings are one call. Here a static path is cached for a minute, traffic is limited to 100 requests per second per IP with a burst of 200, and the WAF runs in detect mode:

curl -u "$USER:$PASS" -X PUT \
https://api.foundrydb.com/app-services/$APP_ID/edge/settings \
-H 'Content-Type: application/json' \
-d '{
"cache_rules": [{ "path_prefix": "/static/", "ttl_seconds": 60 }],
"rate_limit": { "key": "ip", "requests_per_second": 100, "burst": 200 },
"waf_mode": "detect"
}'

The change is versioned and rolled out to every edge node. Each node renders a complete gateway configuration, validates it offline, swaps it in atomically, and keeps serving the previous configuration if the new one fails to load. A bad setting never takes your site down; it fails the rollout and the old configuration stays live.

Custom domains and certificates

A custom domain is two steps: register it, then point DNS at the target the API hands back.

curl -u "$USER:$PASS" -X POST \
https://api.foundrydb.com/app-services/$APP_ID/domains \
-H 'Content-Type: application/json' \
-d '{ "domain": "app.example.com" }'
# -> { "status": "pending_verification",
# "cname_target": "your-app.foundrydb.com" }

Create a CNAME from app.example.com to that target. The platform watches DNS, and once the record points at us the domain moves through verifying, issuing_certificate, and propagating to active on its own. The first HTTPS request for the domain triggers certificate issuance through an on-demand flow gated by the controller: a domain the platform does not recognize gets no certificate and the handshake fails loudly, so there is no path to a wrong or self-signed certificate. Renewal is automatic.

Pointing your DNS at us is the proof of ownership. There is no separate verification token to copy.

How a request flows

client
-> DNS: app.example.com -> edge node (home PoP) public IP
-> edge: terminate TLS, run WAF, apply rate limit, serve from cache or
-> origin: your app's container over the platform path

The platform domain {name}.foundrydb.com is cut over to the edge automatically once an app's configuration has converged across the fleet and a synthetic request through the edge has proven the full path works. The cutover is reversible: it is a DNS repoint, not a rebuild, so backing it out is another repoint.

The origin only accepts edge traffic. Each app VM's origin listener admits connections solely from the edge fleet, and that allowlist is reconciled automatically as the fleet changes, so the gateway is not something a client can route around.

Seeing what the edge sees

The same request stream becomes metrics. After a little traffic, the analytics for an app show request totals by status class, cache hits and misses, rate-limited requests, WAF detections broken down by rule, a latency histogram, and the busiest paths. A SQL-injection-shaped query string, for example, still returns 200 in detect mode but increments the WAF detection counter under the rule that matched, so you can size the impact of blocking before you enable it.

In every client

The edge surface is available wherever you already work: the REST API, the Go, TypeScript, Python, and C# SDKs, the fdb CLI (fdb apps domains ... and fdb apps edge ...), and the Terraform provider (foundrydb_edge_domain and foundrydb_app_edge_settings).

What's next

This first release is detect-only on the WAF, an in-process rate limiter that is exact per point of presence, and one home PoP per domain. The model already carries what the next steps need: a blocking WAF mode, a shared rate-limit backend when a PoP grows past a single node, and geo-steering across points of presence. The settings surface will not change as those land; only the engine behind it will.

Bring a domain, set a cache rule, and watch the analytics. The edge is the platform's job now, not yours.