hub v0.127.0: off-site key registrar (box never gets the storage password), password sealed at rest, daily key check, clean-up window (shipped off) — decisions 68-69, R-820/R-821/R-822
gates / gates (push) Successful in 29s
gates / gates (push) Successful in 29s
Part A evidence (migration spike, sftp-written repo through the pinned rclone key) and the hub red-proofs under documentation/audits/offsite-lock-build-2026-10-03/. Manifest bump follows after the image is built and Secret/offsite-secret-key exists. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -49,6 +49,7 @@ type Poker interface {
|
||||
// Handler handles API endpoints for report ingest and customer queries.
|
||||
type Handler struct {
|
||||
store *store.Store
|
||||
offsiteKeys OffsiteKeyService // decision 69 key registrar (nil → 503)
|
||||
apiKey string
|
||||
resendAPIKey string
|
||||
fromEmail string
|
||||
@@ -355,6 +356,16 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
case r.Method == http.MethodPost && strings.HasPrefix(path, "/offsite/consume-password/"):
|
||||
customerID := strings.TrimPrefix(path, "/offsite/consume-password/")
|
||||
h.handleOffsiteConsumePassword(w, r, customerID)
|
||||
case r.Method == http.MethodPost && strings.HasPrefix(path, "/offsite/register-key/"):
|
||||
h.handleOffsiteRegisterKey(w, r, strings.TrimPrefix(path, "/offsite/register-key/"))
|
||||
case r.Method == http.MethodPost && strings.HasPrefix(path, "/offsite/confirm-key/"):
|
||||
h.handleOffsiteConfirmKey(w, r, strings.TrimPrefix(path, "/offsite/confirm-key/"))
|
||||
case r.Method == http.MethodPost && strings.HasPrefix(path, "/offsite/move-aside/"):
|
||||
h.handleOffsiteMoveAside(w, r, strings.TrimPrefix(path, "/offsite/move-aside/"))
|
||||
case r.Method == http.MethodPost && strings.HasPrefix(path, "/offsite/window-open/"):
|
||||
h.handleOffsiteWindowOpen(w, r, strings.TrimPrefix(path, "/offsite/window-open/"))
|
||||
case r.Method == http.MethodPost && strings.HasPrefix(path, "/offsite/window-close/"):
|
||||
h.handleOffsiteWindowClose(w, r, strings.TrimPrefix(path, "/offsite/window-close/"))
|
||||
case r.Method == http.MethodGet && strings.HasPrefix(path, "/artifacts/"):
|
||||
customerID := strings.TrimPrefix(path, "/artifacts/")
|
||||
h.handleArtifactManifest(w, r, customerID)
|
||||
@@ -2049,8 +2060,11 @@ var allowedEventTypes = map[string]bool{
|
||||
"offsite_proof_empty": true,
|
||||
// R-431 — the hub raises this itself; allowlisted so a hub-origin event is never 400'd.
|
||||
"offsite_snapshots_dropped": true,
|
||||
"crossdrive_completed": true,
|
||||
"crossdrive_failed": true,
|
||||
// controller v0.289.0 (decision 69): the customer-chosen deletion of set-aside history is deferred
|
||||
// to the operator — the box's append-only key cannot delete. Operator-only (notify.operatorOnlyEvents).
|
||||
"offbox_abandon_deferred": true,
|
||||
"crossdrive_completed": true,
|
||||
"crossdrive_failed": true,
|
||||
// controller v0.134.1 — enlarged offsite push refused by the quota gate (warning; the controller's
|
||||
// dynamic Hungarian message is customer-grade — deliberately NO customerMessages entry, which would
|
||||
// discard the numbers (templates.go:129 priority)).
|
||||
|
||||
Reference in New Issue
Block a user