agentguard/commands/
sim.rs1use agentguard_core::authorize::build_entities;
2use agentguard_core::{AgentRequest, Authorizer, PolicyStore};
3use anyhow::Result;
4use std::path::Path;
5use tokio::io::AsyncReadExt;
6
7pub async fn run(
8 store: impl AsRef<Path>,
9 request: impl AsRef<Path>,
10 entities_path: Option<impl AsRef<Path>>,
11 output: &str,
12) -> Result<()> {
13 let text = if request.as_ref().as_os_str() == "-" {
14 let mut buf = String::new();
15 tokio::io::stdin().read_to_string(&mut buf).await?;
16 buf
17 } else {
18 tokio::fs::read_to_string(request.as_ref()).await?
19 };
20 let req: AgentRequest = serde_json::from_str(&text)?;
21
22 let entities = if let Some(p) = entities_path {
23 let path = p.as_ref().to_path_buf();
24 tokio::task::spawn_blocking(move || -> Result<cedar_policy::Entities> {
25 let text = std::fs::read_to_string(&path)?;
26 let arr: Vec<serde_json::Value> = serde_json::from_str(&text)?;
27 Ok(build_entities(arr)?)
28 })
29 .await
30 .map_err(|e| anyhow::anyhow!("blocking task: {e}"))??
31 } else {
32 cedar_policy::Entities::empty()
33 };
34
35 let store_path = store.as_ref().to_path_buf();
36 let req_for_blocking = req.clone();
37 let entities_for_blocking = entities.clone();
38 let decision =
39 tokio::task::spawn_blocking(move || -> Result<agentguard_core::authorize::Decision> {
40 let store = PolicyStore::open(&store_path)?;
41 let engine = Authorizer::new(store)?;
42 Ok(engine.authorize(&req_for_blocking, &entities_for_blocking)?)
43 })
44 .await
45 .map_err(|e| anyhow::anyhow!("blocking task: {e}"))??;
46
47 if output == "json" {
48 println!("{}", serde_json::to_string_pretty(&decision)?);
49 } else {
50 let sym = match decision.effect {
51 agentguard_core::authorize::Effect::Allow => "✓ ALLOW",
52 _ => "✗ DENY ",
53 };
54 println!(
55 "{} {} → {} on {}",
56 sym, req.principal, req.action, req.resource
57 );
58 if !decision.policies.is_empty() {
59 println!(" policies: {}", decision.policies.join(", "));
60 }
61 for r in &decision.reasons {
62 println!(" reason: {}", r);
63 }
64 }
65 Ok(())
66}