Trace a rotation's credential writes and compositions, record the bindings a composition carries, drop SchemaReachOf, and re-pin mesh-sdk to e45bdc0891bb (issue 1945)

This commit is contained in:
2026-10-24 20:23:05 +02:00
parent 6ed5de186d
commit 8c54139905
8 changed files with 122 additions and 17 deletions
-13
View File
@@ -3,8 +3,6 @@ package inventory
import (
"context"
"errors"
"github.com/jackc/pgx/v5"
)
// What a controller build knows of the store's schema (novox/hq issue 352): the highest migration it
@@ -23,17 +21,6 @@ func (i *Inventory) RecordSchemaReach(ctx context.Context, build string, reach i
return err
}
// SchemaReachOf is the highest migration a build carries, as it recorded when it served; false for a
// build that never did.
func (i *Inventory) SchemaReachOf(ctx context.Context, build string) (int, bool, error) {
var reach int
err := i.store.Pool().QueryRow(ctx, `select reach from controller_schema where build = $1`, build).Scan(&reach)
if errors.Is(err, pgx.ErrNoRows) {
return 0, false, nil
}
return reach, err == nil, err
}
// SchemaApplied is the highest migration the store has applied.
func (i *Inventory) SchemaApplied(ctx context.Context) (int, error) {
var n *int
+30
View File
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"runtime"
"slices"
"sort"
"strings"
@@ -21,6 +22,31 @@ import (
// The table holds nothing usable — see the migration and internal/secrets for why that is the
// design rather than an inconvenience.
// SecretTrace, when set, is told of every write of a pair credential's row — a made or accepted one, a rotated one discarded —
// with the callers that led to it. A test sets it to see who wrote what; the controller never does.
var SecretTrace func(op, what string)
func traceSecret(op, name, consumer, module, provider string) {
if SecretTrace == nil {
return
}
pcs := make([]uintptr, 8)
n := runtime.Callers(3, pcs)
frames := runtime.CallersFrames(pcs[:n])
var callers []string
for {
f, more := frames.Next()
if i := strings.LastIndex(f.Function, "/"); i >= 0 {
f.Function = f.Function[i+1:]
}
callers = append(callers, f.Function)
if !more || len(callers) >= 5 {
break
}
}
SecretTrace(op, fmt.Sprintf("%s for %s/%s from %s, by %s", name, consumer, module, provider, strings.Join(callers, " < ")))
}
// Secret is one provision's credential, sealed to each end.
type Secret struct {
Name string
@@ -146,6 +172,7 @@ func (i *Inventory) SecretFor(ctx context.Context, name, consumer, consumerModul
if err != nil {
return Secret{}, err
}
traceSecret("made", name, consumer, consumerModule, provider)
return Secret{Name: name, Consumer: consumer, ConsumerModule: consumerModule, Local: local,
Provider: provider,
ForConsumer: made.ForConsumer, ForProvider: made.ForProvider,
@@ -276,6 +303,9 @@ func (i *Inventory) RotateSecret(ctx context.Context, name, consumer, consumerMo
`delete from secret where name = $1 and consumer = $2 and consumer_module = $3
and provider = $4 and local = $5`,
name, consumerNode.ID, consumerModule, providerNode.ID, local)
if err == nil {
traceSecret("discarded", name, consumer, consumerModule, provider)
}
return err
}