diff --git a/external/yaad b/external/yaad index fbc04665..ab5e6490 160000 --- a/external/yaad +++ b/external/yaad @@ -1 +1 @@ -Subproject commit fbc04665cca69a56defee566a80404ed399127ba +Subproject commit ab5e6490c052919e9e293612c15201af0cf70c7b diff --git a/go.mod b/go.mod index 6a86554f..cd16c968 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ require ( github.com/GrayCodeAI/inspect v0.0.0-20260726091806-08f3151d5738 github.com/GrayCodeAI/sight v0.0.0-20260726091804-84c96edfc589 github.com/GrayCodeAI/tok v0.1.5-0.20260812042126-622cafb3bd1b - github.com/GrayCodeAI/yaad v0.2.1-0.20260815132449-fbc04665cca6 + github.com/GrayCodeAI/yaad v0.2.1-0.20260815153959-ab5e6490c052 github.com/alecthomas/chroma/v2 v2.26.1 github.com/bwmarrin/discordgo v0.28.1 github.com/charmbracelet/x/ansi v0.11.7 @@ -36,7 +36,7 @@ require ( golang.org/x/mod v0.38.0 golang.org/x/sys v0.47.0 golang.org/x/term v0.45.0 - golang.org/x/text v0.40.0 + golang.org/x/text v0.41.0 gopkg.in/yaml.v3 v3.0.1 modernc.org/sqlite v1.51.0 ) @@ -150,7 +150,7 @@ require ( github.com/yuin/goldmark-emoji v1.0.6 // indirect github.com/zalando/go-keyring v0.2.8 // indirect go4.org v0.0.0-20260112195520-a5071408f32f // indirect - golang.org/x/crypto v0.54.0 // indirect + golang.org/x/crypto v0.55.0 // indirect golang.org/x/sync v0.22.0 // indirect golang.org/x/time v0.15.0 ) diff --git a/go.sum b/go.sum index d8771348..f74a43c8 100644 --- a/go.sum +++ b/go.sum @@ -30,8 +30,8 @@ github.com/GrayCodeAI/tok v0.1.5-0.20260812042126-622cafb3bd1b h1:iVEaIbxkbyQ751 github.com/GrayCodeAI/tok v0.1.5-0.20260812042126-622cafb3bd1b/go.mod h1:/KTHlWg+qg8fDV8qRsLUfp4VKtt5seTyED1byxldBtE= github.com/GrayCodeAI/trace v0.1.4-0.20260812042155-a31e98c7d75b h1:xqdfzKQ+wzy7B0aTr14Y7CXply41M7z2LoG/qjO0cYE= github.com/GrayCodeAI/trace v0.1.4-0.20260812042155-a31e98c7d75b/go.mod h1:RPt/KV4f2DKezxzqAPe960z3vVmO5eJUGB/ZDlV/sOI= -github.com/GrayCodeAI/yaad v0.2.1-0.20260815132449-fbc04665cca6 h1:Udda7o9RremeNJ4ETwb6Ltu546PsTSS/KoXP/R8VOOU= -github.com/GrayCodeAI/yaad v0.2.1-0.20260815132449-fbc04665cca6/go.mod h1:oL8Wr0JPEtayrKrQxVqVUQODDQ8g8YjzUadETQVE55A= +github.com/GrayCodeAI/yaad v0.2.1-0.20260815153959-ab5e6490c052 h1:0PWsscUHI4CgnlJhaijuQK0OQcATn8TMSQlAfiSlN+c= +github.com/GrayCodeAI/yaad v0.2.1-0.20260815153959-ab5e6490c052/go.mod h1:5qaVC0sdXT38zTH54JJZnUJmKOfCAKoVcrNaoIj4bXw= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE= @@ -424,8 +424,8 @@ go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go4.org v0.0.0-20260112195520-a5071408f32f h1:ziUVAjmTPwQMBmYR1tbdRFJPtTcQUI12fH9QQjfb0Sw= go4.org v0.0.0-20260112195520-a5071408f32f/go.mod h1:ZRJnO5ZI4zAwMFp+dS1+V6J6MSyAowhRqAE+DPa1Xp0= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= -golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= +golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= +golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= golang.org/x/exp v0.0.0-20260603202125-055de637280b h1:v1uXiEBHo8QA0LiGCo7UgHMzHT4Kdfpl2zmtH5vaP1Q= golang.org/x/exp v0.0.0-20260603202125-055de637280b/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw= golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= @@ -445,8 +445,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= -golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= +golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8= +golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/internal/intelligence/memory/yaad_bridge.go b/internal/intelligence/memory/yaad_bridge.go index f608df04..5e73628a 100644 --- a/internal/intelligence/memory/yaad_bridge.go +++ b/internal/intelligence/memory/yaad_bridge.go @@ -69,6 +69,13 @@ func NewYaadBridge() *YaadBridge { return b } +// yaadEncryptionKeyEnv names the environment variable supplying the +// at-rest encryption key for the yaad memory database. It is opt-in: +// without it, node content is stored in plaintext (the historical +// behaviour). Set it consistently on every process that opens the same +// database — content sealed without the key becomes unreadable. +const yaadEncryptionKeyEnv = "YAAD_ENCRYPTION_KEY" + func (b *YaadBridge) init() { home, err := os.UserHomeDir() if err != nil { @@ -85,6 +92,18 @@ func (b *YaadBridge) init() { return } + // Opt-in at-rest encryption (PR yaad#59): when the key variable is set, + // node content is sealed with AES-256-GCM before writing. An invalid key + // disables the bridge entirely rather than silently storing plaintext + // the user did not ask for. + if v := strings.TrimSpace(os.Getenv(yaadEncryptionKeyEnv)); v != "" { + if err := store.EnableEncryption(storage.NewEnvKeyProvider(yaadEncryptionKeyEnv)); err != nil { + _ = store.Close() + slog.Warn("[hawk/memory] yaad encryption key invalid; memory disabled", "error", err) + return + } + } + g := yaadGraph.New(store, store.DB()) eng := yaadEngine.New(store, g)