Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions audits/assail-classifications.a2ml
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
%A2ML
(metadata
(name "assail-classifications")
(version "1.0")
)
- suppression:
file: 'scripts/mass-apply-templates.sh'
rule: 'CommandInjection'
Expand Down
11 changes: 4 additions & 7 deletions benches/contract_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ fn rust_proposal() -> Proposal {
action_type: ActionType::CreateFile {
path: "src/lib.rs".to_string(),
},
content: "pub fn compute(x: u64) -> u64 { x.wrapping_mul(6364136223846793005) }".to_string(),
content: "pub fn compute(x: u64) -> u64 { x.wrapping_mul(6364136223846793005) }"
.to_string(),
files_affected: vec!["src/lib.rs".to_string()],
llm_confidence: 0.97,
}
Expand Down Expand Up @@ -63,15 +64,11 @@ fn nickel_proposal() -> Proposal {

/// Complex proposal touching many files and long content — stresses the inner loops.
fn complex_proposal() -> Proposal {
let files: Vec<String> = (0..20)
.map(|i| format!("src/module_{}.rs", i))
.collect();
let files: Vec<String> = (0..20).map(|i| format!("src/module_{}.rs", i)).collect();

let mut content = String::with_capacity(4096);
for i in 0..50 {
content.push_str(&format!(
"pub fn func_{i}(x: u32) -> u32 {{ x + {i} }}\n"
));
content.push_str(&format!("pub fn func_{i}(x: u32) -> u32 {{ x + {i} }}\n"));
}

Proposal {
Expand Down
14 changes: 6 additions & 8 deletions benches/oracle_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
action_type: ActionType::CreateFile {
path: "src/config.rs".to_string(),
},
content: r#"let api_key = "supersecretkey12345""#.to_string(), // scanner-allow: rust-secrets
content: r#"let api_key = "supersecretkey12345""#.to_string(), // scanner-allow: rust-secrets

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay this needs to be fixed right away

files_affected: vec!["src/config.rs".to_string()],
llm_confidence: 0.9,
}
Expand Down Expand Up @@ -101,16 +101,12 @@

// Forbidden language: TypeScript (.ts extension, typed content)
group.bench_function("typescript_forbidden", |b| {
b.iter(|| {
black_box(oracle.check_proposal(black_box(&ts_proposal)).unwrap())
})
b.iter(|| black_box(oracle.check_proposal(black_box(&ts_proposal)).unwrap()))
});

// Tier-1 language: Rust (should be Compliant)
group.bench_function("rust_allowed", |b| {
b.iter(|| {
black_box(oracle.check_proposal(black_box(&rs_proposal)).unwrap())
})
b.iter(|| black_box(oracle.check_proposal(black_box(&rs_proposal)).unwrap()))
});

group.finish();
Expand Down Expand Up @@ -178,7 +174,9 @@

group.bench_function("forbidden_typescript", |b| {
b.iter(|| {
let eval = oracle.check_proposal(black_box(&forbidden_proposal)).unwrap();
let eval = oracle
.check_proposal(black_box(&forbidden_proposal))
.unwrap();
black_box(eval)
})
});
Expand Down
133 changes: 85 additions & 48 deletions src/contract/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -666,10 +666,8 @@
/// Evaluate a gating request and return a decision
pub fn evaluate(&self, request: &GatingRequest) -> Result<GatingDecision, ContractError> {
let start = std::time::Instant::now();
let mut stages_executed = Vec::new();

// Stage 1: Oracle evaluation
stages_executed.push("oracle".to_string());
let stages_executed = vec!["oracle".to_string()];
let oracle_eval = self.oracle.check_proposal(&request.proposal)?;

// Determine verdict based on oracle result
Expand Down Expand Up @@ -1415,9 +1413,11 @@
Custom(String),
}

impl RedTeamCategory {
pub fn from_str(s: &str) -> Self {
match s.to_lowercase().as_str() {
impl std::str::FromStr for RedTeamCategory {
type Err = std::convert::Infallible;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s.to_lowercase().as_str() {
"documentation_bypass" | "doc_bypass" | "comment_bypass" => {
RedTeamCategory::DocumentationBypass
}
Expand All @@ -1430,7 +1430,7 @@
"secret_hiding" | "secret_splitting" => RedTeamCategory::SecretEvasion,
"false_positive_avoidance" | "false_positive" => RedTeamCategory::FalsePositiveCheck,
other => RedTeamCategory::Custom(other.to_string()),
}
})
}
}

Expand Down Expand Up @@ -1565,7 +1565,7 @@
let runner = ContractRunner::new();
let request = GatingRequest::new(create_proposal(
"config.rs",
r#"let password = "supersecret123456""#, // scanner-allow: rust-secrets
r#"let password = "supersecret123456""#, // scanner-allow: rust-secrets

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you fix this stuff if it needs it, but I mean whatever you do here - is it about putting an exclusion in or is it something else (I realise now it's just a fake one)

));

let decision = runner.evaluate(&request).unwrap();
Expand Down Expand Up @@ -1666,8 +1666,14 @@

#[test]
fn test_refusal_category_display() {
assert_eq!(RefusalCategory::ForbiddenLanguage.display_name(), "Forbidden Language");
assert_eq!(RefusalCategory::SecurityViolation.display_name(), "Security Violation");
assert_eq!(
RefusalCategory::ForbiddenLanguage.display_name(),
"Forbidden Language"
);
assert_eq!(
RefusalCategory::SecurityViolation.display_name(),
"Security Violation"
);
assert_eq!(RefusalCategory::SystemError.display_name(), "System Error");
}

Expand All @@ -1682,9 +1688,18 @@

#[test]
fn test_refusal_category_severity() {
assert_eq!(RefusalCategory::SecurityViolation.severity(), Severity::Critical);
assert_eq!(RefusalCategory::ForbiddenLanguage.severity(), Severity::Critical);
assert_eq!(RefusalCategory::ForbiddenToolchain.severity(), Severity::High);
assert_eq!(
RefusalCategory::SecurityViolation.severity(),
Severity::Critical
);
assert_eq!(
RefusalCategory::ForbiddenLanguage.severity(),
Severity::Critical
);
assert_eq!(
RefusalCategory::ForbiddenToolchain.severity(),
Severity::High
);
assert_eq!(RefusalCategory::VerbositySmell.severity(), Severity::Low);
}

Expand All @@ -1705,8 +1720,7 @@
..Default::default()
};

let request = GatingRequest::new(proposal.clone())
.with_context(context.clone());
let request = GatingRequest::new(proposal.clone()).with_context(context.clone());

assert_eq!(request.context.source, "test");
assert_eq!(request.context.session_id, Some("session-123".to_string()));
Expand All @@ -1715,40 +1729,38 @@
#[test]
fn test_refusal_with_evidence() {
let runner = ContractRunner::new();
let request = GatingRequest::new(create_proposal(
"main.ts",
"const x: string = 'hello';",
));
let request = GatingRequest::new(create_proposal("main.ts", "const x: string = 'hello';"));

let decision = runner.evaluate(&request).unwrap();
assert!(decision.refusal.is_some());

let refusal = decision.refusal.unwrap();
assert!(!refusal.evidence.is_empty());
assert_eq!(refusal.evidence[0].evidence_type, EvidenceType::ContentMarker);
assert_eq!(
refusal.evidence[0].evidence_type,
EvidenceType::ContentMarker
);
}

#[test]
fn test_python_forbidden_with_remediation() {
let runner = ContractRunner::new();
let request = GatingRequest::new(create_proposal(
"script.py",
"import os",
));
let request = GatingRequest::new(create_proposal("script.py", "import os"));

let decision = runner.evaluate(&request).unwrap();
let refusal = decision.refusal.unwrap();
assert!(refusal.remediation.is_some());
assert!(refusal.remediation.unwrap().contains("only allowed in salt"));
assert!(refusal
.remediation
.unwrap()
.contains("only allowed in salt"));
}

#[test]
fn test_go_forbidden_with_rust_remediation() {
let runner = ContractRunner::new();
let request = GatingRequest::new(create_proposal(
"main.go",
"package main\nfunc main() {}",
));
let request =
GatingRequest::new(create_proposal("main.go", "package main\nfunc main() {}"));

let decision = runner.evaluate(&request).unwrap();
let refusal = decision.refusal.unwrap();
Expand All @@ -1763,7 +1775,10 @@
let request = GatingRequest::new(create_proposal("lib.rs", "pub fn foo() {}"));

let decision = runner.evaluate(&request).unwrap();
assert!(decision.processing.stages_executed.contains(&"oracle".to_string()));
assert!(decision
.processing
.stages_executed
.contains(&"oracle".to_string()));
assert!(decision.evaluations.oracle.is_some());
}

Expand Down Expand Up @@ -1961,28 +1976,49 @@

#[test]
fn test_red_team_category_from_str() {
assert_eq!(RedTeamCategory::from_str("doc_bypass"), RedTeamCategory::DocumentationBypass);
assert_eq!(RedTeamCategory::from_str("marker_obfuscation"), RedTeamCategory::MarkerObfuscation);
assert_eq!(RedTeamCategory::from_str("encoding"), RedTeamCategory::EncodedContent);
assert_eq!(RedTeamCategory::from_str("boundary"), RedTeamCategory::BoundaryCondition);
assert_eq!(RedTeamCategory::from_str("polyglot"), RedTeamCategory::ContentInjection);
assert_eq!(RedTeamCategory::from_str("secret_hiding"), RedTeamCategory::SecretEvasion);
assert_eq!(RedTeamCategory::from_str("false_positive"), RedTeamCategory::FalsePositiveCheck);
assert_eq!(
"doc_bypass".parse::<RedTeamCategory>().unwrap(),
RedTeamCategory::DocumentationBypass
);
assert_eq!(
"marker_obfuscation".parse::<RedTeamCategory>().unwrap(),
RedTeamCategory::MarkerObfuscation
);
assert_eq!(
"encoding".parse::<RedTeamCategory>().unwrap(),
RedTeamCategory::EncodedContent
);
assert_eq!(
"boundary".parse::<RedTeamCategory>().unwrap(),
RedTeamCategory::BoundaryCondition
);
assert_eq!(
"polyglot".parse::<RedTeamCategory>().unwrap(),
RedTeamCategory::ContentInjection
);
assert_eq!(
"secret_hiding".parse::<RedTeamCategory>().unwrap(),
RedTeamCategory::SecretEvasion
);
assert_eq!(
"false_positive".parse::<RedTeamCategory>().unwrap(),
RedTeamCategory::FalsePositiveCheck
);
}

#[test]
fn test_elixir_compliant() {
let runner = ContractRunner::new();
// Elixir with .ex extension and defmodule marker
let request = GatingRequest::new(create_proposal(
"app.ex",
"defmodule MyModule, do: :ok",
));
let request = GatingRequest::new(create_proposal("app.ex", "defmodule MyModule, do: :ok"));

let decision = runner.evaluate(&request).unwrap();
// Should be allowed as tier1 language
assert!(matches!(decision.verdict, Verdict::Allow),
"Elixir should be allowed, got {:?}", decision.verdict);
assert!(
matches!(decision.verdict, Verdict::Allow),
"Elixir should be allowed, got {:?}",
decision.verdict
);
}

#[test]
Expand Down Expand Up @@ -2050,11 +2086,12 @@
#[test]
fn test_npm_with_deno_allowed() {
let runner = ContractRunner::new();
let mut request = GatingRequest::new(create_proposal(
"package.json",
r#"{"name": "test"}"#,
));
request.proposal.files_affected.push("deno.json".to_string());
let mut request =
GatingRequest::new(create_proposal("package.json", r#"{"name": "test"}"#));
request
.proposal
.files_affected
.push("deno.json".to_string());

let decision = runner.evaluate(&request).unwrap();
assert_eq!(decision.verdict, Verdict::Allow);
Expand Down
Loading
Loading