v0.105.0: fork-4 offsite password custody — hand-off + atomicity gate + DR inject + coord
Pairs with agent v0.77.0. StageEscrowSecret pushes the repo password to the agent (POST /escrow/stage-secret) at offsite-enable → EscrowState="pending". Atomicity gate: RunOffboxBackup (scheduler + handler) refuses until EscrowState="escrowed" (operator POST /backup/offbox/confirm-escrow after the escrow ceremony) — no un-recoverable offsite ciphertext can exist. DR: POST /backup/offbox/inject-password pre-places a recovered 64-hex password 0600 (honored by WriteOffboxSecrets' IsNotExist guard; refuses clobber without force). DR recipe gains non-secret offsite_restic coords (DRResticCoord); SFTP key regenerated at DR, not escrowed. New settings.OffboxTarget.EscrowState. Tests + atomicity & inject companion red-proofs green; UI gates pass. NOT yet live-validated (supervised ceremony). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
@@ -463,6 +463,17 @@ type EjectResult struct {
|
||||
// EjectDisk safe-unmounts a host mount (data preserved) and returns the dependent guests.
|
||||
// Status-aware POST (campaign F2 evidence gap): the agent's refusal body carries the reason
|
||||
// (e.g. "…eject refused (role: system)") — surface it instead of a bare "HTTP 403".
|
||||
// StageEscrowSecret pushes the offsite restic repo password to the agent (fork-4), which stages it
|
||||
// transiently for the escrow-create ceremony to wrap under the customer recovery code R. The value is
|
||||
// sent over the authenticated pinned local-API channel; the CALLER must never log it.
|
||||
func (c *Client) StageEscrowSecret(ctx context.Context, resticRepoPassword string) error {
|
||||
env, status, err := c.postWithStatus(ctx, "/escrow/stage-secret", map[string]string{"restic_repo_password": resticRepoPassword})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return refusalError("/escrow/stage-secret", status, env)
|
||||
}
|
||||
|
||||
func (c *Client) EjectDisk(ctx context.Context, where string) (EjectResult, error) {
|
||||
var out EjectResult
|
||||
env, status, err := c.postWithStatus(ctx, "/disks/eject", map[string]string{"where": where})
|
||||
|
||||
Reference in New Issue
Block a user