feat(controls): B3 — categorize the rest of needs_tooling (architectural + RBAC)
CI / Check (push) Skipped
CI / Check (pull_request) Successful in 5m41s
CI / Detect Changes (pull_request) Skipped
CI / Deploy Agent (pull_request) Skipped
CI / Deploy Dashboard (pull_request) Skipped
CI / Deploy Docs (pull_request) Skipped
CI / Deploy MCP (pull_request) Skipped
CI / Check (push) Skipped
CI / Check (pull_request) Successful in 5m41s
CI / Detect Changes (pull_request) Skipped
CI / Deploy Agent (pull_request) Skipped
CI / Deploy Dashboard (pull_request) Skipped
CI / Deploy Docs (pull_request) Skipped
CI / Deploy MCP (pull_request) Skipped
Closes out B's coverage of the 16 needs_tooling CRA controls: - cra-ai-2,3,4,5 (minimal attack surface, secure architecture, least-privilege, tamper protection) are design properties, not local code patterns -> marked not_code_checkable (out of static-scan scope) with reviewer notes. - cra-ai-12 (RBAC) is surface-checkable (authorization points) -> added to the grounded surface pass; note points to the gated grounded mechanism. Final CRA coverage: covered 13 | needs_tooling 8 (all grounded-covered, gated) | not_code_checkable 19. The 16 needs_tooling now fully categorized: 4 custom-semgrep (B1) + 8 grounded surface (B2/B3, gated) + 4 architectural (B3). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
4ef257bfe2
commit
7cd4ffdaab
@@ -47,6 +47,17 @@ pub const SURFACES: &[Surface] = &[
|
|||||||
"ratelimit",
|
"ratelimit",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
Surface {
|
||||||
|
control_id: "cra-ai-12", // Rollenbasierte Autorisierung (RBAC)
|
||||||
|
terms: &[
|
||||||
|
"authorize",
|
||||||
|
"permission",
|
||||||
|
"role",
|
||||||
|
"rbac",
|
||||||
|
"require_role",
|
||||||
|
"has_role",
|
||||||
|
],
|
||||||
|
},
|
||||||
Surface {
|
Surface {
|
||||||
control_id: "cra-ai-24", // Security-Logging
|
control_id: "cra-ai-24", // Security-Logging
|
||||||
terms: &["login", "authorize", "permission", "role", "admin", "audit"],
|
terms: &["login", "authorize", "permission", "role", "admin", "audit"],
|
||||||
@@ -196,10 +207,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn surfaces_cover_the_absence_based_controls() {
|
fn surfaces_cover_the_absence_based_controls() {
|
||||||
assert_eq!(SURFACES.len(), 7);
|
assert_eq!(SURFACES.len(), 8);
|
||||||
for id in [
|
for id in [
|
||||||
"cra-ai-6",
|
"cra-ai-6",
|
||||||
"cra-ai-11",
|
"cra-ai-11",
|
||||||
|
"cra-ai-12",
|
||||||
"cra-ai-24",
|
"cra-ai-24",
|
||||||
"cra-ai-27",
|
"cra-ai-27",
|
||||||
"cra-ai-28",
|
"cra-ai-28",
|
||||||
|
|||||||
@@ -25,29 +25,29 @@
|
|||||||
"control": "cra-ai-2",
|
"control": "cra-ai-2",
|
||||||
"title": "Minimale Angriffsflaeche",
|
"title": "Minimale Angriffsflaeche",
|
||||||
"scans": [],
|
"scans": [],
|
||||||
"note": "code-checkable but no off-the-shelf tool digs it out — author a detector (custom semgrep rule / check)",
|
"note": "design property (minimal attack surface) — not derivable from local code patterns; architecture/threat-model review",
|
||||||
"status": "needs_tooling"
|
"status": "not_code_checkable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"control": "cra-ai-3",
|
"control": "cra-ai-3",
|
||||||
"title": "Sichere Systemarchitektur",
|
"title": "Sichere Systemarchitektur",
|
||||||
"scans": [],
|
"scans": [],
|
||||||
"note": "code-checkable but no off-the-shelf tool digs it out — author a detector (custom semgrep rule / check)",
|
"note": "design property (secure system architecture) — architecture review, not statically code-checkable",
|
||||||
"status": "needs_tooling"
|
"status": "not_code_checkable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"control": "cra-ai-4",
|
"control": "cra-ai-4",
|
||||||
"title": "Least-Privilege-Prinzip",
|
"title": "Least-Privilege-Prinzip",
|
||||||
"scans": [],
|
"scans": [],
|
||||||
"note": "code-checkable but no off-the-shelf tool digs it out — author a detector (custom semgrep rule / check)",
|
"note": "design property (least-privilege) — deployment/IAM & architecture review, not a local code pattern",
|
||||||
"status": "needs_tooling"
|
"status": "not_code_checkable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"control": "cra-ai-5",
|
"control": "cra-ai-5",
|
||||||
"title": "Manipulationsschutz",
|
"title": "Manipulationsschutz",
|
||||||
"scans": [],
|
"scans": [],
|
||||||
"note": "code-checkable but no off-the-shelf tool digs it out — author a detector (custom semgrep rule / check)",
|
"note": "design property (tamper protection) — hardware/runtime & operational control, not statically code-checkable",
|
||||||
"status": "needs_tooling"
|
"status": "not_code_checkable"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"control": "cra-ai-6",
|
"control": "cra-ai-6",
|
||||||
@@ -146,7 +146,7 @@
|
|||||||
"control": "cra-ai-12",
|
"control": "cra-ai-12",
|
||||||
"title": "Rollenbasierte Autorisierung",
|
"title": "Rollenbasierte Autorisierung",
|
||||||
"scans": [],
|
"scans": [],
|
||||||
"note": "code-checkable but no off-the-shelf tool digs it out — author a detector (custom semgrep rule / check)",
|
"note": "absence-based — no syntactic pattern; covered by the grounded surface check (retrieve surface + LLM judge), gated (BREAKPILOT_GROUNDED_CHECKS) pending live tuning",
|
||||||
"status": "needs_tooling"
|
"status": "needs_tooling"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -214,6 +214,27 @@ mod tests {
|
|||||||
assert!(hits.iter().any(|c| c.control == "cra-ai-1"));
|
assert!(hits.iter().any(|c| c.control == "cra-ai-1"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn coverage_reflects_the_b_track_split() {
|
||||||
|
let s = ControlMap::cra().unwrap().summary();
|
||||||
|
// 9 already tool-covered + B1's 4 custom-semgrep controls.
|
||||||
|
assert_eq!(s.covered, 13);
|
||||||
|
// The 8 grounded surface controls stay needs_tooling until live-tuned.
|
||||||
|
assert_eq!(s.needs_tooling, 8);
|
||||||
|
// B3 marked the 4 pure-architectural controls not code-checkable.
|
||||||
|
assert_eq!(s.not_code_checkable, 19);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn architectural_controls_are_not_code_checkable() {
|
||||||
|
let map = ControlMap::cra().unwrap();
|
||||||
|
for id in ["cra-ai-2", "cra-ai-3", "cra-ai-4", "cra-ai-5"] {
|
||||||
|
let c = map.coverage(id).unwrap();
|
||||||
|
assert_eq!(c.status, Coverage::NotCodeCheckable, "{id}");
|
||||||
|
assert!(c.scans.is_empty(), "{id} should carry no scan bindings");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn custom_rule_controls_do_not_bind_by_broad_cwe() {
|
fn custom_rule_controls_do_not_bind_by_broad_cwe() {
|
||||||
let map = ControlMap::cra().unwrap();
|
let map = ControlMap::cra().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user