/** * VulnForge MCP - Autonomous Kernel Capability Revocation & Ephemeral Syscall Confinement Synthesizer * @module capability_revocation/capability_revocation_audit * * Implements static and dynamic architectural security auditing for: * 1. VF-CAPREV-001 (CRITICAL, CWE-250/CWE-269): Unrestricted Ambient Linux Capabilities & Missing Ephemeral Capability Dropping * 2. VF-CAPREV-002 (CRITICAL, CWE-284/CWE-693): Inadequate Landlock LSM Filesystem Confinement & Unrestricted Path Traversal * 3. VF-CAPREV-003 (CRITICAL, CWE-754/CWE-653): Unenforced eBPF LSM Syscall Confinement & Missing LSM Probes * 4. VF-CAPREV-004 (HIGH, CWE-276/CWE-281): Permissive Inherited File Descriptor & Socket Capability Leakage * 5. VF-CAPREV-005 (HIGH, CWE-400/CWE-770): Absent Ephemeral Process Lifetime Quotas & Missing cgroups v2 Kernel Resource Confinement * 6. VF-CAPREV-006 (HIGH, CWE-385/CWE-362): Time-of-Check to Time-of-Use (TOCTOU) Capability Restoration Race * 7. VF-CAPREV-007 (HIGH, CWE-778/CWE-754): Unaudited Capability Transition Events & Missing Tamper-Evident Confinement Audit Logging * 8. VF-CAPREV-008 (HIGH, CWE-284/CWE-732): Fail-Open Kernel Capability Fallback on Unsupported LSM Environment */ import { FuzzMutationCase, CapabilityRevocationArtifactFormat, CapabilityRevocationAuditInput, CapabilityRevocationAuditResult, CapabilityRevocationAuditSummary, CapabilityRevocationFindingCode, CapabilityRevocationSecurityPolicy, PatchRecommendation, SecurityFinding } from '../types/index.js'; export const DEFAULT_CAPABILITY_REVOCATION_POLICY: CapabilityRevocationSecurityPolicy = { policyVersion: '1.40.0', capabilityDropping: { enforceCapabilityDrop: true, clearAmbientCapabilities: true, dropBoundingSet: true, allowedCapabilities: [], disallowRootCapabilities: true }, landlockLsmConfinement: { enforceLandlockRuleset: true, abiVersion: 3, enforceNoNewPrivs: true, readOnlyPaths: ['/usr', '/lib', '/etc/ssl'], readWritePaths: ['/tmp/agent-ephemeral'], deniedPaths: ['/proc/sys', '/sys', '/root'], disallowExecutablePaths: true }, ebpfLsmHooks: { enforceEbpfLsmHooks: true, monitoredHooks: ['file_open', 'socket_connect', 'task_prctl', 'bpf'], blockUnauthorizedSockets: true, blockRawSockets: true, blockPrivilegedSyscalls: true }, fdCloexecSanitization: { enforceFdCloexec: true, closeInheritedFds: true, maxFdToPreserve: 2, disallowLeakedSockets: true }, cgroupsResourceConfinement: { enforceCgroupsLimits: true, maxPids: 64, maxMemoryBytes: 2147483648, cpuQuotaUs: 100000, executionTimeoutSeconds: 300 }, atomicPrivilegeTransition: { enforceAtomicTransition: true, enforceSecurebits: true, securebitsFlags: ['SECBIT_NOROOT', 'SECBIT_NO_SETUID_FIXUP', 'SECBIT_NOROOT_LOCKED'], synchronizeThreadPrivileges: true }, auditTrailVerification: { cryptographicEventChaining: true, hashAlgorithm: 'SHA-256', logCapabilityTransitions: true, failSecureOnAuditTampering: true }, failClosedPosture: { failClosedOnUnsupportedLsm: true, requireLandlockSupport: true, requireEbpfLsmSupport: true, abortOnDegradedEnvironment: true } }; /** * Detects whether content belongs to Kernel Capability Revocation & Ephemeral Syscall Confinement artifacts. */ export function isCapabilityRevocationContent(content: string): boolean { if (!content) return false; const c = content.toLowerCase(); return ( c.includes('capability_revocation') || c.includes('capabilityrevocation') || c.includes('landlock') || c.includes('landlock_create_ruleset') || c.includes('landlock_restrict_self') || c.includes('cap_set_proc') || c.includes('pr_cap_ambient_clear_all') || c.includes('pr_set_no_new_privs') || c.includes('ebpf_lsm') || c.includes('bpf_lsm') || c.includes('fd_cloexec') || c.includes('o_cloexec') || c.includes('confinement_manifest') || c.includes('cgroupsresourceconfinement') || c.includes('capabilitydropping') || c.includes('landlocklsmconfinement') || c.includes('failclosedposture') ); } /** * Detects artifact format of Capability Revocation & Ephemeral Syscall Confinement specs. */ export function detectCapabilityRevocationFormat( content: string, filePath?: string ): CapabilityRevocationArtifactFormat { if (filePath) { const lower = filePath.toLowerCase(); if (lower.endsWith('.landlock') || lower.includes('landlock')) return 'LANDLOCK_RULES'; if (lower.endsWith('.lsm.c') || lower.includes('ebpf_lsm') || lower.includes('bpf_lsm')) return 'EBPF_LSM_POLICY'; if (lower.includes('cap_drop') || lower.includes('capability')) return 'CAPABILITY_DROP_SPEC'; if (lower.includes('confinement') || lower.includes('confinement_manifest')) return 'CONFINEMENT_MANIFEST'; } const c = content.toLowerCase(); if (c.includes('landlock_create_ruleset') || c.includes('landlock_access_fs') || c.includes('landlock_ruleset_attr')) { return 'LANDLOCK_RULES'; } if (c.includes('sec("lsm/') || c.includes('bpf_lsm_') || c.includes('bpf_prog_type_lsm')) { return 'EBPF_LSM_POLICY'; } if (c.includes('pr_cap_ambient_clear_all') || c.includes('cap_set_proc') || c.includes('allowedcapabilities')) { return 'CAPABILITY_DROP_SPEC'; } if (c.includes('confinement_manifest') || c.includes('confinementmanifest') || c.includes('cgroupsresourceconfinement')) { return 'CONFINEMENT_MANIFEST'; } if (content.trim().startsWith('{') || content.trim().startsWith('[')) { return 'JSON'; } if (content.includes('---') || (content.includes(':') && !content.includes(';'))) { return 'YAML'; } return 'UNKNOWN'; } /** * Synthesizes a hardened Capability Revocation & Ephemeral Syscall Confinement policy from partial configuration. */ export function synthesizeCapabilityRevocationPolicyFromConfig( config?: Partial ): CapabilityRevocationSecurityPolicy { return { policyVersion: config?.policyVersion || DEFAULT_CAPABILITY_REVOCATION_POLICY.policyVersion, capabilityDropping: { ...DEFAULT_CAPABILITY_REVOCATION_POLICY.capabilityDropping, ...(config?.capabilityDropping || {}) }, landlockLsmConfinement: { ...DEFAULT_CAPABILITY_REVOCATION_POLICY.landlockLsmConfinement, ...(config?.landlockLsmConfinement || {}) }, ebpfLsmHooks: { ...DEFAULT_CAPABILITY_REVOCATION_POLICY.ebpfLsmHooks, ...(config?.ebpfLsmHooks || {}) }, fdCloexecSanitization: { ...DEFAULT_CAPABILITY_REVOCATION_POLICY.fdCloexecSanitization, ...(config?.fdCloexecSanitization || {}) }, cgroupsResourceConfinement: { ...DEFAULT_CAPABILITY_REVOCATION_POLICY.cgroupsResourceConfinement, ...(config?.cgroupsResourceConfinement || {}) }, atomicPrivilegeTransition: { ...DEFAULT_CAPABILITY_REVOCATION_POLICY.atomicPrivilegeTransition, ...(config?.atomicPrivilegeTransition || {}) }, auditTrailVerification: { ...DEFAULT_CAPABILITY_REVOCATION_POLICY.auditTrailVerification, ...(config?.auditTrailVerification || {}) }, failClosedPosture: { ...DEFAULT_CAPABILITY_REVOCATION_POLICY.failClosedPosture, ...(config?.failClosedPosture || {}) } }; } export const synthesizeCapabilityRevocationSecurityPolicy = synthesizeCapabilityRevocationPolicyFromConfig; /** * Generates an adversarial mutation fuzz suite for Capability Revocation & Ephemeral Syscall Confinement testing. */ export function generateCapabilityRevocationFuzzSuite( basePolicy?: Partial ): FuzzMutationCase[] { const policy = synthesizeCapabilityRevocationPolicyFromConfig(basePolicy); const fuzzCases: FuzzMutationCase[] = [ { id: 'FUZZ-CAPREV-001', field: 'capabilityDropping.enforceCapabilityDrop', mutationType: 'STATE_INJECTION', payload: { enforceCapabilityDrop: false, clearAmbientCapabilities: false, allowedCapabilities: ['CAP_SYS_ADMIN'] }, description: 'Retain ambient Linux capabilities and skip prctl ambient clear', expectedStatus: 400 }, { id: 'FUZZ-CAPREV-002', field: 'landlockLsmConfinement.enforceLandlockRuleset', mutationType: 'STATE_INJECTION', payload: { enforceLandlockRuleset: false, enforceNoNewPrivs: false, readWritePaths: ['/'] }, description: 'Disable Landlock ruleset enforcement and permit root filesystem write access', expectedStatus: 400 }, { id: 'FUZZ-CAPREV-003', field: 'ebpfLsmHooks.enforceEbpfLsmHooks', mutationType: 'STATE_INJECTION', payload: { enforceEbpfLsmHooks: false, blockUnauthorizedSockets: false }, description: 'Disable eBPF LSM syscall hook interception allowing arbitrary sockets', expectedStatus: 400 }, { id: 'FUZZ-CAPREV-004', field: 'fdCloexecSanitization.enforceFdCloexec', mutationType: 'STATE_INJECTION', payload: { enforceFdCloexec: false, closeInheritedFds: false, maxFdToPreserve: 1024 }, description: 'Disable FD_CLOEXEC allowing child processes to inherit privileged descriptors', expectedStatus: 400 }, { id: 'FUZZ-CAPREV-005', field: 'cgroupsResourceConfinement.enforceCgroupsLimits', mutationType: 'STATE_INJECTION', payload: { enforceCgroupsLimits: false, maxPids: 999999 }, description: 'Remove cgroups v2 process table boundaries risking runaway fork bombs', expectedStatus: 400 }, { id: 'FUZZ-CAPREV-006', field: 'atomicPrivilegeTransition.enforceAtomicTransition', mutationType: 'STATE_INJECTION', payload: { enforceAtomicTransition: false, enforceSecurebits: false }, description: 'Omit securebits locks allowing threads to re-acquire root privileges across execve', expectedStatus: 400 }, { id: 'FUZZ-CAPREV-007', field: 'auditTrailVerification.cryptographicEventChaining', mutationType: 'STATE_INJECTION', payload: { cryptographicEventChaining: false, logCapabilityTransitions: false }, description: 'Disable cryptographic SHA-256 hash chaining on capability transition audit events', expectedStatus: 400 }, { id: 'FUZZ-CAPREV-008', field: 'failClosedPosture.failClosedOnUnsupportedLsm', mutationType: 'STATE_INJECTION', payload: { failClosedOnUnsupportedLsm: false, abortOnDegradedEnvironment: false }, description: 'Permit unconfined fail-open execution on unsupported kernel LSM host environments', expectedStatus: 400 } ]; return fuzzCases; } /** * Conducts static and dynamic architectural security audits for Kernel Capability Revocation & Ephemeral Syscall Confinement. */ export async function auditCapabilityRevocationSecurity( input: CapabilityRevocationAuditInput ): Promise { const content = input.content || ''; const filePath = input.filePath || 'confinement_policy.json'; const format = input.format || detectCapabilityRevocationFormat(content, filePath); const findings: SecurityFinding[] = []; const patchRecommendations: PatchRecommendation[] = []; let parsedConfig: any = null; try { parsedConfig = JSON.parse(content); } catch { parsedConfig = null; } const raw = content.toLowerCase(); // Helper check functions const has = (key: string): boolean => raw.includes(key.toLowerCase()); const hasInConfig = (path: string[], expectedVal?: any): boolean => { if (!parsedConfig) return false; let curr = parsedConfig; for (const p of path) { if (curr && typeof curr === 'object' && p in curr) { curr = curr[p]; } else { return false; } } if (expectedVal !== undefined) { return curr === expectedVal; } return Boolean(curr); }; // 1. VF-CAPREV-001 (CRITICAL, CWE-250/CWE-269): Unrestricted Ambient Linux Capabilities & Missing Ephemeral Capability Dropping const retainsAmbientCaps = hasInConfig(['capabilityDropping', 'clearAmbientCapabilities'], false) || hasInConfig(['capabilityDropping', 'enforceCapabilityDrop'], false) || has('allow_ambient_capabilities: true') || has('clear_ambient_capabilities: false') || has('cap_sys_admin') || has('cap_net_admin') || (parsedConfig?.capabilityDropping?.allowedCapabilities && parsedConfig.capabilityDropping.allowedCapabilities.some((cap: string) => ['CAP_SYS_ADMIN', 'CAP_NET_ADMIN', 'CAP_SYS_PTRACE', 'CAP_DAC_OVERRIDE', 'CAP_SYS_RAWIO'].includes( cap.toUpperCase() ) )) || (!has('pr_cap_ambient_clear_all') && !has('clearambientcapabilities') && !hasInConfig(['capabilityDropping', 'clearAmbientCapabilities'], true)); if (retainsAmbientCaps) { findings.push({ id: 'VF-CAPREV-001', findingCode: 'VF-CAPREV-001', title: 'Unrestricted Ambient Linux Capabilities & Missing Ephemeral Capability Dropping', severity: 'CRITICAL', category: 'kernel_capability_revocation', cwe: 'CWE-250', target: filePath, description: 'The process does not deterministically drop ambient or bounding Linux capabilities after initialization. Retaining high-privilege capabilities (e.g., CAP_SYS_ADMIN, CAP_NET_ADMIN) allows compromised AI agent subprocesses to perform privileged operations or escape container boundaries.', evidence: parsedConfig?.capabilityDropping ? `capabilityDropping: ${JSON.stringify(parsedConfig.capabilityDropping)}` : 'Missing PR_CAP_AMBIENT_CLEAR_ALL or cap_set_proc capability reduction routine', impact: 'Compromised child processes inherit dangerous administrative capabilities, leading to complete host/container compromise.', remediation: 'Invoke prctl(PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0, 0) and cap_set_proc() immediately after process startup, ensuring an empty ambient capability set.', patchRecommendation: { patchType: 'capability_dropping_enforce', targetFile: filePath, description: 'Drop all ambient and bounding capabilities via PR_CAP_AMBIENT_CLEAR_ALL and cap_set_proc().' } }); } // 2. VF-CAPREV-002 (CRITICAL, CWE-284/CWE-693): Inadequate Landlock LSM Filesystem Confinement & Unrestricted Path Traversal const lacksLandlockConfinement = hasInConfig(['landlockLsmConfinement', 'enforceLandlockRuleset'], false) || hasInConfig(['landlockLsmConfinement', 'enforceNoNewPrivs'], false) || has('enforce_landlock_ruleset: false') || has('enforce_no_new_privs: false') || (parsedConfig?.landlockLsmConfinement?.readWritePaths && parsedConfig.landlockLsmConfinement.readWritePaths.includes('/')) || (!has('landlock_create_ruleset') && !has('landlocklsmconfinement') && !hasInConfig(['landlockLsmConfinement', 'enforceLandlockRuleset'], true)); if (lacksLandlockConfinement) { findings.push({ id: 'VF-CAPREV-002', findingCode: 'VF-CAPREV-002', title: 'Inadequate Landlock LSM Filesystem Confinement & Unrestricted Path Traversal', severity: 'CRITICAL', category: 'landlock_filesystem_confinement', cwe: 'CWE-284', target: filePath, description: 'Filesystem confinement via Linux Landlock LSM is missing or misconfigured. Running without PR_SET_NO_NEW_PRIVS or with unconstrained root directory write access exposes the host system to arbitrary file overwriting and path traversal.', evidence: parsedConfig?.landlockLsmConfinement ? `landlockLsmConfinement: ${JSON.stringify(parsedConfig.landlockLsmConfinement)}` : 'Missing landlock_create_ruleset or landlock_restrict_self invocation', impact: 'Autonomous AI agents can traverse host directory hierarchies, overwrite critical binaries, and persist malicious artifacts.', remediation: 'Define explicit Landlock ABI v3 rulesets restricting read-only hierarchies to dependency directories and isolated ephemeral write paths, preceded by prctl(PR_SET_NO_NEW_PRIVS, 1).', patchRecommendation: { patchType: 'landlock_ruleset_enforce', targetFile: filePath, description: 'Apply strict Landlock filesystem confinement ruleset with isolated ephemeral read/write boundaries.' } }); } // 3. VF-CAPREV-003 (CRITICAL, CWE-754/CWE-653): Unenforced eBPF LSM Syscall Confinement & Missing LSM Probes const lacksEbpfLsm = hasInConfig(['ebpfLsmHooks', 'enforceEbpfLsmHooks'], false) || hasInConfig(['ebpfLsmHooks', 'blockUnauthorizedSockets'], false) || has('enforce_ebpf_lsm_hooks: false') || has('block_unauthorized_sockets: false') || (!has('bpf_lsm_') && !has('ebpflsmhooks') && !hasInConfig(['ebpfLsmHooks', 'enforceEbpfLsmHooks'], true)); if (lacksEbpfLsm) { findings.push({ id: 'VF-CAPREV-003', findingCode: 'VF-CAPREV-003', title: 'Unenforced eBPF LSM Syscall Confinement & Missing LSM Probes', severity: 'CRITICAL', category: 'ebpf_lsm_syscall_confinement', cwe: 'CWE-754', target: filePath, description: 'The execution environment does not attach eBPF LSM hooks to sensitive kernel syscall checkpoints (file_open, socket_connect, task_prctl, bpf), permitting arbitrary raw socket creation or unconfined syscall invocation.', evidence: parsedConfig?.ebpfLsmHooks ? `ebpfLsmHooks: ${JSON.stringify(parsedConfig.ebpfLsmHooks)}` : 'Missing eBPF LSM attachment hooks on sensitive kernel operations', impact: 'Agent workloads can establish unauthorized outbound network sockets or load malicious unverified eBPF programs.', remediation: 'Attach eBPF LSM hooks to intercept security_socket_connect, security_file_open, and security_task_prctl, enforcing strict protocol denylists.', patchRecommendation: { patchType: 'ebpf_lsm_hooks_enforce', targetFile: filePath, description: 'Attach eBPF LSM hooks to deny unconfined socket connections and privileged syscalls.' } }); } // 4. VF-CAPREV-004 (HIGH, CWE-276/CWE-281): Permissive Inherited File Descriptor & Socket Capability Leakage const leaksFds = hasInConfig(['fdCloexecSanitization', 'enforceFdCloexec'], false) || hasInConfig(['fdCloexecSanitization', 'closeInheritedFds'], false) || has('enforce_fd_cloexec: false') || has('close_inherited_fds: false') || (parsedConfig?.fdCloexecSanitization?.maxFdToPreserve !== undefined && parsedConfig.fdCloexecSanitization.maxFdToPreserve > 2) || (!has('fd_cloexec') && !has('o_cloexec') && !hasInConfig(['fdCloexecSanitization', 'enforceFdCloexec'], true)); if (leaksFds) { findings.push({ id: 'VF-CAPREV-004', findingCode: 'VF-CAPREV-004', title: 'Permissive Inherited File Descriptor & Socket Capability Leakage', severity: 'HIGH', category: 'fd_cloexec_leakage', cwe: 'CWE-276', target: filePath, description: 'File descriptors allocated by the parent runtime do not enforce FD_CLOEXEC, allowing child agent processes to inherit active database connections, IPC pipes, or administrative sockets.', evidence: parsedConfig?.fdCloexecSanitization ? `fdCloexecSanitization: ${JSON.stringify(parsedConfig.fdCloexecSanitization)}` : 'Missing FD_CLOEXEC flags on allocated file descriptors and inherited sockets', impact: 'Child processes can read, write, or hijack communication channels established by the parent orchestrator.', remediation: 'Apply O_CLOEXEC / SOCK_CLOEXEC on all descriptor allocations and close all file descriptors greater than STDERR_FILENO prior to executing subcommands.', patchRecommendation: { patchType: 'fd_cloexec_enforce', targetFile: filePath, description: 'Set FD_CLOEXEC on all descriptors and close inherited non-standard descriptors before exec.' } }); } // 5. VF-CAPREV-005 (HIGH, CWE-400/CWE-770): Absent Ephemeral Process Lifetime Quotas & Missing cgroups v2 Kernel Resource Confinement const lacksCgroups = hasInConfig(['cgroupsResourceConfinement', 'enforceCgroupsLimits'], false) || has('enforce_cgroups_limits: false') || (parsedConfig?.cgroupsResourceConfinement?.maxPids !== undefined && parsedConfig.cgroupsResourceConfinement.maxPids > 256) || (!has('cgroups') && !has('pids.max') && !hasInConfig(['cgroupsResourceConfinement', 'enforceCgroupsLimits'], true)); if (lacksCgroups) { findings.push({ id: 'VF-CAPREV-005', findingCode: 'VF-CAPREV-005', title: 'Absent Ephemeral Process Lifetime Quotas & Missing cgroups v2 Kernel Resource Confinement', severity: 'HIGH', category: 'cgroups_resource_confinement', cwe: 'CWE-400', target: filePath, description: 'Autonomous AI agent processes run without cgroups v2 slice boundaries (pids.max, memory.high, cpu.max). Unmetered agent execution can result in fork-bomb exhaustion or runaway memory consumption.', evidence: parsedConfig?.cgroupsResourceConfinement ? `cgroupsResourceConfinement: ${JSON.stringify(parsedConfig.cgroupsResourceConfinement)}` : 'Missing cgroups v2 resource controller bindings (pids.max, memory.max)', impact: 'Runaway or hostile agent child tasks can deplete host process tables and memory, inducing node-wide Denial of Service.', remediation: 'Enforce cgroups v2 resource confinement setting pids.max <= 64, memory.high <= 2GB, and bind process execution to bounded lifetime watchdogs.', patchRecommendation: { patchType: 'cgroups_confinement_enforce', targetFile: filePath, description: 'Bind agent execution to cgroups v2 with strict pids.max and memory limits.' } }); } // 6. VF-CAPREV-006 (HIGH, CWE-385/CWE-362): Time-of-Check to Time-of-Use (TOCTOU) Capability Restoration Race const vulnerableToctou = hasInConfig(['atomicPrivilegeTransition', 'enforceAtomicTransition'], false) || hasInConfig(['atomicPrivilegeTransition', 'enforceSecurebits'], false) || has('enforce_atomic_transition: false') || has('enforce_securebits: false') || (parsedConfig?.atomicPrivilegeTransition?.securebitsFlags && parsedConfig.atomicPrivilegeTransition.securebitsFlags.length === 0) || (!has('securebits') && !has('secbit_noroot') && !hasInConfig(['atomicPrivilegeTransition', 'enforceAtomicTransition'], true)); if (vulnerableToctou) { findings.push({ id: 'VF-CAPREV-006', findingCode: 'VF-CAPREV-006', title: 'Time-of-Check to Time-of-Use (TOCTOU) Capability Restoration Race', severity: 'HIGH', category: 'toctou_privilege_restoration', cwe: 'CWE-385', target: filePath, description: 'Privilege transitions are not executed atomically across all task threads or omit locked securebits (SECBIT_NOROOT_LOCKED, SECBIT_NO_SETUID_FIXUP_LOCKED), permitting capability re-acquisition across execve or thread cloning.', evidence: parsedConfig?.atomicPrivilegeTransition ? `atomicPrivilegeTransition: ${JSON.stringify(parsedConfig.atomicPrivilegeTransition)}` : 'Missing PR_SET_SECUREBITS lock flags and thread synchronization', impact: 'Threads can exploit transition latency windows to re-elevate capabilities or execute setuid binaries.', remediation: 'Lock securebits flags (SECBIT_NOROOT | SECBIT_NOROOT_LOCKED | SECBIT_NO_SETUID_FIXUP_LOCKED) and ensure atomic capability transition synchronization across threads.', patchRecommendation: { patchType: 'securebits_lock_enforce', targetFile: filePath, description: 'Lock securebits flags and enforce atomic process-wide privilege transitions.' } }); } // 7. VF-CAPREV-007 (HIGH, CWE-778/CWE-754): Unaudited Capability Transition Events & Missing Tamper-Evident Confinement Audit Logging const lacksAuditTrail = hasInConfig(['auditTrailVerification', 'cryptographicEventChaining'], false) || hasInConfig(['auditTrailVerification', 'logCapabilityTransitions'], false) || has('cryptographic_event_chaining: false') || has('log_capability_transitions: false') || (!has('cryptographiceventchaining') && !has('logcapabilitytransitions') && !hasInConfig(['auditTrailVerification', 'cryptographicEventChaining'], true)); if (lacksAuditTrail) { findings.push({ id: 'VF-CAPREV-007', findingCode: 'VF-CAPREV-007', title: 'Unaudited Capability Transition Events & Missing Tamper-Evident Confinement Audit Logging', severity: 'HIGH', category: 'confinement_audit_trail', cwe: 'CWE-778', target: filePath, description: 'Capability drops, Landlock rule applications, and eBPF LSM denials are executed without cryptographically verifiable hash chaining, preventing forensic validation and audit integrity.', evidence: parsedConfig?.auditTrailVerification ? `auditTrailVerification: ${JSON.stringify(parsedConfig.auditTrailVerification)}` : 'Missing cryptographic hash-chained audit telemetry for confinement transitions', impact: 'Security incidents cannot be attributed or audited, and hostile privilege escalation attempts remain unrecorded.', remediation: 'Implement tamper-evident SHA-256 chained audit event logging for all capability transitions and Landlock LSM violations.', patchRecommendation: { patchType: 'audit_trail_chain_enforce', targetFile: filePath, description: 'Enable cryptographic SHA-256 hash chaining on capability and LSM transition audit logs.' } }); } // 8. VF-CAPREV-008 (HIGH, CWE-284/CWE-732): Fail-Open Kernel Capability Fallback on Unsupported LSM Environment const failOpenFallback = hasInConfig(['failClosedPosture', 'failClosedOnUnsupportedLsm'], false) || hasInConfig(['failClosedPosture', 'abortOnDegradedEnvironment'], false) || has('fail_closed_on_unsupported_lsm: false') || has('abort_on_degraded_environment: false') || (!has('failclosedonunsupportedlsm') && !has('abortondegradedenvironment') && !hasInConfig(['failClosedPosture', 'failClosedOnUnsupportedLsm'], true)); if (failOpenFallback) { findings.push({ id: 'VF-CAPREV-008', findingCode: 'VF-CAPREV-008', title: 'Fail-Open Kernel Capability Fallback on Unsupported LSM Environment', severity: 'HIGH', category: 'fail_closed_lsm_posture', cwe: 'CWE-284', target: filePath, description: 'The confinement policy permits fail-open execution if the underlying kernel lacks Landlock or eBPF LSM support, allowing autonomous AI agents to run unconfined in degraded host environments.', evidence: parsedConfig?.failClosedPosture ? `failClosedPosture: ${JSON.stringify(parsedConfig.failClosedPosture)}` : 'Missing fail-closed assertion on unsupported kernel LSM capabilities', impact: 'Agents deployed on older or stripped host kernels execute with unconfined privileges without administrative warning.', remediation: 'Set failClosedOnUnsupportedLsm: true to immediately abort process initialization if required LSM subsystems are uninitialized or unsupported.', patchRecommendation: { patchType: 'fail_closed_lsm_posture_enforce', targetFile: filePath, description: 'Enforce strict fail-closed termination when required kernel LSM subsystems are unavailable.' } }); } // Calculate audit score & summary const totalChecks = 8; const findingsCount = findings.length; const passedChecks = totalChecks - findingsCount; const score = Math.max(0, Math.round((passedChecks / totalChecks) * 100)); const critical = findings.filter((f) => f.severity === 'CRITICAL').length; const high = findings.filter((f) => f.severity === 'HIGH').length; const medium = findings.filter((f) => f.severity === 'MEDIUM').length; const low = findings.filter((f) => f.severity === 'LOW').length; const passed = findingsCount === 0; const complianceStatus = critical > 0 || high > 0 ? 'FAIL' : medium > 0 ? 'WARN' : 'PASS'; const attestationStatus = passed ? 'VERIFIED_SECURE' : 'ATTESTATION_FAILED'; const summary: CapabilityRevocationAuditSummary = { score, totalChecks, passedChecks, findingsCount, severityCounts: { critical, high, medium, low }, format, complianceStatus, passed, capabilityDropEnforced: !retainsAmbientCaps, landlockConfinementAttested: !lacksLandlockConfinement, ebpfLsmHooksVerified: !lacksEbpfLsm, fdCloexecSanitized: !leaksFds, cgroupsLimitsBound: !lacksCgroups, atomicTransitionEnforced: !vulnerableToctou, auditTrailChained: !lacksAuditTrail, failClosedPostureGuaranteed: !failOpenFallback }; const recommendedPolicy = synthesizeCapabilityRevocationPolicyFromConfig(parsedConfig || {}); return { targetFile: filePath, findings, summary, recommendedPolicy, patchRecommendations, passed, complianceStatus, attestationStatus, fuzzCasesGenerated: 8 }; }