package main // Bootstrap test for issue 0006a/c: under enforce, membershipd must still reach // JetStream on its OWN embedded server to create the nonce/KV buckets. It does so // with an ephemeral internal identity the authenticator grants full permissions // (NewNkeyAuthenticatorACLInternal). These tests prove that privileged // self-connection works AND that no other identity can claim it. import ( "context" "encoding/hex" "net" "testing" "time" cs "fn-registry/functions/cybersecurity" "github.com/enmanuel/unibus/pkg/busauth" "github.com/enmanuel/unibus/pkg/embeddednats" "github.com/nats-io/nats.go" "github.com/nats-io/nats.go/jetstream" ) func icFreePort(t *testing.T) int { t.Helper() l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatalf("free port: %v", err) } defer l.Close() return l.Addr().(*net.TCPAddr).Port } // TestInternalConnPrivilegedUnderEnforce: with an enforce authenticator that // authorizes NO bus user, the internal identity still connects in-process and has // full permissions — it creates a KV bucket and round-trips a value. This is the // resolution of the bootstrap cycle the audit flagged as the reason the KV store // was never wired. func TestInternalConnPrivilegedUnderEnforce(t *testing.T) { internalID, err := cs.GenerateIdentity() if err != nil { t.Fatalf("internal identity: %v", err) } internalPubHex := hex.EncodeToString(internalID.SignPub) // Authenticator: no bus user is authorized; only the internal identity passes. auth := busauth.NewNkeyAuthenticatorACLInternal( func(string) bool { return false }, busauth.PermissionsFromSubjects(func(string) ([]string, error) { return []string{"_INBOX.>"}, nil }), internalPubHex, ) ns, err := embeddednats.StartServer(embeddednats.ServerConfig{ StoreDir: t.TempDir(), Host: "127.0.0.1", Port: icFreePort(t), Auth: auth, }) if err != nil { t.Fatalf("nats: %v", err) } t.Cleanup(func() { ns.Shutdown(); ns.WaitForShutdown() }) nc, js, err := connectInternalJS(ns, internalID, true /*useNkey*/) if err != nil { t.Fatalf("connectInternalJS: %v", err) } t.Cleanup(nc.Close) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() kv, err := js.CreateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: "KV_UNIBUS_test", Replicas: 1}) if err != nil { t.Fatalf("internal conn could not create KV bucket (full perms expected): %v", err) } if _, err := kv.Put(ctx, "k", []byte("v")); err != nil { t.Fatalf("kv put: %v", err) } e, err := kv.Get(ctx, "k") if err != nil || string(e.Value()) != "v" { t.Fatalf("kv get: val=%q err=%v", e, err) } } // TestInternalConnOutsiderRejected: an identity that is neither the internal one // nor an allowlisted bus user cannot connect — proving the internal bypass is // scoped to the exact internal key, not a blanket hole. func TestInternalConnOutsiderRejected(t *testing.T) { internalID, err := cs.GenerateIdentity() if err != nil { t.Fatalf("internal identity: %v", err) } auth := busauth.NewNkeyAuthenticatorACLInternal( func(string) bool { return false }, busauth.PermissionsFromSubjects(func(string) ([]string, error) { return []string{"_INBOX.>"}, nil }), hex.EncodeToString(internalID.SignPub), ) ns, err := embeddednats.StartServer(embeddednats.ServerConfig{ StoreDir: t.TempDir(), Host: "127.0.0.1", Port: icFreePort(t), Auth: auth, }) if err != nil { t.Fatalf("nats: %v", err) } t.Cleanup(func() { ns.Shutdown(); ns.WaitForShutdown() }) outsider, err := cs.GenerateIdentity() if err != nil { t.Fatalf("outsider identity: %v", err) } pub, sign, err := busauth.ClientNkey(outsider.SignPriv) if err != nil { t.Fatalf("outsider nkey: %v", err) } conn, err := nats.Connect(ns.ClientURL(), nats.Nkey(pub, sign), nats.MaxReconnects(0), nats.Timeout(2*time.Second), ) if err == nil { conn.Close() t.Fatalf("outsider (unauthorized, non-internal) must be rejected, but connected") } }