v0.106.0: offsite provisioning SLICE 2 — controller apply-bridge

On startup reconcile the hub-served offsite: descriptor into a key-only offbox
target. internal/offsiteapply.Bridge: verify-pin box host key vs host_fingerprint
(NO blind TOFU) → consume the one-time password (single-use, never logged) →
sshpass ssh-copy-id -s -f install + verify → configure offbox → EscrowState=pending
(fork-4 via Manager.ApplyOffsiteTarget) → persist a descriptor-hash marker LAST.
Idempotent + fail-safe. Seams faked in tests; both red-proofs run+reverted.
Dockerfile + sshpass. NOT yet live-applied (supervised end-to-end next runbook).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PSK5g6qYLknKj8u3QAFEr6
This commit is contained in:
2026-07-09 19:14:14 +02:00
parent fa9362f36f
commit aa61fb3411
10 changed files with 686 additions and 61 deletions
+15
View File
@@ -13,6 +13,20 @@ import (
// Config is the top-level configuration structure.
// Contains ONLY infrastructure/customer identity.
// App-specific config lives in per-app app.yaml files.
// OffsiteConfig is the hub-served offsite target descriptor (SLICE 1/2). Non-secret; the transient password
// is fetched once via the hub consume endpoint (never in config). Mirrors hub offsite.Descriptor.
type OffsiteConfig struct {
Enabled bool `yaml:"enabled"`
Type string `yaml:"type"` // "shared" | "dedicated"
Host string `yaml:"host"`
User string `yaml:"user"`
Port int `yaml:"port"` // 23
RepoPath string `yaml:"repo_path"` // /home/<repo>
QuotaGB int `yaml:"quota_gb"`
BoxType string `yaml:"box_type"`
HostFingerprint string `yaml:"host_fingerprint"` // SHA256:… — verified before pinning (no blind TOFU)
}
type Config struct {
Customer CustomerConfig `yaml:"customer"`
Infrastructure InfrastructureConfig `yaml:"infrastructure"`
@@ -31,6 +45,7 @@ type Config struct {
LocalAPI LocalAPIConfig `yaml:"local_api"`
Quiesce QuiesceConfig `yaml:"quiesce"`
MailRelay MailRelayConfig `yaml:"mail_relay"`
Offsite OffsiteConfig `yaml:"offsite"`
}
// MailRelayConfig tunes the in-controller SMTP shim (app email → shim → hub → Resend).