carlos / platform Public

gate-platform-apex

Gate minted platform apexes like the routes they proxy; stop calling them external in the layout report

What

  • internal/domains: the domains pass's minted platform route (<app>.<sqid>.<apps-domain>, Platform: true) now carries a password gate, and keeps it converged on every pass. - Which gate: the gate of the route it serves from (same Socket, same Addr, or for static the same Channel). If that route is open and any other route of the same app and account is gated, it takes the first such gate in host order. It is open only when every route of the app is open. - When it is set: at mint, so the apex is born gated. After that, a new section 6 runs over every Platform row (apex and canary). It uses reg.SetGate, because Upsert keeps a set gate against an empty one and so could never clear it. - Why the fail-closed fallback is a real hash, not a sentinel: internal/gate derives the cookie key from the hash alone. A well-known "closed" value would let anyone mint a valid cookie.
  • internal/host (layout report): a Platform instance row whose socket is served by a non-platform row of the same app now reports the new word platform, with a reason naming the source host. This applies both with and without a layout pass armed. Before this it fell through to external and raised the mixed-layout warning. A Platform row whose socket matches nothing keeps its old classification. - Old consoles already ignore unknown words in layoutMixed and in the downgrade guard, so the change is additive. - Comments are updated in status.RowLayout and console.layoutMixed.
  • docs/site/cli.md, carlos gate: says the app's own domain follows its instances' password.
  • Root read census: a new overlay, internal/provision/testdata/plan14-root-reads-platform-apex-gate.tsv, is loaded last in TestPlan14RootReadCensus, after db-region-forward-3. It is proposed: every new or re-frozen row carries rev3=PROPOSED-platform-apex-gate, and the ruling is still to be asked of the census owner on #280. The two re-pinned layout reports keep their existing disposition; only their sites and digest move. - domains.Reconcile is re-frozen as accepted legacy at its census-ruling-seeded-instances disposition, with this change appended: the gate stamped at mint, and section 6's SetGate convergence. - The new platformGate and servesSame are proposed as accepted legacy at J1 root-route. That is the disposition of their siblings in the same file (candidateApps, firstReadyUpstream, mintedRoute). - platformGate's basis says plainly that its result becomes the apex's Gate, so it decides who the edge admits. It only ever copies a hash that another route of the same app and account already carries. - layoutStatusReport and unmanagedLayoutReport are re-pinned at their diagnostic H3 no-effect disposition. The new mintedAliasOf, which only those two call, takes the same class. - Every read is of registry Route rows the agent (user carlos) wrote itself, so no root decision is involved. - The console, domains, host and status envelopes are re-pinned. The console and status changes are comments only. - Frozen declarations are added, so the legacy seal moves. db-region-forward-3's seal is checked before the overlay loads.

Why

On the new exciting.io deployment, app jelly-demo has three password-gated demo instances. The minted apex jelly-demo.bac.apps.exciting.io copied the first instance's socket but not its gate. It served that demo, including /dev/mail with its sign-in links, to anyone, with no password.

carlos gate set -host <apex> said "not found", because no record sits behind a minted route. Deleting the route got it re-minted. The same layout report labelled the minted row external, which falsely warned that nested isolation was not in force.

A live stopgap is in place on that deployment: an instance record now owns the apex host and is gated. This branch is the platform fix.

Caveats

  • The apex follows a gate change on the domains loop's cadence (5 minutes plus jitter, on the box that runs the pass), not on the 2-second serial. A gate change on an instance therefore reaches the apex up to a few minutes later. Within that window, a cleared or changed password still applies the old rule on the apex. In the fail-closed direction, an instance gated after the apex was minted leaves the apex open until the next domains pass.
  • On rollout, the first domains pass gates every existing apex whose app has a gated route.
  • Removing a minted route still has no API path. Today it is the box verb carlos remove; that is a separate product gap.

Tests

  • internal/domains (reconcile_test.go): - TestReconcileMintedApexCarriesTheSourceGate: born gated on the first pass. - TestReconcileMintedApexCarriesARealBcryptHash: a real bcrypt hash arrives verbatim. - TestReconcileMintedApexGateConverges: set, change and clear on the source all reach the apex. - TestReconcileMintedApexFailsClosedOnMixedGates: covers the mint case, the converge case, and the apex's own source winning. - TestReconcileMintedApexStaysOpenWhenNothingIsGated. - TestReconcileMintedApexGateDoesNotLeakAcrossApps: covers another app, and the same app name in another account. - All except the stays-open guard fail against main's reconcile.go; I watched them fail.
  • internal/host: TestUnmanagedLayoutReportPlatformRowProxiesItsSource, TestLayoutStatusReportPlatformRowProxiesItsSource.
  • internal/console: TestLayoutMixedIgnoresPlatformRows, TestAPIStatusLayoutPlatformRowIsNotMixed.
  • internal/edge: TestPlatformApexRowCarryingTheSourceGateIsGatedOnItsOwn. A gated apex returns 401 on / and /dev/mail and never reaches the backend. The source host's cookie does not open the apex, because cookies are host-bound. Logging in on the apex does open it.
  • internal/provision: TestPlan14RootReadCensus passes locally with the overlay, as do the rest of the package's census tests (-run 'Plan14|Census|Overlay'). Before the overlay, it was the only failure in CI on amadan.
  • Checks run: gofmt -l . and go vet ./... are clean.
  • Package results on macOS: - domains, gate, status, edge and docsite pass. - console and host show only the failures that main shows on the same Mac. Those are environmental: unix-socket and system apply platform limits. - The new tests pass in both console and host. - The full Linux gate has not been run: CI on push.
Commits 1
Files changed 11 +538 −8
Discussions 0 0 open
Tasks 0/0 done

Discussions

  • No discussions on this branch yet.

Tasks

  • No tasks yet.

Activity