use super::ambient::{AmbientCategory, AmbientFinding, KNOWN_FINDINGS, Severity};
use crate::cx::Cx;
use crate::error::{Error, ErrorKind};
use crate::types::RegionId;
use std::collections::HashSet;
use std::time::Instant;
#[derive(Debug, Clone)]
pub struct MetaAuditor {
pub region_id: RegionId,
pub audit_domain: AuditDomain,
pub last_validated: Instant,
pub findings_hash: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AuditDomain {
Collection,
Validation,
Meta,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum CapabilityEscalationResult {
Clean,
FindingsTampered {
expected_hash: u64,
actual_hash: u64,
suspicious_entries: Vec<String>,
},
CrossRegionEscalation {
audit_region: RegionId,
target_region: RegionId,
violation_type: String,
},
AuditAccumulation {
violations: Vec<AmbientCategory>,
affected_functions: Vec<String>,
},
}
impl MetaAuditor {
pub fn new(region_id: RegionId, domain: AuditDomain, now: Instant) -> Self {
let findings_hash = compute_findings_hash(KNOWN_FINDINGS);
Self {
region_id,
audit_domain: domain,
last_validated: now,
findings_hash,
}
}
pub fn validate_audit_capabilities(
&mut self,
cx: &Cx,
target_region: Option<RegionId>,
) -> Result<CapabilityEscalationResult, Error> {
if !self.is_operation_authorized(cx) {
return Err(Error::new(ErrorKind::AdmissionDenied)
.with_message("Meta-audit operation not authorized by region capability context"));
}
let current_hash = compute_findings_hash(KNOWN_FINDINGS);
if current_hash != self.findings_hash {
let suspicious_entries = self.detect_suspicious_findings_changes();
return Ok(CapabilityEscalationResult::FindingsTampered {
expected_hash: self.findings_hash,
actual_hash: current_hash,
suspicious_entries,
});
}
if let Some(target) = target_region {
if target != self.region_id && !self.can_audit_cross_region(cx, target) {
return Ok(CapabilityEscalationResult::CrossRegionEscalation {
audit_region: self.region_id,
target_region: target,
violation_type: "Unauthorized cross-region audit access".to_string(),
});
}
}
let audit_violations = self.scan_audit_code_for_ambient_authority()?;
if !audit_violations.is_empty() {
let affected_functions = self.identify_affected_audit_functions(&audit_violations);
return Ok(CapabilityEscalationResult::AuditAccumulation {
violations: audit_violations,
affected_functions,
});
}
self.last_validated = Instant::now();
Ok(CapabilityEscalationResult::Clean)
}
pub fn enforce_domain_isolation(
&self,
requested_operation: AuditOperation,
) -> Result<(), Error> {
let allowed = match (self.audit_domain, requested_operation) {
(AuditDomain::Collection, AuditOperation::GatherViolations) => true,
(AuditDomain::Collection, AuditOperation::ScanSource) => true,
(AuditDomain::Validation, AuditOperation::ValidateFindings) => true,
(AuditDomain::Validation, AuditOperation::CheckIntegrity) => true,
(AuditDomain::Meta, AuditOperation::AuditAuditors) => true,
(AuditDomain::Meta, AuditOperation::ValidateCapabilities) => true,
_ => false,
};
if !allowed {
return Err(Error::new(ErrorKind::AdmissionDenied).with_message(format!(
"Operation {:?} not allowed in domain {:?} - capability escalation attempt",
requested_operation, self.audit_domain
)));
}
Ok(())
}
pub fn create_constrained_audit_context(
&self,
_cx: &Cx,
target_region: RegionId,
max_privilege: AuditDomain,
) -> Result<MetaAuditor, Error> {
if self.audit_domain != AuditDomain::Meta {
return Err(Error::new(ErrorKind::AdmissionDenied)
.with_message("Only Meta domain can create constrained audit contexts"));
}
let constrained_domain = match max_privilege {
AuditDomain::Meta => AuditDomain::Validation, other => other, };
Ok(MetaAuditor {
region_id: target_region,
audit_domain: constrained_domain,
last_validated: Instant::now(),
findings_hash: self.findings_hash, })
}
fn is_operation_authorized(&self, cx: &Cx) -> bool {
cx.budget().remaining_cost().unwrap_or(0) > 0 }
fn can_audit_cross_region(&self, _cx: &Cx, _target_region: RegionId) -> bool {
self.audit_domain == AuditDomain::Meta
}
fn detect_suspicious_findings_changes(&self) -> Vec<String> {
let mut suspicious = Vec::new();
for finding in KNOWN_FINDINGS {
if finding.exempt && finding.exemption_reason.is_none_or(|r| r.len() < 20) {
suspicious.push(format!(
"{}:{} - Exempt without sufficient justification",
finding.file, finding.line
));
}
if finding.exempt && finding.severity == Severity::Critical {
suspicious.push(format!(
"{}:{} - Critical finding marked exempt",
finding.file, finding.line
));
}
if finding.file.starts_with("audit/") && !finding.exempt {
suspicious.push(format!(
"{}:{} - Audit system has unexempt finding",
finding.file, finding.line
));
}
}
suspicious
}
fn scan_audit_code_for_ambient_authority(&self) -> Result<Vec<AmbientCategory>, Error> {
use super::ambient::{ViolationType, detect_ambient_violations};
let audit_files = ["src/audit/ambient.rs", "src/audit/mod.rs"];
let mut violations = Vec::new();
for file_path in &audit_files {
if let Ok(content) = std::fs::read_to_string(file_path) {
let detected = detect_ambient_violations(&content);
for violation in detected {
if violation.violation_type == ViolationType::DirectUsage {
violations.push(violation.category);
}
}
}
}
let unique_violations: HashSet<_> = violations.into_iter().collect();
Ok(unique_violations.into_iter().collect())
}
fn identify_affected_audit_functions(&self, violations: &[AmbientCategory]) -> Vec<String> {
let mut affected = Vec::new();
for category in violations {
match category {
AmbientCategory::Time => {
affected.push("scan_source".to_string());
affected.push("validate_audit_capabilities".to_string());
}
AmbientCategory::Io => {
affected.push("collect_rs_files".to_string());
affected.push("scan_directory".to_string());
}
AmbientCategory::Output => {
affected.push("format_violations".to_string());
}
_ => {
affected.push(format!("unknown_function_{:?}", category));
}
}
}
let unique_functions: HashSet<_> = affected.into_iter().collect();
unique_functions.into_iter().collect()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AuditOperation {
GatherViolations,
ScanSource,
ValidateFindings,
CheckIntegrity,
AuditAuditors,
ValidateCapabilities,
}
fn compute_findings_hash(findings: &[AmbientFinding]) -> u64 {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
for finding in findings {
finding.file.hash(&mut hasher);
finding.line.hash(&mut hasher);
finding.evidence_pattern.hash(&mut hasher);
finding.exempt.hash(&mut hasher);
let severity_value = match finding.severity {
Severity::Low => 0u8,
Severity::Medium => 1u8,
Severity::High => 2u8,
Severity::Critical => 3u8,
};
severity_value.hash(&mut hasher);
}
hasher.finish()
}
pub fn create_meta_auditor_for_region(region_id: RegionId, cx: &Cx) -> Result<MetaAuditor, Error> {
let auditor = MetaAuditor::new(region_id, AuditDomain::Validation, Instant::now());
if auditor.is_operation_authorized(cx) {
Ok(auditor)
} else {
Err(Error::new(ErrorKind::AdmissionDenied)
.with_message("Not authorized to create meta-auditor in this region"))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::types::RegionId;
use std::time::Instant;
#[test]
fn meta_auditor_creation() {
let region_id = RegionId::new_for_test(1, 0);
let now = Instant::now();
let auditor = MetaAuditor::new(region_id, AuditDomain::Collection, now);
assert_eq!(auditor.region_id, region_id);
assert_eq!(auditor.audit_domain, AuditDomain::Collection);
assert_eq!(auditor.last_validated, now);
assert!(auditor.findings_hash != 0); }
#[test]
fn domain_isolation_enforcement() {
let region_id = RegionId::new_for_test(1, 0);
let now = Instant::now();
let collection_auditor = MetaAuditor::new(region_id, AuditDomain::Collection, now);
let validation_auditor = MetaAuditor::new(region_id, AuditDomain::Validation, now);
let meta_auditor = MetaAuditor::new(region_id, AuditDomain::Meta, now);
assert!(
collection_auditor
.enforce_domain_isolation(AuditOperation::GatherViolations)
.is_ok()
);
assert!(
collection_auditor
.enforce_domain_isolation(AuditOperation::ValidateFindings)
.is_err()
);
assert!(
validation_auditor
.enforce_domain_isolation(AuditOperation::ValidateFindings)
.is_ok()
);
assert!(
validation_auditor
.enforce_domain_isolation(AuditOperation::GatherViolations)
.is_err()
);
assert!(
meta_auditor
.enforce_domain_isolation(AuditOperation::AuditAuditors)
.is_ok()
);
assert!(
meta_auditor
.enforce_domain_isolation(AuditOperation::ValidateCapabilities)
.is_ok()
);
}
#[test]
fn findings_hash_computation() {
let hash1 = compute_findings_hash(KNOWN_FINDINGS);
let hash2 = compute_findings_hash(KNOWN_FINDINGS);
assert_eq!(hash1, hash2);
assert!(hash1 != 0); }
#[test]
fn constrained_context_creation() {
let region_id = RegionId::new_for_test(1, 0);
let target_region = RegionId::new_for_test(2, 0);
let now = Instant::now();
let meta_auditor = MetaAuditor::new(region_id, AuditDomain::Meta, now);
let collection_auditor = MetaAuditor::new(region_id, AuditDomain::Collection, now);
let cx = crate::cx::Cx::for_testing();
assert!(
meta_auditor
.create_constrained_audit_context(&cx, target_region, AuditDomain::Collection)
.is_ok()
);
assert!(
collection_auditor
.create_constrained_audit_context(&cx, target_region, AuditDomain::Collection)
.is_err()
);
}
#[test]
fn cross_region_escalation_detection() {
let audit_region = RegionId::new_for_test(1, 0);
let target_region = RegionId::new_for_test(2, 0);
let now = Instant::now();
let collection_auditor = MetaAuditor::new(audit_region, AuditDomain::Collection, now);
assert!(
!collection_auditor
.can_audit_cross_region(&crate::cx::Cx::for_testing(), target_region)
);
let meta_auditor = MetaAuditor::new(audit_region, AuditDomain::Meta, now);
assert!(meta_auditor.can_audit_cross_region(&crate::cx::Cx::for_testing(), target_region));
}
#[test]
fn suspicious_findings_detection() {
let region_id = RegionId::new_for_test(1, 0);
let now = Instant::now();
let auditor = MetaAuditor::new(region_id, AuditDomain::Meta, now);
let suspicious = auditor.detect_suspicious_findings_changes();
for entry in &suspicious {
assert!(
entry.contains(" - "),
"Suspicious entry should have explanation: {}",
entry
);
}
}
}