Replace a value given by hand like one the mesh made (hq ADR 0228)

A given own secret the module reads at start is held by nobody but that
module, so the mesh need not read it to replace it: secret rotate now
works on it, and a value given through secret accept is replaced on its
own after the module's first good start under the mesh. Only a value an
outside party issues (own-secrets "issued-by": "outside") or one the
module applies stays as given, refused with the reason.
This commit is contained in:
jochen
2026-10-06 12:13:48 +02:00
parent 722682f1c4
commit e51c6a2cb9
20 changed files with 761 additions and 60 deletions
+17 -6
View File
@@ -789,9 +789,9 @@ func TestADeliveredPairCredentialIsRefusedForARequirementTheModuleDoesNotHave(t
}
// A module's own secret rotates when its definition says the module reads it at start: made anew,
// sealed to the machine and the operator, origin made. Refused with the reason when the definition
// says nothing, says the module applies it, or when the value was given to the mesh (novox/hq
// ADR 0114, issue 180).
// sealed to the machine and the operator, origin made — whether the mesh made the value or a person
// gave it (novox/hq ADR 0228). Refused with the reason when the definition says nothing or says the
// module applies it (novox/hq ADR 0114, issue 180).
func TestAnOwnSecretRotatesOnlyWhenTheModuleReadsItAtStart(t *testing.T) {
inv, ctx := twoNodesWithKeys(t)
m := catalogue.Manifest{Module: "idp", Version: "1", OwnSecrets: catalogue.OwnSecrets{
@@ -833,12 +833,23 @@ func TestAnOwnSecretRotatesOnlyWhenTheModuleReadsItAtStart(t *testing.T) {
t.Fatalf("a secret that says nothing of how it is taken must be refused: %v", err)
}
// A value given to the mesh for a secret read at start is replaced like one it made (ADR 0228).
if err := inv.AcceptSecretForModule(ctx, "consumer", "idp", "session", "the-real-one"); err != nil {
t.Fatal(err)
}
err = inv.RotateModuleSecret(ctx, "consumer", "idp", "session")
if !errors.As(err, &refused) || !strings.Contains(err.Error(), "given to the mesh") {
t.Fatalf("an accepted value must be refused: %v", err)
if err := inv.RotateModuleSecret(ctx, "consumer", "idp", "session"); err != nil {
t.Fatalf("a given value read at start must rotate: %v", err)
}
if origin, _, err := inv.OwnSecretOrigin(ctx, "consumer", "idp", "session"); err != nil || origin != OriginMade {
t.Fatalf("a rotated given value is the mesh's own from then on: %q %v", origin, err)
}
// A given value the module applies stays refused, with the reason.
if err := inv.AcceptSecretForModule(ctx, "consumer", "idp", "admin", "the-real-one"); err != nil {
t.Fatal(err)
}
err = inv.RotateModuleSecret(ctx, "consumer", "idp", "admin")
if !errors.As(err, &refused) || !strings.Contains(err.Error(), "staged") {
t.Fatalf("a given value the module applies must be refused: %v", err)
}
if err := inv.RotateModuleSecret(ctx, "consumer", "idp", "nothing"); err == nil || !strings.Contains(err.Error(), "does not declare") {
t.Fatalf("an undeclared secret: %v", err)