Files
felhom.eu/hub/internal/configgen/r879_unreadable_test.go
T
admin 5f060e3d1e R-879: seal box API keys, owner passphrases, controller keys and PBS-DR tokens at rest
hosts.api_key, customer_configs.api_key / retrieval_password and host_pbs_secrets.value now hold the
R-821/R-133 seal (enc:v1:, OFFSITE_SECRET_KEY). The two API keys get an api_key_hash lookup twin
(SHA-256, backfilled keyless in migrate()), so box authentication never needs the sealing key; a row
with no hash is matched on its plaintext only while it is plaintext. SealLegacyBoxSecrets seals legacy
rows at start-up (idempotent, non-fatal). A sealed value that does not open sets SecretsUnreadable:
serve/compare paths answer 500, saves refuse the record, the PBS token is not burned.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
2026-10-05 21:45:04 +02:00

24 lines
757 B
Go

package configgen
import (
"strings"
"testing"
"gitea.dooplex.hu/admin/felhom-hub/internal/store"
)
// R-879: a config whose sealed secrets did not open must not become a controller.yaml with an empty
// hub key — Generate refuses it.
func TestR879_GenerateRefusesUnreadableSecrets(t *testing.T) {
cfg := &store.CustomerConfig{CustomerID: "c1", ConfigJSON: "{}", SecretsUnreadable: true}
out, err := Generate("hub: {}\n", cfg, nil)
if err == nil || strings.Contains(out, "api_key") {
t.Fatalf("Generate = %q, %v — want a refusal", out, err)
}
cfg.SecretsUnreadable = false
cfg.APIKey = "k1"
if out, err := Generate("hub: {}\n", cfg, nil); err != nil || !strings.Contains(out, "k1") {
t.Fatalf("readable config = %q, %v", out, err)
}
}