Flush aggregated denial summaries to the gateway via `SubmitPolicyAnalysis`.
(
endpoint: &str,
sandbox_name: &str,
summaries: Vec<denial_aggregator::FlushableDenialSummary>,
)
| 553 | |
| 554 | /// Flush aggregated denial summaries to the gateway via `SubmitPolicyAnalysis`. |
| 555 | async fn flush_proposals_to_gateway( |
| 556 | endpoint: &str, |
| 557 | sandbox_name: &str, |
| 558 | summaries: Vec<denial_aggregator::FlushableDenialSummary>, |
| 559 | ) -> Result<()> { |
| 560 | use openshell_core::grpc_client::CachedOpenShellClient; |
| 561 | use openshell_core::proto::{DenialSummary, L7RequestSample}; |
| 562 | |
| 563 | let client = CachedOpenShellClient::connect(endpoint).await?; |
| 564 | |
| 565 | let proto_summaries: Vec<DenialSummary> = summaries |
| 566 | .into_iter() |
| 567 | .map(|s| DenialSummary { |
| 568 | sandbox_id: String::new(), |
| 569 | host: s.host, |
| 570 | port: u32::from(s.port), |
| 571 | binary: s.binary, |
| 572 | ancestors: s.ancestors, |
| 573 | deny_reason: s.deny_reason, |
| 574 | first_seen_ms: s.first_seen_ms, |
| 575 | last_seen_ms: s.last_seen_ms, |
| 576 | count: s.count, |
| 577 | suppressed_count: 0, |
| 578 | total_count: s.count, |
| 579 | sample_cmdlines: s.sample_cmdlines, |
| 580 | binary_sha256: String::new(), |
| 581 | persistent: false, |
| 582 | denial_stage: s.denial_stage, |
| 583 | l7_request_samples: s |
| 584 | .l7_samples |
| 585 | .into_iter() |
| 586 | .map(|l| L7RequestSample { |
| 587 | method: l.method, |
| 588 | path: l.path, |
| 589 | decision: "deny".to_string(), |
| 590 | count: l.count, |
| 591 | }) |
| 592 | .collect(), |
| 593 | l7_inspection_active: false, |
| 594 | }) |
| 595 | .collect(); |
| 596 | |
| 597 | // Run the mechanistic mapper sandbox-side to generate proposals. |
| 598 | // The gateway is a thin persistence + validation layer — it never |
| 599 | // generates proposals itself. |
| 600 | let proposals = mechanistic_mapper::generate_proposals(&proto_summaries); |
| 601 | |
| 602 | info!( |
| 603 | sandbox_name = %sandbox_name, |
| 604 | summaries = proto_summaries.len(), |
| 605 | proposals = proposals.len(), |
| 606 | "Flushed denial analysis to gateway" |
| 607 | ); |
| 608 | |
| 609 | client |
| 610 | .submit_policy_analysis( |
| 611 | sandbox_name, |
| 612 | proto_summaries, |
no test coverage detected