Skip to main content

lean_ctx/core/patterns/
cosign.rs

1//! Cosign (sigstore) output compression.
2//!
3//! `cosign verify` prints a human-readable verdict (`Verification for X --`
4//! plus the checks performed) followed by a large JSON signature payload. We
5//! keep the verdict/checks and any error, dropping the trailing JSON blob.
6
7use crate::core::compressor::strip_ansi;
8
9pub fn compress(_cmd: &str, output: &str) -> Option<String> {
10    let trimmed = output.trim();
11    if trimmed.is_empty() {
12        return Some("cosign: ok".to_string());
13    }
14
15    let mut kept: Vec<String> = Vec::new();
16    for raw in trimmed.lines() {
17        let line = strip_ansi(raw);
18        let line = line.trim();
19        if line.is_empty() {
20            continue;
21        }
22        // The JSON signature payload starts with '[' or '{' — stop there.
23        if line.starts_with('[') || line.starts_with('{') {
24            break;
25        }
26        kept.push(line.to_string());
27    }
28
29    if kept.is_empty() {
30        return Some("cosign: ok".to_string());
31    }
32    Some(kept.join("\n"))
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    const VERIFY: &str = "\nVerification for myimage:latest --\nThe following checks were performed on each of these signatures:\n  - The cosign claims were validated\n  - The signatures were verified against the specified public key\n[{\"critical\":{\"identity\":{\"docker-reference\":\"myimage\"},\"image\":{\"docker-manifest-digest\":\"sha256:deadbeef\"}}}]\n";
40
41    #[test]
42    fn keeps_verdict_drops_json() {
43        let r = compress("cosign verify myimage", VERIFY).unwrap();
44        assert!(r.contains("Verification for myimage:latest"), "{r}");
45        assert!(r.contains("claims were validated"), "{r}");
46        assert!(
47            !r.contains("docker-manifest-digest"),
48            "drops json payload: {r}"
49        );
50        assert!(!r.contains("sha256:deadbeef"), "{r}");
51    }
52
53    #[test]
54    fn keeps_errors() {
55        let out = "Error: no matching signatures:\nfailed to verify signature\n";
56        let r = compress("cosign verify x", out).unwrap();
57        assert!(r.contains("no matching signatures"), "{r}");
58    }
59
60    #[test]
61    fn empty_is_ok() {
62        assert_eq!(compress("cosign verify x", "").unwrap(), "cosign: ok");
63    }
64}