carlos / platform Public

Specify scoped maintenance worker enrollment and publication

Paul Campbell pushed by paul@keymail.dev 38326fa7600d4a175f5f52fa6066ea27451d73fb parent a0a60b5
1 file changed, +30 −0
  • implementation/maintenance-worker-identity/proposal.json +30 −0
diff --git a/implementation/maintenance-worker-identity/proposal.json b/implementation/maintenance-worker-identity/proposal.json
new file mode 100644
index 000000000..52c5d5aca
--- /dev/null
+++ b/implementation/maintenance-worker-identity/proposal.json
@@ -0,0 +1,30 @@
+{
+ "status":"Proposed integration contract; no authenticated worker or endpoint implemented by this file",
+ "parent":"Maintenance protocol5f18cdd / platform117; Fable investigations worker-identity-design and worker-identity-design-r2 are proposals, not approvals",
+ "scope":"Initial shared/root platform boxes only, exactly one eligible enrolled box for the target region/pool. Customer fleet targets and ambiguous multi-box placement refuse. Do not distribute deployment decryption keys to customer machines.",
+ "enrollment":{
+ "registry":"Reuse fleet_boxes token-hash convention but distinguish ops-owned platform fleets with additive fleets.kind='platform'; legacy/default kind='' remains customer. Never infer kind from name or reinterpret an existing customer fleet named platform.",
+ "generation":"Add credential_rev, changed on admit/reactivation/token/status mutation, independent of tag rev. All increments guard signed-int64 overflow. Durable per-box enrollment head in deployment store binds current generation and token hash; fresh SQLite record must match it exactly. Snapshot rollback cannot restore authority. Recovery through explicit owner admit advances from durable head generation, not lagging SQLite.",
+ "authority":"Only current human ops-account owners may create platform-kind fleets or admit, read credential metadata, rotate, detach or tag platform workers. Check actual principal kind plus current RoleOwner via apiSystemOwner. Account membership alone is insufficient. Existing CLI/browser fleet mutators must route platform-kind changes through the worker coordinator, or refuse them; no raw token rotation/status bypass.",
+ "isolation":"Platform-kind fleets excluded from tunnel auth, store-door maps, customer placement and ordinary app creation placement. Existing customer fleets retain behavior and API defaults.",
+ "bootstrap":"Updated platform worker generates a per-box 32-byte random credential once in its protected local state, persists with exclusive creation/0600 and checked fsync before publication. Publish only token hash plus label/placement/random candidate ID. Ops-owner carlos workers admit selects a concrete candidate and confirms current inventory/placement; worker polls supported self endpoint. No plaintext token in console, terminal, logs or enrollment object. Existing credential is never silently replaced on process restart.",
+ "console_discovery":"Console publishes an authenticated deployment console-origin record using existing platform release signing primitives; worker validates against its existing root release public key. This requires explicit format/domain review before implementation, and cannot be replaced with an unsigned bucket URL.",
+ "rotation":"Explicit owner detach/re-admit, with a new candidate ID and fresh credential generation. No automatic self-reactivation. All owner mutation commands must deliver and verify completion through CLI/API without follow-up box administration. Bootstrap agent polls are product implementation, not instructions for a user to SSH."
+ },
+ "assignment":{
+ "owner_box":"Use stable logical box label (existing valid 1-32-character name), not fleet/label or fleet name. Existing guard continuity keeps OwnerBox fixed; replacing physical hardware under the same logical label requires explicit owner re-enrollment and a new credential generation. Changing logical label for an existing guard is unsupported until a reviewed guard migration.",
+ "immutable":"Server creates assignment bound to deployment origin, fleet/kind/account, logical box label, enrollment generation and token-hash identity, app/account/host, request/attempt, record identity/revision and exact placement observation. Request body copies do not select principal or assignment.",
+ "placement":"Region/pool metadata only establishes eligibility. Target refuses unless exactly one active enrolled shared/root worker matches authoritative deployment placement and current inventory. No first-claim selection. Owner approval binds assignment digest. Serving authority additionally requires global guard/projection, proven local stop and continuously retained per-host lease; enrollment never proves stop or lease ownership.",
+ "stop":"Use reviewed FenceAndStop and retained lease/executor evidence; missing activator entry is not stop evidence. No remote stop or inference from elapsed lease TTL. Checked quiescence must precede execution."
+ },
+ "publication":{
+ "fresh_auth":"Authenticate bearer against freshly read registry and durable enrollment head on every self/preflight/outcome request; derive deployment/box/generation server-side. Never use cached tunnel auth or human/service CLI tokens.",
+ "serialization":"Initial coordinator is a single console instance. A checked exclusive process lock over its registry plus per-worker in-process lock spans fresh authentication, payload/receipt persistence and terminal pointer CAS, and also owner enrollment/rotation/revocation. Admission explicitly refuses a multi-console deployment. Lock failure disables worker mutation endpoints; it must not degrade to unlocked operation. This is a scoped single-console contract, not a distributed lock claim.",
+ "durable_revocation":"Before changing SQLite or returning successful revocation, persist create-only tombstone for the old generation and CAS durable enrollment head. Authenticate/publication refuse tombstoned generation even after registry restore. Crash between store and SQLite fails closed. No auto repair from stale row. Owner re-admit uses current durable head as generation floor.",
+ "linearization":"Terminal pointer CAS while serialized and current active generation is the acceptance point. Revocation waits for an in-flight publication to finish its CAS or fail. A historical accepted result remains accepted after later revocation; result readback checks its immutable generation binding and accepted attempt, not current token activity. This does not retroactively cancel a result accepted before revocation.",
+ "binding":"Persist bounded encrypted payload create-only, derive exact immutable receipt digest, verify all scope/assignment/approved artifact/environment/input/recipient refs and checked worker execution evidence, then CAS only the matching attempt pointer. Changed replay conflicts; identical publication-ID retry is idempotent. Neither arbitrary bucket writes nor body booleans establish accepted execution.",
+ "limits":"Direct root edits or hostile broad deployment-store writers are outside existing platform trusted-writer boundary; do not claim this mechanism protects tenants from a compromised platform root. Separate console IAM is a tracked platform security improvement. Worker enrollment does not fix cross-tenant shared-UID issues126/127."
+ },
+ "review_questions":["Confirm single-console admission/locking can be mechanically enforced from actual console deployment metadata, not an unchecked configuration boolean; otherwise publication needs distributed serialization before mounting.","Confirm existing signing library supplies a suitable authenticated console-discovery envelope without new worker receipt authority.","Verify every platform-kind fleet mutation and auth/placement reader is covered, and durable generation recovery is safe across each crash boundary."],
+ "required_tests":["customer namespace collision preserved","member/service/other-account owner denied platform enrollment","platform worker token never accepted by tunnel/store door","stale/rotated/detached/token-swapped generation denied from fresh registry plus durable head","snapshot rollback cannot revive revoked generation","wrong box/request/attempt/placement publication denied","revocation racing publish respects acceptance boundary","publication crash/idempotent retry and pointer conflict","single-console lock/admission refuses unsupported topology","bootstrap restart preserves credential and duplicate/conflicting candidates refuse"]
+}