Capture guarded human gestures and verify agent administration

This commit is contained in:
Karl committed 2026-10-13 18:24:44 +02:00
1 parent 244f01630b
commit adf0940e5f
32 files changed
+523 -52

No files matched your search

+7 -4
View File
@@ -37,11 +37,14 @@ function includesCredential(payload){
function sourceMatches(source,payload,type){
let metadata;try{metadata=JSON.parse(source.metadata);}catch{return false;}
if(type==='interaction'){
if(payload.outcome!=='completed'||!payload.sessionId)return false;
if(source.kind==='agent.action'){
if(!payload.sessionId)return false;
if(source.kind==='browser.interaction'){
if(payload.captureSource!=='human-observer'||payload.outcome!=='observed'||!['click','submit'].includes(payload.action)||metadata.interaction?.action!==payload.action||metadata.interaction?.outcome!=='observed'||metadata.interaction?.sessionId!==payload.sessionId)return false;
}else if(source.kind==='agent.action'){
if(payload.outcome!=='completed')return false;
if(payload.captureSource!=='agent-adapter'||metadata.agent?.action!=='click'||metadata.agent.outcome!=='completed'||payload.action!=='click'||metadata.agent.sessionId!==payload.sessionId)return false;
}else{
if(payload.captureSource!=='guarded-clipboard'||!['clipboard.copy','clipboard.cut','clipboard.paste'].includes(source.kind)||payload.action!==source.kind.split('.')[1]||metadata.interaction?.action!==payload.action||metadata.interaction?.outcome!=='completed'||metadata.interaction?.sessionId!==payload.sessionId)return false;
if(payload.outcome!=='completed'||payload.captureSource!=='guarded-clipboard'||!['clipboard.copy','clipboard.cut','clipboard.paste'].includes(source.kind)||payload.action!==source.kind.split('.')[1]||metadata.interaction?.action!==payload.action||metadata.interaction?.outcome!=='completed'||metadata.interaction?.sessionId!==payload.sessionId)return false;
}
}
if(type==='download'&&source.kind==='download.released'&&payload.decision!=='allow'||type==='download'&&source.kind==='download.block'&&payload.decision!=='block')return false;
@@ -71,7 +74,7 @@ export function installEvidence(app,store,config,device,admin){
if(Date.parse(policy.expiresAt)<=Date.now()||!policy.evidence.enabled||b.type==='download'&&!policy.evidence.captureDownloads||b.type==='interaction'&&!policy.evidence.captureInteractions)return res.status(403).json({error:'Evidence collection is disabled by current policy'});
const payload=(b.type==='interaction'?InteractionEvidenceSchema:payloads[b.type]).parse(b.payload);if(includesCredential(payload))return res.status(400).json({error:'Recognizable credentials are excluded from evidence'});plain=Buffer.from(JSON.stringify(payload));if(plain.length>65536)return res.status(413).json({error:'Evidence too large'});
const source=db.prepare('SELECT id,kind,metadata FROM events WHERE device_id=? AND json_extract(metadata,\'$.eventId\')=?').get(req.device.id,b.eventId);if(!source)return res.status(404).json({error:'Own source event not found'});
const matching=b.type==='download'?['download.scan','download.released','download.block']:['clipboard.copy','clipboard.cut','clipboard.paste','agent.action'];if(!matching.includes(source.kind))return res.status(400).json({error:'Evidence type does not match source event'});
const matching=b.type==='download'?['download.scan','download.released','download.block']:['clipboard.copy','clipboard.cut','clipboard.paste','agent.action','browser.interaction'];if(!matching.includes(source.kind))return res.status(400).json({error:'Evidence type does not match source event'});
if(!sourceMatches(source,payload,b.type))return res.status(400).json({error:'Evidence facts contradict the source event'});
const prior=db.prepare('SELECT * FROM protected_evidence WHERE source_event_id=? AND type=?').get(source.id,b.type);if(prior){
let same=false;try{if(prior.key_id===keyId){const priorPlain=decryptStoredEvidence(prior,key);try{same=JSON.stringify(JSON.parse(priorPlain.toString('utf8')))===JSON.stringify(payload);}finally{priorPlain.fill(0);}}}catch{}