carlos / platform Public

Merge pull request #290 from carlosframework/wildcard-parents-provisioned

edge: wildcard parents from provisioned routes too (region edges served no wildcards)
Paul Campbell pushed by paul@keymail.dev d6cd0e906754db21636b41f36734a42d82547cff parent d7eba3eparent b8cf371
2 files changed, +41 −19
  • internal/edge/edge.go +17 −9
  • internal/edge/wildcard_test.go +24 −10
diff --git a/internal/edge/edge.go b/internal/edge/edge.go
index db04072b0..7b376d8ff 100644
--- a/internal/edge/edge.go
+++ b/internal/edge/edge.go
@@ -695,15 +695,23 @@ func (e *Edge) current() map[string]upstream {
return nil
}
-// currentHosts lists the hosts of PLATFORM-minted routes only
-// (upstream.route.Platform == true) — the wildcard manager's view of the
-// route table for parent derivation. Not every served host: parents are
-// derived from these hosts, and if a custom domain shaped like
-// x.y.<apps-domain> ever entered the route table, it would mint a wildcard
+// currentHosts lists the hosts of platform-minted routes — rows the console
+// minted directly (Platform) or the provisioning reconciler minted from a
+// bucket record (Provisioned) — the wildcard manager's view of the route
+// table for parent derivation. Not every served host: parents are derived
+// from these hosts, and if a custom domain shaped like x.y.<apps-domain>
+// ever entered the route table by some other path, it would mint a wildcard
// parent and burn a Let's Encrypt issuance on something the wildcard was
-// never meant to cover. Platform-minted app routes set Platform:true; static
-// parents (e.g. tito's go.tito.io) come from CARLOS_WILDCARD_DOMAINS via env,
-// so they are unaffected by this filter.
+// never meant to cover. Provisioned rows are admitted since 2026-08-24: a
+// box whose routes are ALL records-provisioned (every multi-region edge, and
+// any new account on a single box) derived no parents at all and could not
+// serve a single mirrored wildcard — found on the first three-region
+// flagship roll. A provisioned CUSTOM domain (a static record like
+// story.carlosframework.com) is harmless here: parentsFor only mints a
+// parent for hosts exactly two labels under the apps domain, and custom
+// domains under the apps domain are refused at the console. Static parents
+// (e.g. tito's go.tito.io) come from CARLOS_WILDCARD_DOMAINS via env, so
+// they are unaffected by this filter.
//
// Attached hostnames (#151) are excluded by the !up.alias half: an alias
// entry carries the PRIMARY's route row verbatim, Platform flag included, so
@@ -713,7 +721,7 @@ func (e *Edge) currentHosts() []string {
m := e.current()
out := make([]string, 0, len(m))
for h, up := range m {
- if up.route.Platform && !up.alias {
+ if (up.route.Platform || up.route.Provisioned) && !up.alias {
out = append(out, h)
}
}
diff --git a/internal/edge/wildcard_test.go b/internal/edge/wildcard_test.go
index 17b90d41d..8b3f5e182 100644
--- a/internal/edge/wildcard_test.go
+++ b/internal/edge/wildcard_test.go
@@ -12,6 +12,7 @@ import (
"math/big"
"reflect"
"slices"
+ "sort"
"strings"
"testing"
"time"
@@ -408,24 +409,37 @@ func TestOnReloadHookFires(t *testing.T) {
}
// TestCurrentHostsPlatformOnly guards the wildcard-safety filter: only
-// PLATFORM-minted routes (Platform==true) contribute to currentHosts, since
-// parentsFor derives wildcard parents from that list. A custom domain
-// shaped like <x>.<y>.<apps-domain> that somehow landed in the route table
-// (Platform==false) must never mint a wildcard parent and burn an ACME
-// issuance for it — only the routes the domains-reconcile pass itself
-// minted are trusted for that.
+// platform-minted routes contribute to currentHosts — console-minted
+// (Platform==true) or records-provisioned (Provisioned==true) — since
+// parentsFor derives wildcard parents from that list. A host shaped like
+// <x>.<y>.<apps-domain> that landed in the route table by neither path
+// must never mint a wildcard parent and burn an ACME issuance for it.
+//
+// Provisioned rows joined the set on 2026-08-24: a box holding ONLY
+// provisioned rows (every multi-region edge) derived no parents and served
+// no mirrored wildcard. A provisioned custom domain is listed here but
+// mints nothing — parentsFor's two-labels-under-the-apps-domain rule is the
+// bound, pinned below.
func TestCurrentHostsPlatformOnly(t *testing.T) {
e := &Edge{}
e.upstreams.Store(&map[string]upstream{
- "app.acct.oncarlos.com": {route: registry.Route{Host: "app.acct.oncarlos.com", Platform: true}},
- "custom.example.com": {route: registry.Route{Host: "custom.example.com", Platform: false}},
- "evil.acct2.oncarlos.com": {route: registry.Route{Host: "evil.acct2.oncarlos.com", Platform: false}},
+ "app.acct.oncarlos.com": {route: registry.Route{Host: "app.acct.oncarlos.com", Platform: true}},
+ "review.acct3.oncarlos.com": {route: registry.Route{Host: "review.acct3.oncarlos.com", Provisioned: true}},
+ "story.example.com": {route: registry.Route{Host: "story.example.com", Provisioned: true}},
+ "custom.example.com": {route: registry.Route{Host: "custom.example.com", Platform: false}},
+ "evil.acct2.oncarlos.com": {route: registry.Route{Host: "evil.acct2.oncarlos.com", Platform: false}},
})
got := e.currentHosts()
- want := []string{"app.acct.oncarlos.com"}
+ sort.Strings(got)
+ want := []string{"app.acct.oncarlos.com", "review.acct3.oncarlos.com", "story.example.com"}
if !reflect.DeepEqual(got, want) {
t.Fatalf("currentHosts = %v, want %v", got, want)
}
+ parents := parentsFor(nil, "oncarlos.com", got)
+ wantParents := []string{"acct.oncarlos.com", "acct3.oncarlos.com"}
+ if !reflect.DeepEqual(parents, wantParents) {
+ t.Fatalf("parents = %v, want %v (a provisioned custom domain mints no parent; the unowned evil row never reaches here)", parents, wantParents)
+ }
}
func TestDelegatedParentsJoinTheSet(t *testing.T) {