Implement managed browser security, individual agents and observability
This commit is contained in:
1 parent
ff482ebe23
commit
ea448de2d4
172 files changed
+5404
-347
No files matched your search
@@ -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};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user