carlos / platform Public

instance-key-build

Instance key provision: the platform mints each instance's key (region HA L21).

Why. Region HA restores a dead box's instance from its replicated database and its files backup. Today an app creates its own instance key when it first starts. If that key is never backed up, the data sealed with it can't be read after a restore. Paul decided on 2026-10-09 that the platform creates the key, before the app first starts and backed up with the instance's files. Rastrillo's side shipped as carlos.InstanceKey (rastrillo e3ea08d, rastrillo#66). The app's own key wins. Otherwise the app takes $CARLOS_INSTANCE_KEY. On CARLOS with no key at all, the app refuses to start.

What changes:

  • internal/instancekey: one rule for the env parse, the effective layer, the digest and the canonical adoption record.
  • The mint. CARLOS_INSTANCE_KEY is written into <host>.env, the file that already holds CARLOS_ADMIN_TOKEN: - create-only: an existing key is never rewritten; - durable before success: chmod 0600, file fsync and directory fsync; - flat files are opened O_NOFOLLOW|O_NONBLOCK, regular files only; - a failed write is truncated back; - fenced and conflicting rows are refused; - nothing is minted until the instance's configuration has been delivered. The bucket is asked, in two phases, outside adminTokenMu. A configured key always wins.
  • Every launch path mints: seed, spawn, nested prepare, and the claim launch source, which mints under the guard and names the key it delivers. The startup backfill does the same on legacy boxes only (activatorStart.Run).
  • Replica gate (ruling 26). A replica runs only with its home's verified key, or with no key and a control socket the helper refuses on. The verified keys are in /etc/carlos/replica-home-keys, which is re-read at every launch. Every replica launch path is gated: seed, spawn, worker, flat and nested sidecar, every nested role, and SelectClaimLaunch.
  • Adoption verb (PUT /instance-key/adoption). It writes a record bound to the writer, and publishes it through a session relay. It is mounted nowhere until O6 and O7.
  • Re-render and moves. The key survives a re-render and travels byte for byte through a move.

Dormant in effect. An env var no app reads yet is harmless. Apps adopt it by moving to rastrillo's helper. The behaviour changes on current fleets are listed in the plan's rollout section, and each one has a pre-roll check:

  • a symlinked or FIFO flat <host>.env now fails launch;
  • keyless replicas' legacy sidecars and workers are refused.

Review:

  • Plan (docs/superpowers/plans/2026-10-10-instance-key-provision.md): Astra, seven rounds, ready to build at rev 5.1.
  • Tasks: each task had its own review and fix rounds; reports are in the branch's SDD ledger.
  • Final review: Fable and Astra, with one fix wave, then two scoped re-reviews. The last one judged it merge-ready at 114ef741.
  • Main merged in at f6a2aa5f (the zdd surfaces). Main added no new launch paths.

Tests:

  • Every guard has a test that fails when the guard is flipped.
  • The full suite passes, sandbox off: 94 packages.

Follow-ups, not built here:

  • #273: the admin token's own symlink, reclassify and second-read gaps.
  • O6: a control socket and the adoption verb on claim launches.
  • O7: moves retire the adoption record.
  • O8: replicas fetch the home's key.

The plan's "Known gaps" section lists the rest.

Merging is Paul's call.

Commits 57
Discussions 0 0 open
Tasks 0/0 done

Discussions

  • No discussions on this branch yet.

Tasks

  • No tasks yet.

Activity