R-105 (decision 169): retire the never-built slim DR record fields (no writer, no reader); 05 §9/§11, 06 §3.5 corrected
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:
@@ -1220,9 +1220,9 @@ type escrowUploadRequest struct {
|
||||
KeyFingerprint string `json:"key_fingerprint"` // for operator display only
|
||||
Posture string `json:"posture"` // e.g. "zero_knowledge"
|
||||
CreatedAt string `json:"created_at"` // RFC3339
|
||||
// Slice 10D.1 — optional DR bundle, stored alongside the K-escrow (both opaque/non-secret).
|
||||
IdentityBlobB64 string `json:"identity_blob_b64,omitempty"` // age-wrapped {tunnel_token, pbs_token}
|
||||
DirectiveJSON json.RawMessage `json:"directive,omitempty"` // non-secret directive (pbs repo/ns, expected fp, tunnel id)
|
||||
// Slice 10D.1 — optional identity escrow, stored alongside the K-escrow (opaque). An old agent may still send a
|
||||
// `directive`; it is ignored (R-105, decision 169 — retired, never read).
|
||||
IdentityBlobB64 string `json:"identity_blob_b64,omitempty"` // age-wrapped {tunnel_token, pbs_token}
|
||||
// SLICE 3 — sha256 hex of the restic repo password sealed in the identity blob (non-reversible hash
|
||||
// of a 256-bit random secret — safe to store/serve; present only when a staged password was folded in).
|
||||
ResticPwSHA256 string `json:"restic_pw_sha256,omitempty"`
|
||||
@@ -1290,25 +1290,20 @@ func (h *Handler) handleHostEscrowPut(w http.ResponseWriter, r *http.Request, pa
|
||||
h.maybeEmitRepoKeyChanged(host.CustomerID, pathHostID, prevPwSHA, req.ResticPwSHA256, n)
|
||||
}
|
||||
}
|
||||
// Slice 10D.1: optionally store the IDENTITY escrow blob + the non-secret DR directive alongside
|
||||
// the K-escrow (both opaque / non-secret — no usable secret hub-side). Additive: a slice-7
|
||||
// upload without these is unchanged.
|
||||
// Slice 10D.1: optionally store the IDENTITY escrow blob alongside the K-escrow (opaque — no usable secret
|
||||
// hub-side). Additive: a slice-7 upload without it is unchanged. The directive is retired (R-105).
|
||||
if req.IdentityBlobB64 != "" {
|
||||
idBlob, derr := base64.StdEncoding.DecodeString(req.IdentityBlobB64)
|
||||
if derr != nil || len(idBlob) == 0 {
|
||||
http.Error(w, "Invalid payload: identity_blob_b64 not valid base64", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
directive := req.DirectiveJSON
|
||||
if len(directive) == 0 || !json.Valid(directive) {
|
||||
directive = json.RawMessage("{}")
|
||||
}
|
||||
if err := h.store.SaveHostDRBundle(pathHostID, idBlob, string(directive)); err != nil {
|
||||
if err := h.store.SaveHostDRBundle(pathHostID, idBlob); err != nil {
|
||||
h.logger.Printf("[ERROR] Failed to store DR bundle for host %s: %v", pathHostID, err)
|
||||
http.Error(w, "Internal error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
h.logger.Printf("[INFO] stored DR bundle for host %s (identity %d bytes + directive)", pathHostID, len(idBlob))
|
||||
h.logger.Printf("[INFO] stored DR bundle for host %s (identity %d bytes)", pathHostID, len(idBlob))
|
||||
}
|
||||
h.logger.Printf("[INFO] stored opaque escrow blob for host %s (%d bytes, posture=%s, fp=%s)",
|
||||
pathHostID, len(blob), req.Posture, req.KeyFingerprint)
|
||||
|
||||
Reference in New Issue
Block a user