A pair credential is sealed to the operator key too
The secret the vault provides a module is the credential of the consumer↔vault pair, and so is every credential a provider grants; sealing only own secrets to the operator left exactly those unrecoverable. Same column, same call; the export and `secret recover` address a pair by consumer node, module and the provision's name, and say which kind each entry is.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package inventory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/catalogue"
|
||||
@@ -95,3 +96,74 @@ func TestAnOwnSecretIsSealedToTheOperatorToo(t *testing.T) {
|
||||
t.Fatal("the new key is not the mesh's key")
|
||||
}
|
||||
}
|
||||
|
||||
// A pair credential — what the vault provides a module — is sealed to the operator too, and the
|
||||
// operator's copy is the very value the consumer's node unseals.
|
||||
func TestAPairCredentialIsSealedToTheOperatorToo(t *testing.T) {
|
||||
inv := fresh(t)
|
||||
ctx := context.Background()
|
||||
// Two nodes with keys, keeping the consumer's opener: the test made the key, so it can play the
|
||||
// consumer's host for one assertion.
|
||||
var openAsConsumer func(string) ([]byte, bool)
|
||||
for _, n := range []string{"consumer", "provider"} {
|
||||
node, err := inv.AddNode(ctx, n)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
key, open := aSealingKey(t)
|
||||
if n == "consumer" {
|
||||
openAsConsumer = open
|
||||
}
|
||||
if err := inv.RecordSealingKey(ctx, node.ID, key); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
for _, m := range []string{"gitea", "mesh-vault"} {
|
||||
if err := inv.RegisterModule(ctx, catalogue.Manifest{Module: m, Version: "1"}, Source{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
pub, priv, err := secrets.Keypair()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := inv.SetOperatorKey(ctx, pub); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
made, err := inv.SecretFor(ctx, "secret", "consumer", "gitea", "provider")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kept, err := inv.KeptSecret(ctx, "consumer", "gitea", "secret")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if kept.Kind != "pair" || kept.Provider != "provider" {
|
||||
t.Fatalf("kept as %+v", kept)
|
||||
}
|
||||
fromOperator, err := secrets.Open(priv, kept.Sealed)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// The consumer's blob is sealed to the consumer node. Same value, two recipients.
|
||||
fromNode, ok := openAsConsumer(made.ForConsumer)
|
||||
if !ok {
|
||||
t.Fatal("the consumer cannot open its own blob")
|
||||
}
|
||||
if string(fromOperator) != string(fromNode) {
|
||||
t.Fatal("the operator's copy of the pair credential differs from the consumer's")
|
||||
}
|
||||
all, _, err := inv.KeptForOperator(ctx)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var pairs int
|
||||
for _, k := range all {
|
||||
if k.Kind == "pair" {
|
||||
pairs++
|
||||
}
|
||||
}
|
||||
if pairs != 1 {
|
||||
t.Fatalf("%d pair credential(s) in the export, expected 1", pairs)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user