Implement managed browser security, individual agents and observability

This commit is contained in:
Karl committed 2026-10-13 16:58:15 +02:00
1 parent ff482ebe23
commit ea448de2d4
172 files changed
+5404 -347

No files matched your search

+6 -3
View File
@@ -4,13 +4,14 @@ import { join } from 'node:path';
import { randomBytes, createHash, generateKeyPairSync } from 'node:crypto';
import { defaultPolicy, signPolicy, PolicySchema } from '../../packages/core/policy.mjs';
import { recordSecurityEvent } from './telemetry.mjs';
import { initializeAuditIntegrity } from './audit-integrity.mjs';
import { evaluateSigma } from '../../packages/core/security.mjs';
import { signBookmarkSnapshot } from '../../packages/core/bookmarks.mjs';
import {applyUserProfiles} from '../../packages/core/user-profiles.mjs';
import {applyPolicyGroups} from '../../packages/core/policy-groups.mjs';
export const token = () => randomBytes(32).toString('base64url');
export const digest = value => createHash('sha256').update(value).digest('hex');
export function openStore(directory) {
export function openStore(directory,{auditSigningKeyFile}={}) {
mkdirSync(directory,{recursive:true,mode:0o700});
const db = new DatabaseSync(join(directory,'safetynet.sqlite'));
db.exec(`PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;
@@ -40,10 +41,12 @@ export function openStore(directory) {
db.prepare('INSERT OR IGNORE INTO policy_group_history(version,groups) VALUES(?,?)').run(getRaw('policy').version,JSON.stringify(getRaw('policyGroups')||[]));
db.prepare('INSERT OR IGNORE INTO user_profile_history(version,configuration) VALUES(?,?)').run(getRaw('policy').version,JSON.stringify(getRaw('userProfiles')||{profiles:[],categories:[]}));
if(!get('installationId'))put('installationId',token());
let auditIntegrity;
try{auditIntegrity=initializeAuditIntegrity(db,{signingKeyFile:auditSigningKeyFile});}catch(error){db.close();throw error;}
function event(device,kind,metadata) {
const time=new Date().toISOString(),records=[];db.exec('SAVEPOINT security_event');
try {
const insert=(eventKind,eventMetadata)=>{const result=db.prepare('INSERT INTO events(time,device_id,kind,metadata) VALUES(?,?,?,?)').run(time,device,eventKind,JSON.stringify(eventMetadata));records.push({kind:eventKind,metadata:eventMetadata,id:String(result.lastInsertRowid)});return Number(result.lastInsertRowid);};
const insert=(eventKind,eventMetadata)=>{const result=db.prepare('INSERT INTO events(time,device_id,kind,metadata) VALUES(?,?,?,?)').run(time,device,eventKind,JSON.stringify(eventMetadata));auditIntegrity.append(db.prepare('SELECT * FROM events WHERE id=?').get(Number(result.lastInsertRowid)));records.push({kind:eventKind,metadata:eventMetadata,id:String(result.lastInsertRowid)});return Number(result.lastInsertRowid);};
const sourceEventId=insert(kind,metadata);
for(const alert of evaluateSigma({kind,metadata},getRaw('policy')?.security?.sigma?.rules||[])) {
db.prepare('INSERT INTO alerts(event_id,rule_id,level,time) VALUES(?,?,?,?)').run(sourceEventId,alert.ruleId,alert.level,time);
@@ -55,7 +58,7 @@ export function openStore(directory) {
}
function personalBookmarks(deviceId){const row=db.prepare('SELECT revision,items FROM bookmarks WHERE device_id=?').get(deviceId);return row?{revision:row.revision,items:JSON.parse(row.items)}:{revision:0,items:[]};}
function effectivePolicy(deviceId){let p=get('policy');if(deviceId){const d=db.prepare('SELECT document_analysis_enabled FROM devices WHERE id=?').get(deviceId);if(d?.document_analysis_enabled!==null&&d?.document_analysis_enabled!==undefined)p.inspection.documentAnalysisEnabled=!!d.document_analysis_enabled;p=PolicySchema.parse(applyPolicyGroups(applyUserProfiles(p,getRaw('userProfiles')||{},db.prepare('SELECT * FROM devices WHERE id=?').get(deviceId)||{id:deviceId}),getRaw('policyGroups')||[],deviceId));}return p;}
return {db,get,getRaw,put,event,effectivePolicy,personalBookmarks,envelope:deviceId=>{const p=effectivePolicy(deviceId),keys=get('keys'),envelope=signPolicy(p,keys.privateKey);if(deviceId)envelope.bookmarks=signBookmarkSnapshot({deviceId,policyVersion:p.version,...personalBookmarks(deviceId),expiresAt:p.expiresAt},keys.privateKey);return envelope;},publicKey:()=>get('keys').publicKey};
return {db,get,getRaw,put,event,auditIntegrity,effectivePolicy,personalBookmarks,envelope:deviceId=>{const p=effectivePolicy(deviceId),keys=get('keys'),envelope=signPolicy(p,keys.privateKey);if(deviceId)envelope.bookmarks=signBookmarkSnapshot({deviceId,policyVersion:p.version,...personalBookmarks(deviceId),expiresAt:p.expiresAt},keys.privateKey);return envelope;},publicKey:()=>get('keys').publicKey};
}