Recoverable means sealed to the current operator key; recovery names the provider
From review: the export counted any operator-sealed row as recoverable, so a secret sealed to a replaced key was reported as openable with the current one; replacing the key counted orphans in one table of two; and a pair credential held from two providers was recovered as whichever row came first. The export now lists what the current key opens, what an earlier key opens, and what has no copy; `secret recover` takes --provider and refuses ambiguity; files that must not exist are created exclusively; one constructor builds the export for the operator's file and the vault's disk alike.
This commit is contained in:
@@ -52,14 +52,13 @@ func operatorKeyMake(args []string) error {
|
||||
if err := set.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := os.Stat(*out); err == nil {
|
||||
return fmt.Errorf("%s already exists; this will not overwrite a key somebody may still need", *out)
|
||||
}
|
||||
public, private, err := secrets.Keypair()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := os.WriteFile(*out, []byte(private+"\n"), 0o600); err != nil {
|
||||
// Create-exclusive: a key somebody may still need is never overwritten, and there is no window
|
||||
// between checking and writing in which one could appear.
|
||||
if err := writeNew(*out, []byte(private+"\n")); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("operator key %s\n", secrets.Fingerprint(public))
|
||||
@@ -129,14 +128,20 @@ func operatorKeyShow(ctx context.Context) error {
|
||||
fmt.Println("the mesh has no operator key; `operator key make` then `operator key set` gives it one")
|
||||
return nil
|
||||
}
|
||||
kept, unrecoverable, err := inv.KeptForOperator(ctx)
|
||||
kept, earlier, unrecoverable, err := inv.KeptForOperator(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("operator key %s\n %s\n", secrets.Fingerprint(key), key)
|
||||
fmt.Printf(" %d secret(s) recoverable with it\n", len(kept))
|
||||
if len(earlier) > 0 {
|
||||
fmt.Printf(" %d secret(s) sealed to an earlier operator key — recoverable with that key only, until issued again:\n", len(earlier))
|
||||
for _, k := range earlier {
|
||||
fmt.Printf(" %s %s %s (%s)\n", k.Node, k.Module, k.Name, secrets.Fingerprint(k.Key))
|
||||
}
|
||||
}
|
||||
if len(unrecoverable) > 0 {
|
||||
fmt.Printf(" %d secret(s) not recoverable — made before it, or sealed to an earlier key:\n", len(unrecoverable))
|
||||
fmt.Printf(" %d secret(s) not recoverable — made before the mesh had an operator key:\n", len(unrecoverable))
|
||||
for _, k := range unrecoverable {
|
||||
fmt.Printf(" %s %s %s\n", k.Node, k.Module, k.Name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user