@@ -38,6 +38,25 @@ function createHeaderlessRequest(payload: Record<string, unknown>): NextRequest
3838 } )
3939}
4040
41+ function privateChunkPayload (
42+ scope : { userId : string ; workspaceId ?: string } ,
43+ entries : Array < { name : string ; encryptedValue : string } > = [ ]
44+ ) {
45+ return {
46+ content : 'workflow content' ,
47+ [ PRIVATE_SECRET_PROVENANCE_FIELD ] : {
48+ version : 1 as const ,
49+ complete : true ,
50+ selections : [
51+ {
52+ key : 'chunk-content' ,
53+ provenance : { version : 1 as const , complete : true , entries, scope } ,
54+ } ,
55+ ] ,
56+ } ,
57+ }
58+ }
59+
4160describe ( 'knowledge write secret provenance' , ( ) => {
4261 it ( 'classifies a headerless external chunk write as exact-empty' , ( ) => {
4362 const payload = { content : 'manual content' }
@@ -99,22 +118,7 @@ describe('knowledge write secret provenance', () => {
99118 } )
100119
101120 it ( 'tracks exact-empty provenance only when an internal write supplies a verified envelope' , ( ) => {
102- const bundle = {
103- version : 1 as const ,
104- complete : true ,
105- selections : [
106- {
107- key : 'chunk-content' ,
108- provenance : {
109- version : 1 as const ,
110- complete : true ,
111- entries : [ ] ,
112- scope : PRIVATE_PROVENANCE_SCOPE ,
113- } ,
114- } ,
115- ] ,
116- }
117- const payload = { content : 'workflow content' , [ PRIVATE_SECRET_PROVENANCE_FIELD ] : bundle }
121+ const payload = privateChunkPayload ( PRIVATE_PROVENANCE_SCOPE )
118122
119123 const result = resolveKnowledgeWriteSecretProvenance ( {
120124 request : createRequest ( payload ) ,
@@ -131,6 +135,70 @@ describe('knowledge write secret provenance', () => {
131135 } )
132136 } )
133137
138+ it ( 'accepts a different provenance source user in the destination workspace' , ( ) => {
139+ const payload = privateChunkPayload ( { userId : 'workflow-owner' , workspaceId : 'workspace-1' } , [
140+ { name : 'TOKEN' , encryptedValue : 'encrypted-token' } ,
141+ ] )
142+
143+ expect (
144+ resolveKnowledgeWriteSecretProvenance ( {
145+ request : createRequest ( payload ) ,
146+ payload,
147+ authType : AuthType . INTERNAL_JWT ,
148+ userId : 'billing-actor' ,
149+ workspaceId : 'workspace-1' ,
150+ selectionKeys : [ 'chunk-content' ] ,
151+ } )
152+ ) . toEqual ( {
153+ success : true ,
154+ provenances : [
155+ {
156+ status : 'exact' ,
157+ entries : [
158+ {
159+ name : 'TOKEN' ,
160+ encryptedValue : 'encrypted-token' ,
161+ sourceUserId : 'workflow-owner' ,
162+ sourceWorkspaceId : 'workspace-1' ,
163+ } ,
164+ ] ,
165+ } ,
166+ ] ,
167+ } )
168+ } )
169+
170+ it ( 'rejects provenance from another workspace' , ( ) => {
171+ const payload = privateChunkPayload ( {
172+ userId : 'workflow-owner' ,
173+ workspaceId : 'workspace-2' ,
174+ } )
175+ const result = resolveKnowledgeWriteSecretProvenance ( {
176+ request : createRequest ( payload ) ,
177+ payload,
178+ authType : AuthType . INTERNAL_JWT ,
179+ userId : 'billing-actor' ,
180+ workspaceId : 'workspace-1' ,
181+ selectionKeys : [ 'chunk-content' ] ,
182+ } )
183+
184+ expect ( result . success ) . toBe ( false )
185+ if ( ! result . success ) expect ( result . response . status ) . toBe ( 400 )
186+ } )
187+
188+ it ( 'keeps workspace-less knowledge writes isolated to the authenticated user' , ( ) => {
189+ const payload = privateChunkPayload ( { userId : 'workflow-owner' } )
190+ const result = resolveKnowledgeWriteSecretProvenance ( {
191+ request : createRequest ( payload ) ,
192+ payload,
193+ authType : AuthType . INTERNAL_JWT ,
194+ userId : 'billing-actor' ,
195+ selectionKeys : [ 'chunk-content' ] ,
196+ } )
197+
198+ expect ( result . success ) . toBe ( false )
199+ if ( ! result . success ) expect ( result . response . status ) . toBe ( 400 )
200+ } )
201+
134202 it ( 'rejects a private provenance envelope from an external caller' , ( ) => {
135203 const bundle = {
136204 version : 1 as const ,
0 commit comments