Stabilize diagnostic export and preserve authorized policy continuity
This commit is contained in:
1 parent
0a5df7398e
commit
09bf616d98
18 files changed
+364
-57
No files matched your search
@@ -16,11 +16,11 @@ const extracted=source.slice(source.indexOf('function applyPolicy(envelope)'),so
|
||||
async function fixture(t){
|
||||
const payloads=[],server=createServer((req,res)=>{const chunks=[];req.on('data',v=>chunks.push(v));req.on('end',()=>{payloads.push(JSON.parse(Buffer.concat(chunks).toString()));res.setHeader('content-type','application/json');res.end('{}');});}).listen(0,'127.0.0.1');await new Promise(resolve=>server.once('listening',resolve));
|
||||
const diagnostics=createDiagnostics(),config=DiagnosticsSchema.parse({enabled:true,mode:'debug',endpoint:`http://127.0.0.1:${server.address().port}`,sampleRate:1,debugSampleRate:1,flushIntervalMs:10000});
|
||||
t.after(async()=>{await diagnostics.shutdown();server.closeAllConnections();await new Promise(resolve=>server.close(resolve));});diagnostics.configure(config);
|
||||
t.after(async()=>{await diagnostics.shutdown();server.closeAllConnections();await new Promise(resolve=>server.close(resolve));});diagnostics.configure(config,{policyVersion:1,deviceId:'00000000-0000-4000-8000-000000000001'});
|
||||
const calls=[],next=defaultPolicy();next.diagnostics=config;const keys=generateKeyPairSync('ed25519'),privateKey=keys.privateKey.export({type:'pkcs8',format:'pem'}),publicKey=keys.publicKey.export({type:'spki',format:'pem'}),deviceId='00000000-0000-4000-8000-000000000001';
|
||||
const envelope=()=>({...signPolicy(next,privateKey),bookmarks:signBookmarkSnapshot({deviceId,policyVersion:next.version,revision:0,expiresAt:next.expiresAt,items:[]},privateKey)});
|
||||
const tracked=name=>async()=>{calls.push({name,enabled:diagnostics.status().enabled});};
|
||||
const c=vm.createContext({require,process:{env:{}},core:{verifyPolicy},assertPolicyAssignment:require('../apps/browser/policy-assignment.cjs').assertPolicyAssignment,credentialBroker:{revoke:()=>calls.push({name:'credential-revoke',enabled:diagnostics.status().enabled})},device:{id:deviceId,publicKey,minimumVersion:0},policy:next,personalBookmarks:{revision:0,items:[]},bookmarkSnapshotJSON:'',bookmarkModule:{verifyBookmarkSnapshot},saveDevice:()=>calls.push({name:'save',enabled:diagnostics.status().enabled}),diagnosticSpan:(name,attributes,fn)=>diagnostics.span(name,attributes,fn),configureDiagnostics:v=>{calls.push({name:'configure',enabled:v.enabled});diagnostics.configure(v);},reconcileAgentPolicy:tracked('agent'),enforceEvidencePolicy:()=>{},emit:()=>{},quarantine:()=>{},browserSession:{closeAllConnections:tracked('browser-close'),setProxy:tracked('browser-proxy'),clearHostResolverCache:tracked('browser-dns')},managementSession:{closeAllConnections:tracked('management-close'),setProxy:tracked('management-proxy'),clearHostResolverCache:tracked('management-dns')},app:{configureHostResolver:()=>calls.push({name:'resolver',enabled:diagnostics.status().enabled})},resolverOptions:v=>v,recentRequests:new Map(),tabs:{all:()=>[{security:{developerToolsGuard:{close:()=>{}}},view:{webContents:{closeDevTools:()=>{}}}}]},configureVisualPage:tracked('page'),audit:tracked('audit')});
|
||||
const c=vm.createContext({require,diagnostics,diagnosticContext:extra=>({deviceId,policyVersion:c.policy?.version||0,...extra}),process:{env:{}},core:{verifyPolicy},assertPolicyAssignment:require('../apps/browser/policy-assignment.cjs').assertPolicyAssignment,credentialBroker:{revoke:()=>calls.push({name:'credential-revoke',enabled:diagnostics.status().enabled})},device:{id:deviceId,publicKey,minimumVersion:0},policy:next,personalBookmarks:{revision:0,items:[]},bookmarkSnapshotJSON:'',bookmarkModule:{verifyBookmarkSnapshot},saveDevice:()=>calls.push({name:'save',enabled:diagnostics.status().enabled}),diagnosticSpan:(name,attributes,fn)=>diagnostics.span(name,attributes,fn),configureDiagnostics:v=>{calls.push({name:'configure',enabled:v.enabled});diagnostics.configure(v,{deviceId,policyVersion:c.policy?.version||0});},reconcileAgentPolicy:tracked('agent'),enforceEvidencePolicy:()=>{},emit:()=>{},quarantine:()=>{},browserSession:{closeAllConnections:tracked('browser-close'),setProxy:tracked('browser-proxy'),clearHostResolverCache:tracked('browser-dns')},managementSession:{closeAllConnections:tracked('management-close'),setProxy:tracked('management-proxy'),clearHostResolverCache:tracked('management-dns')},app:{configureHostResolver:()=>calls.push({name:'resolver',enabled:diagnostics.status().enabled})},resolverOptions:v=>v,recentRequests:new Map(),tabs:{all:()=>[{security:{developerToolsGuard:{close:()=>{}}},view:{webContents:{closeDevTools:()=>{}}}}]},configureVisualPage:tracked('page'),audit:tracked('audit')});
|
||||
c.localRelay={proxyRules:'127.0.0.1:45678',proxyBypassRules:'<-loopback>',invalidate:tracked('relay-invalidate')};
|
||||
const originalSetProxy=c.browserSession.setProxy;c.browserSession.setProxy=async settings=>{assert.equal(settings.mode,'fixed_servers');assert.equal(settings.proxyRules,c.localRelay.proxyRules);assert.equal(settings.proxyBypassRules,'<-loopback>');await originalSetProxy(settings);};
|
||||
vm.runInContext(extracted,c);return {c,next,envelope,calls,diagnostics,payloads,spans:()=>payloads.flatMap(v=>v.resourceSpans||[]).flatMap(v=>v.scopeSpans||[]).flatMap(v=>v.spans||[])};
|
||||
@@ -43,3 +43,18 @@ test('enabled new policy exports only post-configuration stages after protected
|
||||
test('signed verification failure prevents bookmark, proxy and policy mutations',async t=>{
|
||||
const f=await fixture(t);const tampered=f.envelope();tampered.payload+='A';await assert.rejects(f.c.applyPolicy(tampered),/signature rejected/);await f.diagnostics.flush();assert.equal(f.calls.length,0);assert.equal(f.c.policy.version,1);assert.ok(f.spans().some(s=>s.status.code===2));
|
||||
});
|
||||
|
||||
test('verified policy-only update keeps identical telemetry authorization throughout the transition',async t=>{
|
||||
const f=await fixture(t);f.c.policy=structuredClone(f.next);f.next.version=2;
|
||||
await f.c.applyPolicy(f.envelope());await f.diagnostics.flush();
|
||||
assert.ok(f.calls.filter(v=>v.name==='configure').every(v=>v.enabled===true));
|
||||
for(const name of ['browser-close','browser-proxy','management-close','management-proxy','browser-dns','management-dns','credential-revoke','resolver','save','page','agent','audit'])assert.equal(f.calls.find(v=>v.name===name).enabled,true,name);
|
||||
assert.equal(f.c.policy.version,2);assert.equal(f.diagnostics.status().lifetimeFailedExports,0);
|
||||
});
|
||||
|
||||
test('expired previous policy cannot preserve telemetry authorization even with identical collector settings',async t=>{
|
||||
const f=await fixture(t);f.c.policy={...structuredClone(f.next),expiresAt:new Date(Date.now()-1000).toISOString()};f.next.version=2;
|
||||
await f.c.applyPolicy(f.envelope());await f.diagnostics.flush();
|
||||
assert.equal(f.calls.find(v=>v.name==='browser-proxy').enabled,false);
|
||||
assert.deepEqual(f.calls.filter(v=>v.name==='configure').map(v=>v.enabled),[false,true]);
|
||||
});
|
||||
Reference in new issue
Block a user