// Package provision implements the slice-8A provisioning BACK HALF: after the slice-7 bring-up // front half (restore → identity → size → start), the agent mints a per-guest local-API token, // renders the stable bootstrap.json contract, and populates a read-only config mount the golden's // baked controller-bootstrap unit consumes (F3: host-side only, no pct exec). // // The agent NEVER enters the guest and NEVER puts a registry credential in the guest (the // controller image is baked into the golden — configs/build-golden.sh). The only secret written // into the guest is the per-guest local-API token, in the 0600 bootstrap.json on the config mount. package provision import "encoding/json" // SchemaV1 is the stable agent→controller contract version. It MUST stay byte-compatible with the // controller's internal/bootstrap.SchemaV1 / Bootstrap shape (cross-repo contract; doc_test.go // pins the key set, mirroring the controller's bootstrap_test.go). const SchemaV1 = "felhom.bootstrap/v1" // Doc is the bootstrap.json the agent emits. Field names + json tags MUST match the controller's // internal/bootstrap.Bootstrap exactly. It carries ONLY what the controller needs to come up // configured and reach the agent's local API — no registry credential (image is baked). type Doc struct { Schema string `json:"schema"` Customer DocCustomer `json:"customer"` Hub DocHub `json:"hub"` LocalAPI DocLocalAPI `json:"local_api"` } type DocCustomer struct { ID string `json:"id"` Name string `json:"name"` Domain string `json:"domain"` Email string `json:"email"` } type DocHub struct { URL string `json:"url"` APIKey string `json:"api_key"` HostID string `json:"host_id"` } type DocLocalAPI struct { Endpoint string `json:"endpoint"` // host bridge IP:port Fingerprint string `json:"fingerprint"` // agent leaf-cert SHA-256 (hex) to pin Token string `json:"token"` // per-guest bearer; SECRET — written 0600 only } // render marshals the doc as indented JSON (the bytes written into the config mount). func (d Doc) render() ([]byte, error) { return json.MarshalIndent(d, "", " ") }