carlos / platform Public

edge: the store door grants a box its platform pointer and artifact

Two exact shapes under control/system/ and bootstrap/router/, no
listing, no writes. Without the pointer grant a door-backed fleet box
would never see a platform promote.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015QCUCpfxbCyEAVQ2m51dH5
Paul Campbell pushed by paul@keymail.dev cab0d09afa6206a80417e2cbfba4c21b2061dcd6 parent 3d4ef80
2 files changed, +48 −4
  • internal/edge/storedoor.go +30 −2
  • internal/edge/storedoor_test.go +18 −2
diff --git a/internal/edge/storedoor.go b/internal/edge/storedoor.go
index ad3a0d460..b2a623761 100644
--- a/internal/edge/storedoor.go
+++ b/internal/edge/storedoor.go
@@ -352,8 +352,14 @@ func canonicalPrefix(raw string) (string, bool) {
// aclRead is the read half of F3, prefix-string exact against the
// authenticated fleet's own identity:
//
-// control/serial the convergence poll
-// bootstrap/carlos the sanctioned self-update path (F7)
+// control/serial the convergence poll
+// bootstrap/carlos the sanctioned self-update path (F7);
+// stays until update-platform-binary.sh
+// is retired (spec §10)
+// control/system/<c>/<ch>.json its platform channel pointer (system
+// update spec §3) — see systemReadKey
+// bootstrap/router/<v>/<asset> a mirrored platform artifact — see
+// systemReadKey
// accounts/<sqid>/** its owning account's record — the manifest lives at
// accounts/<sqid>/account.json (domains.AccountManifestKey),
// NOT accounts/<sqid>.json: a box that cannot read it
@@ -388,6 +394,9 @@ func aclRead(sqid, fleet, key string) bool {
case "control/serial", "bootstrap/carlos":
return true
}
+ if systemReadKey(key) {
+ return true
+ }
if strings.HasPrefix(key, "domains/") {
return true
}
@@ -396,6 +405,25 @@ func aclRead(sqid, fleet, key string) bool {
strings.HasPrefix(key, "fleets/"+fleet+"/")
}
+// systemReadKey is the two shapes the system-update spec (§3) grants every
+// fleet box: its platform channel pointer and a mirrored platform artifact.
+// Shapes, not prefixes — exactly three segments each, so nothing else that
+// ever lands under control/ or bootstrap/ is readable by a box. Listing is
+// not granted (aclDir is unchanged), and canonicalKey has already refused
+// any "." or ".." segment before this runs.
+func systemReadKey(key string) bool {
+ if rest, ok := strings.CutPrefix(key, "control/system/"); ok {
+ comp, file, ok := strings.Cut(rest, "/")
+ return ok && comp != "" && file != "" && !strings.Contains(file, "/") &&
+ strings.HasSuffix(file, ".json") && len(file) > len(".json")
+ }
+ if rest, ok := strings.CutPrefix(key, "bootstrap/router/"); ok {
+ ver, asset, ok := strings.Cut(rest, "/")
+ return ok && ver != "" && asset != "" && !strings.Contains(asset, "/")
+ }
+ return false
+}
+
// aclDir is aclRead for a LISTING's child prefixes (ListDirs), which are
// directories rather than objects and so cannot be judged by it: a returned
// prefix is in scope exactly when it lies inside one of this tenant's own
diff --git a/internal/edge/storedoor_test.go b/internal/edge/storedoor_test.go
index cfb98cf8f..979c11fa6 100644
--- a/internal/edge/storedoor_test.go
+++ b/internal/edge/storedoor_test.go
@@ -82,6 +82,19 @@ func TestStoreDoorACLMatrix(t *testing.T) {
{"control/serial2", opRead, false, "the allowlist is exact, not a prefix"},
{"control/", opRead, false, "no listing-shaped key stands in for the allowlist"},
{"bootstrap/carlos.sig", opRead, false, "exact key only"},
+ {"control/system/router/stable.json", opRead, true, "the platform channel pointer (system update spec §3)"},
+ {"control/system/router/canary.json", opRead, true, "…and the canary one"},
+ {"control/system/router/stable.json", opWrite, false, "a box never writes a pointer"},
+ {"control/system/router", opRead, false, "the pointer shape is exactly three segments ending .json"},
+ {"control/system/router/stable.json/x", opRead, false, "…not four"},
+ {"control/system/router/stable.txt", opRead, false, "…and .json"},
+ {"bootstrap/router/v0.18.0/carlos-linux-arm64", opRead, true, "a mirrored platform artifact"},
+ {"bootstrap/router/v0.18.0/carlos-linux-arm64", opWrite, false, "a box must never publish the platform binary"},
+ {"bootstrap/router/v0.18.0", opRead, false, "the artifact shape is exactly three segments"},
+ {"bootstrap/router/v0.18.0/a/b", opRead, false, "…not four"},
+ {"bootstrap/router.sig", opRead, false, "nothing else under bootstrap/"},
+ {"bootstrap/router/../../x", opRead, false, "traversal is refused by canonicalKey before the ACL"},
+ {"control/system/../serial", opRead, false, "…on both prefixes"},
// --- own account estate ---
// The account manifest is accounts/<sqid>/account.json
@@ -367,8 +380,10 @@ func TestStoreDoorGetServesOwnEstate(t *testing.T) {
etag := seedObject(t, store, ownKey, `{"version":"v1"}`)
seedObject(t, store, "control/serial", "42")
seedObject(t, store, "bootstrap/carlos", "ELF...")
+ seedObject(t, store, "control/system/router/stable.json", `{"payload":"x"}`)
+ seedObject(t, store, "bootstrap/router/v1/carlos-linux-arm64", "ELF")
- for _, key := range []string{ownKey, "control/serial", "bootstrap/carlos"} {
+ for _, key := range []string{ownKey, "control/serial", "bootstrap/carlos", "control/system/router/stable.json", "bootstrap/router/v1/carlos-linux-arm64"} {
w := doorDo(d, "GET", "/store/o/"+key, "", nil)
if w.Code != http.StatusOK {
t.Fatalf("GET %s = %d, want 200", key, w.Code)
@@ -517,7 +532,8 @@ func TestStoreDoorRefusalsAreByteIdentical(t *testing.T) {
// control/certs/**, control/edge-mesh-key and the housekeeper's own lease
// object are NOT in aclRead's allowlist (compare the doc comment above
// aclRead — control/serial, bootstrap/carlos, domains/, accounts/<sqid>/,
-// apps/<sqid>/, fleets/<fleet>/, and nothing else), so no fleet box can ever
+// apps/<sqid>/, fleets/<fleet>/, control/system/<c>/<ch>.json,
+// bootstrap/router/<v>/<asset>, and nothing else), so no fleet box can ever
// read a private key, an ACME account key, a challenge token or the
// housekeeper's coordination lock through this door, however it authenticates.
//