Files
story/internal/kmsrotationconformance/conformance_test.go
T

62 lines
3.0 KiB
Go
Raw Normal View History

2026-08-26 06:41:07 +08:00
package kmsrotationconformance
import (
"strings"
"testing"
"time"
)
func TestEvaluateRealKMSRequiresBothConsumptionModes(t *testing.T) {
t.Parallel()
capture, now := rotationFixture("KMS_HSM")
report := Evaluate(capture, "0.64.0-rc.1", "sha256:"+strings.Repeat("a", 64), now)
if report.Result != "PASS" || report.EvidenceScope != "REAL_KMS_HSM" || report.ExternalValidationRequired || report.RotationCount != 2 || len(report.ConsumptionModes) != 2 {
t.Fatalf("unexpected report: %+v", report)
}
capture.Rotations = capture.Rotations[:1]
report = Evaluate(capture, "0.64.0-rc.1", "sha256:"+strings.Repeat("a", 64), now)
if report.Result != "FAIL" || !report.ExternalValidationRequired {
t.Fatal("real KMS evidence without rolling restart mode was accepted")
}
}
func TestEvaluateLocalRotationPreservesExternalGate(t *testing.T) {
t.Parallel()
capture, now := rotationFixture("LOCAL")
capture.Environment = "LOCAL"
capture.Rotations = capture.Rotations[:1]
report := Evaluate(capture, "0.64.0-rc.1", "sha256:"+strings.Repeat("a", 64), now)
if report.Result != "PASS" || report.EvidenceScope != "LOCAL_SECRET" || !report.ExternalValidationRequired {
t.Fatalf("local evidence boundary changed: %+v", report)
}
}
func TestStrictKMSCaptureAndReport(t *testing.T) {
t.Parallel()
if _, err := ParseCapture([]byte(`{"schema_version":"kms-rotation-capture-v1","unknown":true}`)); err == nil {
t.Fatal("unknown capture field was accepted")
}
if _, err := ParseReport([]byte(`{"schema_version":"kms-rotation-conformance-report-v1","unknown":true}`)); err == nil {
t.Fatal("unknown report field was accepted")
}
}
func rotationFixture(source string) (Capture, time.Time) {
now := time.Date(2026, 8, 25, 12, 0, 0, 0, time.UTC)
rotation := func(secret, consumer, mode string, offset int) RotationEvidence {
return RotationEvidence{
SecretRef: secret, ConsumerRef: consumer, ConsumptionMode: mode, OldVersionRef: secret + ":v1", NewVersionRef: secret + ":v2",
StartedAt: now.Add(time.Duration(-10+offset) * time.Minute), CompletedAt: now.Add(time.Duration(-8+offset) * time.Minute),
NewCredentialVerified: true, OldCredentialRejected: true, BusinessContinuityVerified: true, SecretValueNotExported: true,
PreRotationProbeRef: "probe:before:" + secret, NewCredentialProbeRef: "probe:new:" + secret,
OldRejectionProbeRef: "probe:old-rejected:" + secret, ContinuityProbeRef: "probe:continuity:" + secret, AccessAuditRef: "audit:" + secret,
}
}
return Capture{
SchemaVersion: CaptureSchema, EvidenceSource: source, CandidateVersion: "0.64.0-rc.1", BuildDigest: "sha256:" + strings.Repeat("a", 64),
Environment: "STAGING", ProviderRef: "cloud-secret-manager:voice-platform", WorkloadIdentityRef: "workload-identity:voice-platform-api", ProviderAuditRef: "provider-audit:masked-001",
AttestedByRef: "security-reviewer:masked-001", AttestedAt: now.Add(-time.Minute), CollectedAt: now,
Rotations: []RotationEvidence{rotation("device-secret:terminal-001", "api", "DYNAMIC_READ", 0), rotation("provider-callback-secret", "callbacks", "ROLLING_RESTART", 3)},
}, now
}