From f194d7a68d28379443afc29ba2ab58e8a0439a4b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 16 Aug 2026 20:49:51 +0900 Subject: [PATCH 01/15] test: stage adaptive SOC orchestration contract --- scripts/stage_adaptive_soc_default_test.py | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 scripts/stage_adaptive_soc_default_test.py diff --git a/scripts/stage_adaptive_soc_default_test.py b/scripts/stage_adaptive_soc_default_test.py new file mode 100644 index 00000000..1a1682e1 --- /dev/null +++ b/scripts/stage_adaptive_soc_default_test.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python3 +"""Stage a Rust contract test for the SOC LLM adaptive request default.""" + +from pathlib import Path + +root = Path(__file__).resolve().parents[1] +test_path = root / "tests" / "adaptive_orchestrator_default.rs" +content = '''//! Contract test for the contextual-orchestrator SOC request policy. + +#[test] +fn soc_llm_request_explicitly_delegates_to_auto_policy() { + let source = include_str!("../src/lib.rs"); + assert!(source.contains("orchestration_mode")); + assert!(source.contains("auto")); +} +''' + +if test_path.exists(): + if test_path.read_text(encoding="utf-8") != content: + raise SystemExit(f"refusing to replace a different test: {test_path}") +else: + test_path.parent.mkdir(parents=True, exist_ok=True) + test_path.write_text(content, encoding="utf-8") From 11506af42fbf48ceaa78ae04d27df61c7c3f041b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 16 Aug 2026 20:50:19 +0900 Subject: [PATCH 02/15] feat: stage adaptive SOC orchestration default --- scripts/apply_adaptive_soc_default.py | 98 +++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 scripts/apply_adaptive_soc_default.py diff --git a/scripts/apply_adaptive_soc_default.py b/scripts/apply_adaptive_soc_default.py new file mode 100644 index 00000000..946a1915 --- /dev/null +++ b/scripts/apply_adaptive_soc_default.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 +"""Add explicit auto orchestration to the optional SOC LLM request.""" + +from __future__ import annotations + +import re +from pathlib import Path + +root = Path(__file__).resolve().parents[1] +source_path = root / "src" / "lib.rs" +adr_path = root / "docs" / "adr" / "0010-adaptive-contextual-orchestrator-default.md" +changelog_path = root / "CHANGELOG.md" + +source = source_path.read_text(encoding="utf-8") +if "orchestration_mode" not in source: + patterns = [ + r'(?P[ \t]*)"model"\s*:\s*(?P[^,\n}]+),\s*\n(?P=indent)"messages"\s*:', + r'(?P[ \t]*)"model"\s*=>\s*(?P[^,\n}]+),\s*\n(?P=indent)"messages"\s*=>', + ] + changed = False + for pattern in patterns: + match = re.search(pattern, source) + if match is None: + continue + original = match.group(0) + separator = ":" if '"model"' in original and ":" in original.splitlines()[0] else "=>" + message_separator = ":" if separator == ":" else "=>" + replacement = ( + f'{match.group("indent")}"model"{separator}{match.group("value")},\n' + f'{match.group("indent")}"orchestration_mode"{separator} "auto",\n' + f'{match.group("indent")}"messages"{message_separator}' + ) + source = source[: match.start()] + replacement + source[match.end() :] + changed = True + break + if not changed: + # Flexible fallback for serde_json::json! blocks where formatting places + # model and messages on one line. + source, count = re.subn( + r'("model"\s*:\s*[^,}]+,\s*)("messages"\s*:)', + r'\1"orchestration_mode": "auto", \2', + source, + count=1, + ) + if count != 1: + raise RuntimeError("could not locate the SOC model/messages JSON payload") +source_path.write_text(source, encoding="utf-8") + +adr_path.parent.mkdir(parents=True, exist_ok=True) +if not adr_path.exists(): + adr_path.write_text( + '''# ADR-0010: SOC analysis delegates default execution to contextual-orchestrator auto + +- Status: Accepted +- Date: 2026-08-16 + +## Context + +Wardnet's optional SOC analysis endpoint calls the organization LLM gateway, but a +model/messages-only request leaves policy implicit and can collapse into a fixed +single-worker path. Security analysis ranges from short enrichment to high-risk, +multi-step investigation; the application should not hard-code one model or one +workflow for all cases. + +## Decision + +The SOC request explicitly includes `orchestration_mode: "auto"`. The central +orchestrator selects the quality-sufficient route, worker-plus-verifier path, or +conducted workflow; known lower cost is used only after capability and safety +requirements. Unpriced providers are not treated as free. + +Wardnet retains WAF/IDS evidence collection, authorization, bounded request handling, +audit records, security-domain validation, and operator presentation. Explicit fixed +modes remain controlled orchestration experiments and rollback controls, not the +product default. + +## References + +Omidvar, H., & Akhlaghi, V. (2026). *A communication-theoretic framework for LLM agents: Cost-aware adaptive reliability* [Preprint]. arXiv. https://doi.org/10.48550/arXiv.2605.09121 + +Tang, Y., Cetin, E., Xu, J., Sun, Q., Nielsen, S., Richard, V., Goda, H., Tymchenko, I., Nguyen, N., Lee, H., Ashiga, M., Kotyan, S., Kuroki, S., & Clanuwat, T. (2026). *Sakana Fugu technical report* [Technical report]. arXiv. https://doi.org/10.48550/arXiv.2606.21228 +''', + encoding="utf-8", + ) + +if changelog_path.exists(): + changelog = changelog_path.read_text(encoding="utf-8") + entry = ( + "- Optional SOC LLM analysis now explicitly selects contextual-orchestrator " + "`auto` instead of relying on a single-model default.\n" + ) + if entry not in changelog: + marker = "## Unreleased\n" + if marker in changelog: + changelog = changelog.replace(marker, marker + "\n### Changed\n\n" + entry, 1) + else: + changelog = "## Unreleased\n\n### Changed\n\n" + entry + "\n" + changelog + changelog_path.write_text(changelog, encoding="utf-8") From bc505790ae2db241b1ddcc396a87311dc2e3ba2e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sun, 16 Aug 2026 20:50:35 +0900 Subject: [PATCH 03/15] ci: apply and verify wardnet adaptive default --- .../apply-adaptive-orchestrator-default.yml | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .github/workflows/apply-adaptive-orchestrator-default.yml diff --git a/.github/workflows/apply-adaptive-orchestrator-default.yml b/.github/workflows/apply-adaptive-orchestrator-default.yml new file mode 100644 index 00000000..2c9f73f9 --- /dev/null +++ b/.github/workflows/apply-adaptive-orchestrator-default.yml @@ -0,0 +1,93 @@ +name: Apply adaptive contextual-orchestrator default + +on: + push: + branches: + - agent/adaptive-orchestrator-default + paths: + - scripts/stage_adaptive_soc_default_test.py + - scripts/apply_adaptive_soc_default.py + - .github/workflows/apply-adaptive-orchestrator-default.yml + +permissions: + contents: write + +concurrency: + group: apply-adaptive-orchestrator-default-${{ github.ref }} + cancel-in-progress: false + +jobs: + red-green-verify: + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - name: Checkout exact branch head + uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: true + + - name: Set up Python + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # actions/setup-python@v6 + with: + python-version: "3.12" + + - name: Set up Rust + uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 + + - name: Stage the Rust contract test + run: python scripts/stage_adaptive_soc_default_test.py + + - name: Establish red state or recognize an already-applied source change + id: red + shell: bash + run: | + set -euo pipefail + set +e + cargo test --test adaptive_orchestrator_default > /tmp/wardnet-adaptive-red.log 2>&1 + status=$? + set -e + cat /tmp/wardnet-adaptive-red.log + if [ "$status" -eq 0 ]; then + echo "already_applied=true" >> "$GITHUB_OUTPUT" + else + grep -Eq "FAILED|panicked|test result: FAILED" /tmp/wardnet-adaptive-red.log + echo "already_applied=false" >> "$GITHUB_OUTPUT" + fi + + - name: Apply SOC payload, ADR, and changelog changes + run: python scripts/apply_adaptive_soc_default.py + + - name: Format Rust source + run: cargo fmt --all + + - name: Prove the focused regression is green + run: cargo test --test adaptive_orchestrator_default + + - name: Run complete Rust tests + run: cargo test --workspace + + - name: Run clippy with warnings denied + run: cargo clippy --workspace --all-targets -- -D warnings + + - name: Verify formatting and patch integrity + shell: bash + run: | + cargo fmt --all -- --check + git diff --check + + - name: Publish the verified source commit + env: + TARGET_BRANCH: agent/adaptive-orchestrator-default + shell: bash + run: | + set -euo pipefail + rm scripts/stage_adaptive_soc_default_test.py + rm scripts/apply_adaptive_soc_default.py + rm .github/workflows/apply-adaptive-orchestrator-default.yml + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add --all + git diff --cached --check + git commit -m "feat(ai): delegate SOC analysis to adaptive orchestration" + git push origin "HEAD:${TARGET_BRANCH}" From eb61643eb9a4e182339ca3845df7095f312a3b1c Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 16 Aug 2026 12:45:45 +0000 Subject: [PATCH 04/15] feat(ai): delegate SOC analysis to adaptive orchestration --- .../apply-adaptive-orchestrator-default.yml | 93 ------------------ ...daptive-contextual-orchestrator-default.md | 30 ++++++ scripts/apply_adaptive_soc_default.py | 98 ------------------- scripts/stage_adaptive_soc_default_test.py | 23 ----- src/lib.rs | 3 +- tests/adaptive_orchestrator_default.rs | 8 ++ 6 files changed, 40 insertions(+), 215 deletions(-) delete mode 100644 .github/workflows/apply-adaptive-orchestrator-default.yml create mode 100644 docs/adr/0010-adaptive-contextual-orchestrator-default.md delete mode 100644 scripts/apply_adaptive_soc_default.py delete mode 100644 scripts/stage_adaptive_soc_default_test.py create mode 100644 tests/adaptive_orchestrator_default.rs diff --git a/.github/workflows/apply-adaptive-orchestrator-default.yml b/.github/workflows/apply-adaptive-orchestrator-default.yml deleted file mode 100644 index 2c9f73f9..00000000 --- a/.github/workflows/apply-adaptive-orchestrator-default.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Apply adaptive contextual-orchestrator default - -on: - push: - branches: - - agent/adaptive-orchestrator-default - paths: - - scripts/stage_adaptive_soc_default_test.py - - scripts/apply_adaptive_soc_default.py - - .github/workflows/apply-adaptive-orchestrator-default.yml - -permissions: - contents: write - -concurrency: - group: apply-adaptive-orchestrator-default-${{ github.ref }} - cancel-in-progress: false - -jobs: - red-green-verify: - runs-on: ubuntu-latest - timeout-minutes: 60 - steps: - - name: Checkout exact branch head - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # actions/checkout@v4 - with: - fetch-depth: 0 - persist-credentials: true - - - name: Set up Python - uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # actions/setup-python@v6 - with: - python-version: "3.12" - - - name: Set up Rust - uses: dtolnay/rust-toolchain@4be7066ada62dd38de10e7b70166bc74ed198c30 - - - name: Stage the Rust contract test - run: python scripts/stage_adaptive_soc_default_test.py - - - name: Establish red state or recognize an already-applied source change - id: red - shell: bash - run: | - set -euo pipefail - set +e - cargo test --test adaptive_orchestrator_default > /tmp/wardnet-adaptive-red.log 2>&1 - status=$? - set -e - cat /tmp/wardnet-adaptive-red.log - if [ "$status" -eq 0 ]; then - echo "already_applied=true" >> "$GITHUB_OUTPUT" - else - grep -Eq "FAILED|panicked|test result: FAILED" /tmp/wardnet-adaptive-red.log - echo "already_applied=false" >> "$GITHUB_OUTPUT" - fi - - - name: Apply SOC payload, ADR, and changelog changes - run: python scripts/apply_adaptive_soc_default.py - - - name: Format Rust source - run: cargo fmt --all - - - name: Prove the focused regression is green - run: cargo test --test adaptive_orchestrator_default - - - name: Run complete Rust tests - run: cargo test --workspace - - - name: Run clippy with warnings denied - run: cargo clippy --workspace --all-targets -- -D warnings - - - name: Verify formatting and patch integrity - shell: bash - run: | - cargo fmt --all -- --check - git diff --check - - - name: Publish the verified source commit - env: - TARGET_BRANCH: agent/adaptive-orchestrator-default - shell: bash - run: | - set -euo pipefail - rm scripts/stage_adaptive_soc_default_test.py - rm scripts/apply_adaptive_soc_default.py - rm .github/workflows/apply-adaptive-orchestrator-default.yml - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add --all - git diff --cached --check - git commit -m "feat(ai): delegate SOC analysis to adaptive orchestration" - git push origin "HEAD:${TARGET_BRANCH}" diff --git a/docs/adr/0010-adaptive-contextual-orchestrator-default.md b/docs/adr/0010-adaptive-contextual-orchestrator-default.md new file mode 100644 index 00000000..0833fe96 --- /dev/null +++ b/docs/adr/0010-adaptive-contextual-orchestrator-default.md @@ -0,0 +1,30 @@ +# ADR-0010: SOC analysis delegates default execution to contextual-orchestrator auto + +- Status: Accepted +- Date: 2026-08-16 + +## Context + +Wardnet's optional SOC analysis endpoint calls the organization LLM gateway, but a +model/messages-only request leaves policy implicit and can collapse into a fixed +single-worker path. Security analysis ranges from short enrichment to high-risk, +multi-step investigation; the application should not hard-code one model or one +workflow for all cases. + +## Decision + +The SOC request explicitly includes `orchestration_mode: "auto"`. The central +orchestrator selects the quality-sufficient route, worker-plus-verifier path, or +conducted workflow; known lower cost is used only after capability and safety +requirements. Unpriced providers are not treated as free. + +Wardnet retains WAF/IDS evidence collection, authorization, bounded request handling, +audit records, security-domain validation, and operator presentation. Explicit fixed +modes remain controlled orchestration experiments and rollback controls, not the +product default. + +## References + +Omidvar, H., & Akhlaghi, V. (2026). *A communication-theoretic framework for LLM agents: Cost-aware adaptive reliability* [Preprint]. arXiv. https://doi.org/10.48550/arXiv.2605.09121 + +Tang, Y., Cetin, E., Xu, J., Sun, Q., Nielsen, S., Richard, V., Goda, H., Tymchenko, I., Nguyen, N., Lee, H., Ashiga, M., Kotyan, S., Kuroki, S., & Clanuwat, T. (2026). *Sakana Fugu technical report* [Technical report]. arXiv. https://doi.org/10.48550/arXiv.2606.21228 diff --git a/scripts/apply_adaptive_soc_default.py b/scripts/apply_adaptive_soc_default.py deleted file mode 100644 index 946a1915..00000000 --- a/scripts/apply_adaptive_soc_default.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 -"""Add explicit auto orchestration to the optional SOC LLM request.""" - -from __future__ import annotations - -import re -from pathlib import Path - -root = Path(__file__).resolve().parents[1] -source_path = root / "src" / "lib.rs" -adr_path = root / "docs" / "adr" / "0010-adaptive-contextual-orchestrator-default.md" -changelog_path = root / "CHANGELOG.md" - -source = source_path.read_text(encoding="utf-8") -if "orchestration_mode" not in source: - patterns = [ - r'(?P[ \t]*)"model"\s*:\s*(?P[^,\n}]+),\s*\n(?P=indent)"messages"\s*:', - r'(?P[ \t]*)"model"\s*=>\s*(?P[^,\n}]+),\s*\n(?P=indent)"messages"\s*=>', - ] - changed = False - for pattern in patterns: - match = re.search(pattern, source) - if match is None: - continue - original = match.group(0) - separator = ":" if '"model"' in original and ":" in original.splitlines()[0] else "=>" - message_separator = ":" if separator == ":" else "=>" - replacement = ( - f'{match.group("indent")}"model"{separator}{match.group("value")},\n' - f'{match.group("indent")}"orchestration_mode"{separator} "auto",\n' - f'{match.group("indent")}"messages"{message_separator}' - ) - source = source[: match.start()] + replacement + source[match.end() :] - changed = True - break - if not changed: - # Flexible fallback for serde_json::json! blocks where formatting places - # model and messages on one line. - source, count = re.subn( - r'("model"\s*:\s*[^,}]+,\s*)("messages"\s*:)', - r'\1"orchestration_mode": "auto", \2', - source, - count=1, - ) - if count != 1: - raise RuntimeError("could not locate the SOC model/messages JSON payload") -source_path.write_text(source, encoding="utf-8") - -adr_path.parent.mkdir(parents=True, exist_ok=True) -if not adr_path.exists(): - adr_path.write_text( - '''# ADR-0010: SOC analysis delegates default execution to contextual-orchestrator auto - -- Status: Accepted -- Date: 2026-08-16 - -## Context - -Wardnet's optional SOC analysis endpoint calls the organization LLM gateway, but a -model/messages-only request leaves policy implicit and can collapse into a fixed -single-worker path. Security analysis ranges from short enrichment to high-risk, -multi-step investigation; the application should not hard-code one model or one -workflow for all cases. - -## Decision - -The SOC request explicitly includes `orchestration_mode: "auto"`. The central -orchestrator selects the quality-sufficient route, worker-plus-verifier path, or -conducted workflow; known lower cost is used only after capability and safety -requirements. Unpriced providers are not treated as free. - -Wardnet retains WAF/IDS evidence collection, authorization, bounded request handling, -audit records, security-domain validation, and operator presentation. Explicit fixed -modes remain controlled orchestration experiments and rollback controls, not the -product default. - -## References - -Omidvar, H., & Akhlaghi, V. (2026). *A communication-theoretic framework for LLM agents: Cost-aware adaptive reliability* [Preprint]. arXiv. https://doi.org/10.48550/arXiv.2605.09121 - -Tang, Y., Cetin, E., Xu, J., Sun, Q., Nielsen, S., Richard, V., Goda, H., Tymchenko, I., Nguyen, N., Lee, H., Ashiga, M., Kotyan, S., Kuroki, S., & Clanuwat, T. (2026). *Sakana Fugu technical report* [Technical report]. arXiv. https://doi.org/10.48550/arXiv.2606.21228 -''', - encoding="utf-8", - ) - -if changelog_path.exists(): - changelog = changelog_path.read_text(encoding="utf-8") - entry = ( - "- Optional SOC LLM analysis now explicitly selects contextual-orchestrator " - "`auto` instead of relying on a single-model default.\n" - ) - if entry not in changelog: - marker = "## Unreleased\n" - if marker in changelog: - changelog = changelog.replace(marker, marker + "\n### Changed\n\n" + entry, 1) - else: - changelog = "## Unreleased\n\n### Changed\n\n" + entry + "\n" + changelog - changelog_path.write_text(changelog, encoding="utf-8") diff --git a/scripts/stage_adaptive_soc_default_test.py b/scripts/stage_adaptive_soc_default_test.py deleted file mode 100644 index 1a1682e1..00000000 --- a/scripts/stage_adaptive_soc_default_test.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python3 -"""Stage a Rust contract test for the SOC LLM adaptive request default.""" - -from pathlib import Path - -root = Path(__file__).resolve().parents[1] -test_path = root / "tests" / "adaptive_orchestrator_default.rs" -content = '''//! Contract test for the contextual-orchestrator SOC request policy. - -#[test] -fn soc_llm_request_explicitly_delegates_to_auto_policy() { - let source = include_str!("../src/lib.rs"); - assert!(source.contains("orchestration_mode")); - assert!(source.contains("auto")); -} -''' - -if test_path.exists(): - if test_path.read_text(encoding="utf-8") != content: - raise SystemExit(f"refusing to replace a different test: {test_path}") -else: - test_path.parent.mkdir(parents=True, exist_ok=True) - test_path.write_text(content, encoding="utf-8") diff --git a/src/lib.rs b/src/lib.rs index c84737fc..aa1e48a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -658,7 +658,8 @@ fn soc_llm_chat_body(model: &str, event: &SecurityEvent) -> serde_json::Value { event.action, event.reason, event.score, event.path, client_ip, event.timestamp_unix ); serde_json::json!({ - "model": model, + "model":model, + "orchestration_mode": "auto", "messages": [ { "role": "system", diff --git a/tests/adaptive_orchestrator_default.rs b/tests/adaptive_orchestrator_default.rs new file mode 100644 index 00000000..f6f42dda --- /dev/null +++ b/tests/adaptive_orchestrator_default.rs @@ -0,0 +1,8 @@ +//! Contract test for the contextual-orchestrator SOC request policy. + +#[test] +fn soc_llm_request_explicitly_delegates_to_auto_policy() { + let source = include_str!("../src/lib.rs"); + assert!(source.contains("orchestration_mode")); + assert!(source.contains("auto")); +} From 4250362141698a50285923a10ef13bd486381fb1 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 18 Aug 2026 05:56:23 -0700 Subject: [PATCH 05/15] test(ai): scope the auto-orchestration contract to SOC payload --- tests/adaptive_orchestrator_default.rs | 32 ++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/adaptive_orchestrator_default.rs b/tests/adaptive_orchestrator_default.rs index f6f42dda..5ba27fc7 100644 --- a/tests/adaptive_orchestrator_default.rs +++ b/tests/adaptive_orchestrator_default.rs @@ -3,6 +3,34 @@ #[test] fn soc_llm_request_explicitly_delegates_to_auto_policy() { let source = include_str!("../src/lib.rs"); - assert!(source.contains("orchestration_mode")); - assert!(source.contains("auto")); + let function_start = source + .find("fn soc_llm_chat_body") + .expect("the SOC request builder must remain present"); + let function_tail = &source[function_start..]; + let function_end = function_tail + .find("\n/// Extracts the assistant message text") + .expect("the SOC request builder must retain a bounded source region"); + let function_source = &function_tail[..function_end]; + + assert_eq!( + function_source + .matches("\"orchestration_mode\": \"auto\"") + .count(), + 1, + "the SOC request builder must declare exactly one auto orchestration policy" + ); + + let model_position = function_source + .find("\"model\"") + .expect("the SOC request must retain its model selector"); + let policy_position = function_source + .find("\"orchestration_mode\": \"auto\"") + .expect("the SOC request must retain the explicit auto policy"); + let messages_position = function_source + .find("\"messages\"") + .expect("the SOC request must retain its messages payload"); + assert!( + model_position < policy_position && policy_position < messages_position, + "the orchestration policy must remain in the generated SOC chat payload" + ); } From def964b85ca8f562a801cb3c544ffe81ced7d931 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Tue, 18 Aug 2026 05:56:59 -0700 Subject: [PATCH 06/15] docs(ai): define the adaptive SOC orchestration boundary --- ...daptive-contextual-orchestrator-default.md | 68 ++++++++++++++++--- 1 file changed, 57 insertions(+), 11 deletions(-) diff --git a/docs/adr/0010-adaptive-contextual-orchestrator-default.md b/docs/adr/0010-adaptive-contextual-orchestrator-default.md index 0833fe96..eaa469d6 100644 --- a/docs/adr/0010-adaptive-contextual-orchestrator-default.md +++ b/docs/adr/0010-adaptive-contextual-orchestrator-default.md @@ -7,24 +7,70 @@ Wardnet's optional SOC analysis endpoint calls the organization LLM gateway, but a model/messages-only request leaves policy implicit and can collapse into a fixed -single-worker path. Security analysis ranges from short enrichment to high-risk, -multi-step investigation; the application should not hard-code one model or one -workflow for all cases. +single-worker path. Security analysis ranges from bounded enrichment to high-risk, +multi-step investigation. The edge gateway must not hard-code one provider, one +model, one topology, or one reasoning budget for every incident. + +The orchestration literature also distinguishes delegation policy from the workers +that perform the task. TRINITY assigns Thinker, Worker, and Verifier roles turn by +turn; Conductor learns communication topologies and targeted worker instructions; +and Fugu adapts the resulting scaffold to the query. These results support an +adaptive default, but they do not authorize the orchestrator to own Wardnet's +security evidence, permissions, audit trail, or operator decision. ## Decision The SOC request explicitly includes `orchestration_mode: "auto"`. The central -orchestrator selects the quality-sufficient route, worker-plus-verifier path, or -conducted workflow; known lower cost is used only after capability and safety -requirements. Unpriced providers are not treated as free. +orchestrator may select, within its published contract: + +1. a quality-sufficient single route for bounded, low-ambiguity enrichment; +2. role-separated worker and verifier execution when independent checking is + warranted; or +3. a conducted or recursive workflow for complex investigations that require + decomposition, additional evidence, or iterative verification. + +Role-specific reasoning effort, workflow depth, tool access, and stopping policy are +owned by contextual-orchestrator. Quality and safety requirements take precedence +over latency. Known cost may break ties only after capability and safety constraints; +unpriced providers are not treated as free. Scheduled evaluations must compare the +single-route, worker-verifier, and deeper orchestration modes so that increased +inference depth is retained only when it improves grounded SOC outcomes. Wardnet retains WAF/IDS evidence collection, authorization, bounded request handling, -audit records, security-domain validation, and operator presentation. Explicit fixed -modes remain controlled orchestration experiments and rollback controls, not the -product default. +audit records, security-domain validation, and operator presentation. The +orchestrator receives only the bounded event representation constructed by Wardnet, +and its response remains untrusted analysis until Wardnet validates and presents it. +Explicit fixed modes remain controlled experiments and rollback controls, not the +product default. Unsupported orchestration capabilities or malformed responses fail +closed rather than silently changing the security decision path. + +## Consequences + +- Adding or removing worker models does not change the Wardnet API contract. +- The gateway continues to make enforcement decisions from deterministic Wardnet + evidence; LLM output cannot directly block, allow, mutate policy, or obtain an + administrative capability. +- Audit and evaluation evidence must identify the selected orchestration mode and + model roles without copying secrets or unrelated personal data. +- A future live-model test lane must measure grounding, unsupported-claim rate, + decision consistency, and the marginal benefit of deeper orchestration on a fixed + incident corpus. ## References -Omidvar, H., & Akhlaghi, V. (2026). *A communication-theoretic framework for LLM agents: Cost-aware adaptive reliability* [Preprint]. arXiv. https://doi.org/10.48550/arXiv.2605.09121 +Nielsen, S., Cetin, E., Schwendeman, P., Sun, Q., Xu, J., & Tang, Y. (2025). +*Learning to orchestrate agents in natural language with the Conductor* [Preprint]. +arXiv. https://doi.org/10.48550/arXiv.2512.04388 + +Omidvar, H., & Akhlaghi, V. (2026). *A communication-theoretic framework for LLM +agents: Cost-aware adaptive reliability* [Preprint]. arXiv. +https://doi.org/10.48550/arXiv.2605.09121 + +Tang, Y., Cetin, E., Xu, J., Sun, Q., Nielsen, S., Richard, V., Goda, H., Tymchenko, +I., Nguyen, N., Lee, H., Ashiga, M., Kotyan, S., Kuroki, S., & Clanuwat, T. (2026). +*Sakana Fugu technical report* [Technical report]. arXiv. +https://doi.org/10.48550/arXiv.2606.21228 -Tang, Y., Cetin, E., Xu, J., Sun, Q., Nielsen, S., Richard, V., Goda, H., Tymchenko, I., Nguyen, N., Lee, H., Ashiga, M., Kotyan, S., Kuroki, S., & Clanuwat, T. (2026). *Sakana Fugu technical report* [Technical report]. arXiv. https://doi.org/10.48550/arXiv.2606.21228 +Xu, J., Sun, Q., Schwendeman, P., Nielsen, S., Cetin, E., & Tang, Y. (2025). +*TRINITY: An evolved LLM coordinator* [Preprint]. arXiv. +https://doi.org/10.48550/arXiv.2512.04695 From 9174a72d5c832a2bbb3d20bf829b9301c8969a9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Aug 2026 00:47:21 -0700 Subject: [PATCH 07/15] build(deps): bump github/codeql-action/upload-sarif to 4.37.6 (#73) Update the immutable github/codeql-action/upload-sarif pin from the official v4.37.5 commit to the official v4.37.6 commit. Exact-head CI, Security Scan, and SAST Semgrep succeeded. --- .github/workflows/scorecard-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard-analysis.yml b/.github/workflows/scorecard-analysis.yml index bf1f03a4..e6ea7c69 100644 --- a/.github/workflows/scorecard-analysis.yml +++ b/.github/workflows/scorecard-analysis.yml @@ -29,6 +29,6 @@ jobs: results_format: sarif publish_results: false - name: Upload SARIF - uses: github/codeql-action/upload-sarif@d1ba80a13dd99fba24a470575428917156a28b43 # v4 + uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4 with: sarif_file: results.sarif From 1cc492775d26845c7e782274e0434117db4ab5a4 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Sat, 22 Aug 2026 17:03:15 +0900 Subject: [PATCH 08/15] fix: address PR review follow-ups on the adaptive orchestrator default - src/lib.rs: fix cosmetic json! spacing ("model":model -> "model": model) flagged by Devin, so it reads consistently with the adjacent "orchestration_mode": "auto" line. rustfmt doesn't reformat inside serde_json::json! macro bodies, so this was silently inconsistent. - tests/adaptive_orchestrator_default.rs: per CodeRabbit's suggested diff, the uniqueness assertion now scans the *entire* source file for "orchestration_mode": "auto" and asserts both that there's exactly one occurrence and that it falls within soc_llm_chat_body's bounds -- previously it only counted matches inside the already-extracted function_source slice, so a second occurrence added to an unrelated function elsewhere in src/lib.rs would have passed undetected. - docs/adr/0010-adaptive-contextual-orchestrator-default.md: added a literature-to-decision mapping table connecting each cited paper's mechanism and reported ablation/metric (TRINITY's role separation and LiveCodeBench pass@1; Conductor's recursive test-time scaling and LiveCodeBench/GPQA-Diamond records; Fugu's query-adaptive scaffolding and SWE-Bench Pro/Terminal-Bench state-of-the-art; Omidvar & Akhlaghi's cost-aware Pareto routing) to the specific ADR decision item it grounds, per CodeRabbit's request and AGENTS.md's research-grounding convention. Did not add PDF copies to docs/papers/: all four are already cited with arXiv links and now have per-paper summaries in the mapping table, satisfying AGENTS.md's explicit fallback ("attach the PDF only when redistribution is permissible; otherwise cite + link + summarize") without taking on individual per-paper license review for redistribution. cargo fmt --check, cargo test --locked --workspace, and cargo clippy --locked --workspace --all-targets -D warnings are all clean (aside from the pre-existing, environment-specific binary_serves_then_shuts_down_on_sigterm local-sandbox flake unrelated to this change). Co-Authored-By: Claude Sonnet 5 --- ...10-adaptive-contextual-orchestrator-default.md | 14 ++++++++++++++ src/lib.rs | 2 +- tests/adaptive_orchestrator_default.rs | 15 ++++++++++++--- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/docs/adr/0010-adaptive-contextual-orchestrator-default.md b/docs/adr/0010-adaptive-contextual-orchestrator-default.md index eaa469d6..1138e8bc 100644 --- a/docs/adr/0010-adaptive-contextual-orchestrator-default.md +++ b/docs/adr/0010-adaptive-contextual-orchestrator-default.md @@ -18,6 +18,20 @@ and Fugu adapts the resulting scaffold to the query. These results support an adaptive default, but they do not authorize the orchestrator to own Wardnet's security evidence, permissions, audit trail, or operator decision. +## Literature-to-decision mapping + +| Source | Mechanism | Reported ablation/metric | Decision item it grounds | +| --- | --- | --- | --- | +| Xu et al. (2025), *TRINITY* | A lightweight (~0.6B parameter) coordinator assigns Thinker/Worker/Verifier roles turn-by-turn without modifying constituent model weights. | 86.2% pass@1 on LiveCodeBench at publication; the ablation attributes the gain to the coordinator's hidden-state contextualization versus RL/imitation-learning coordinators under the same budget. | Decision item 2 (role-separated worker and verifier execution) -- justifies delegating *when* to add an independent checking role to the orchestrator rather than hard-coding it in Wardnet. | +| Nielsen et al. (2025), *Conductor* | A 7B RL-trained coordinator adapts topology to task difficulty: single-query for factual tasks, planner-executor-verifier pipelines for hard tasks, with "Recursive Test-Time Scaling" (the coordinator can select itself as a worker for self-correction). | Record-setting 83.9% LiveCodeBench and 87.5% GPQA-Diamond; measured cost-efficiency gains over Mixture-of-Agents baselines. | Decision item 3 (conducted/recursive workflow for complex investigations) -- the query-adaptive depth and recursive self-correction are exactly the "decomposition, additional evidence, or iterative verification" case this item reserves for the orchestrator, not Wardnet. | +| Tang et al. (2026), *Sakana Fugu* | Fugu/Fugu-Ultra devise dynamic agentic scaffolds (large-scale fine-tuning + evolutionary search + RL) that vary with the query, orchestrating a team of diverse SOTA models. | State-of-the-art on SWE-Bench Pro, Terminal-Bench, LiveCodeBench, GPQA-Diamond, and Humanity's Last Exam; training explicitly optimizes the performance/latency trade-off via evolutionary search. | Decision item 1 (a quality-sufficient single route for bounded, low-ambiguity enrichment) and the "quality and safety take precedence over latency" rule -- query-adaptive scaffolding is the mechanism that keeps bounded events on a cheap route without Wardnet pre-selecting depth. | +| Omidvar & Akhlaghi (2026) | Models LLM sampling as a discrete stochastic channel, unifying retry/majority-vote/self-consistency into six operators, plus a cost-aware semantic-nearest-neighbor router with a single Lagrangian parameter traversing the quality-cost Pareto frontier. | ~56% lower normalized cost at matched quality, and ~7% quality improvement at matched cost (26% over single-shot), on MMLU/GSM8K/HumanEval. | The cost/quality tie-breaking rule ("known cost may break ties only after capability and safety constraints") -- grounds treating cost as a Pareto-frontier parameter subordinate to quality/safety, not an independent optimization target. | + +The scheduled evaluations required by the Decision section (comparing single-route, +worker-verifier, and deeper orchestration modes on grounded SOC outcomes) are the +Wardnet-side analogue of each paper's own ablation methodology, applied to this +system's incident corpus instead of LiveCodeBench/GPQA/MMLU. + ## Decision The SOC request explicitly includes `orchestration_mode: "auto"`. The central diff --git a/src/lib.rs b/src/lib.rs index aa1e48a7..8f54751d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -658,7 +658,7 @@ fn soc_llm_chat_body(model: &str, event: &SecurityEvent) -> serde_json::Value { event.action, event.reason, event.score, event.path, client_ip, event.timestamp_unix ); serde_json::json!({ - "model":model, + "model": model, "orchestration_mode": "auto", "messages": [ { diff --git a/tests/adaptive_orchestrator_default.rs b/tests/adaptive_orchestrator_default.rs index 5ba27fc7..438e990b 100644 --- a/tests/adaptive_orchestrator_default.rs +++ b/tests/adaptive_orchestrator_default.rs @@ -12,13 +12,22 @@ fn soc_llm_request_explicitly_delegates_to_auto_policy() { .expect("the SOC request builder must retain a bounded source region"); let function_source = &function_tail[..function_end]; + let policy = "\"orchestration_mode\": \"auto\""; + let policy_positions = source + .match_indices(policy) + .map(|(position, _)| position) + .collect::>(); + let function_end_absolute = function_start + function_end; + assert_eq!( - function_source - .matches("\"orchestration_mode\": \"auto\"") - .count(), + policy_positions.len(), 1, "the SOC request builder must declare exactly one auto orchestration policy" ); + assert!( + policy_positions[0] >= function_start && policy_positions[0] < function_end_absolute, + "the auto orchestration policy must be confined to soc_llm_chat_body" + ); let model_position = function_source .find("\"model\"") From 3f25ea56ed30aa440758b66631b36d328bee7ce7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2026 19:07:28 -0700 Subject: [PATCH 09/15] build(deps): bump github/codeql-action/upload-sarif (#92) Bumps [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) from 4.37.6 to 4.37.7. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/5595ccaf912efad79be6eef63a5619ff05969be3...ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd) --- updated-dependencies: - dependency-name: github/codeql-action/upload-sarif dependency-version: 4.37.7 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecard-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard-analysis.yml b/.github/workflows/scorecard-analysis.yml index e6ea7c69..dfa64206 100644 --- a/.github/workflows/scorecard-analysis.yml +++ b/.github/workflows/scorecard-analysis.yml @@ -29,6 +29,6 @@ jobs: results_format: sarif publish_results: false - name: Upload SARIF - uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4 with: sarif_file: results.sarif From edcb1a63a816a7aa8c78c97ced4e01cbac4cf487 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Aug 2026 04:28:09 +0000 Subject: [PATCH 10/15] build(deps): bump futures-util from 0.3.33 to 0.3.34 (#91) Bumps [futures-util](https://github.com/rust-lang/futures-rs) from 0.3.33 to 0.3.34. - [Release notes](https://github.com/rust-lang/futures-rs/releases) - [Changelog](https://github.com/rust-lang/futures-rs/blob/main/CHANGELOG.md) - [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.33...0.3.34) --- updated-dependencies: - dependency-name: futures-util dependency-version: 0.3.34 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Seongho Bae --- Cargo.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc09e461..c696190f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,44 +206,44 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-io" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4577ecaa3c4f96589d473f679a71b596316f6641bc350038b962a5daf0085d7a" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 2.0.119", + "syn 3.0.3", ] [[package]] name = "futures-sink" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34418ac499d6305c2fb5ad0ed2f6ac998c5f8ca209b4510f7f94242c647e307" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b231ed28831efb4a61a08580c4bc233ec56bc009f4cd8f52da2c3cb97df0c109" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-io", From c6501e97cae2742cc5dda5f63cd59017efbf54f6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 30 Aug 2026 11:05:11 +0000 Subject: [PATCH 11/15] fix(deploy): disable service account token automount (KSV-0036) The gateway pod never calls the Kubernetes API, so the default ServiceAccount token should not be automounted into the container filesystem. This is the one Trivy Kubernetes Security (KSV) misconfig pattern the prior deployment-hardening pass (KSV-0020/KSV-0021/ KSV-0125, PR #14) left unaddressed. --- deploy/kubernetes/waf-ids-ai-soc.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/deploy/kubernetes/waf-ids-ai-soc.yaml b/deploy/kubernetes/waf-ids-ai-soc.yaml index f811ecb4..fd58c394 100644 --- a/deploy/kubernetes/waf-ids-ai-soc.yaml +++ b/deploy/kubernetes/waf-ids-ai-soc.yaml @@ -41,6 +41,7 @@ spec: labels: app.kubernetes.io/name: waf-ids-ai-soc spec: + automountServiceAccountToken: false securityContext: runAsNonRoot: true fsGroup: 10001 From be45e69011bbc13ebde6f799a186f68d59f6eae6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 30 Aug 2026 11:23:09 +0000 Subject: [PATCH 12/15] fix(shutdown): register SIGTERM handler before announcing readiness tests/binary.rs::binary_serves_then_shuts_down_on_sigterm was failing CI on this branch (job 99248003533): the gateway exited with raw signal 15 instead of code 0. Root cause: shutdown_signal() was an async fn, so tokio::signal::unix::signal() (which installs the OS-level handler) only ran once the future was first polled inside axum::serve(...).with_graceful_shutdown(shutdown) -- which happens after run_from_env has already bound the listener and printed the readiness line. A SIGTERM delivered in that window (exactly what the e2e test, and any container runtime with a short terminationGracePeriodSeconds, does right after startup) fell through to the default disposition and killed the process instead of triggering a graceful shutdown. Fix: split registration from waiting. install_shutdown_signal() calls tokio::signal::unix::signal() synchronously and returns only the subsequent .recv() as a future, so main() installs the handler before run_from_env runs at all. Verified: `cargo test -p waf-ids-ai-soc --test binary` was reliably failing before this change and passes 5/5 after. --- src/main.rs | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index 2c8fc828..80e03481 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,21 +4,31 @@ #[cfg(not(test))] #[tokio::main] async fn main() -> Result<(), Box> { - waf_ids_ai_soc::run_from_env(Box::pin(shutdown_signal())).await + // Registered eagerly, before `run_from_env` binds its listener and prints + // the readiness line, so a SIGTERM delivered immediately on startup (as + // container runtimes and the e2e test harness do) cannot race the OS-level + // handler installation and fall through to the default "kill" disposition. + let shutdown = install_shutdown_signal(); + waf_ids_ai_soc::run_from_env(Box::pin(shutdown)).await } #[cfg(all(not(test), unix))] -async fn shutdown_signal() { - // Shut down gracefully on SIGTERM (what container runtimes and the e2e test - // harness send) so in-flight requests drain and the process exits cleanly. +fn install_shutdown_signal() -> impl std::future::Future + Send + 'static { + // `tokio::signal::unix::signal` registers the handler synchronously on + // call; only the subsequent `.recv()` wait is deferred to the returned + // future, so callers must invoke this *before* announcing readiness. let mut term = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::terminate()) .expect("install SIGTERM handler"); - term.recv().await; + async move { + term.recv().await; + } } #[cfg(all(not(test), not(unix)))] -async fn shutdown_signal() { - tokio::signal::ctrl_c() - .await - .expect("install Ctrl-C handler"); +fn install_shutdown_signal() -> impl std::future::Future + Send + 'static { + async { + tokio::signal::ctrl_c() + .await + .expect("install Ctrl-C handler"); + } } From e67a9396d166e1b9ce7b00fcde7c1bc14743d1f6 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 30 Aug 2026 11:27:43 +0000 Subject: [PATCH 13/15] fix(shutdown): register Windows Ctrl-C handler synchronously too Devin Review flagged (PR #132, src/main.rs:29-32) that the previous commit only fixed the readiness/signal-registration race on the Unix path: the non-Unix install_shutdown_signal() still wrapped tokio::signal::ctrl_c() in an async block, so registration stayed lazy and an immediate Ctrl-C could still kill the process before the handler was installed. tokio::signal::windows::ctrl_c() (unlike the cross-platform tokio::signal::ctrl_c() convenience fn) registers synchronously and returns a CtrlC handle, exactly mirroring unix::signal()/Signal, so apply the same split-registration-from-waiting fix there. Not covered by tests/binary.rs (its Windows test only exercises a forced kill, not graceful Ctrl-C), and this sandbox has no Windows cross-compiler to build/run against; verified the API shape directly against the vendored tokio 1.53.1 source (signal/windows.rs: `pub fn ctrl_c() -> io::Result`, `pub async fn recv(&mut self) -> Option<()>`), which matches the already-used unix::Signal shape exactly. --- src/main.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 80e03481..7244a80c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,9 +26,10 @@ fn install_shutdown_signal() -> impl std::future::Future + Send + ' #[cfg(all(not(test), not(unix)))] fn install_shutdown_signal() -> impl std::future::Future + Send + 'static { - async { - tokio::signal::ctrl_c() - .await - .expect("install Ctrl-C handler"); + // Mirrors the Unix path: `tokio::signal::windows::ctrl_c` registers the + // handler synchronously, so only `.recv()` is deferred to the future. + let mut ctrl_c = tokio::signal::windows::ctrl_c().expect("install Ctrl-C handler"); + async move { + ctrl_c.recv().await; } } From b2bcee3bf2c63f26c48e3be879e5349ef23fafcd Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Mon, 31 Aug 2026 10:01:07 +0900 Subject: [PATCH 14/15] feat(threat-intel): recognize the CISA Known Exploited Vulnerabilities (KEV) catalog (#133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(threat-intel): add CISA KEV catalog ingestion adapter Adds a new threat-intel adapter alongside the existing STIX/MISP/TAXII/ OpenCTI family: POST /api/threat-intel/cisa-kev fetches the CISA Known Exploited Vulnerabilities catalog (a single well-known public JSON feed, https://www.cisa.gov/known-exploited-vulnerabilities-catalog) and upserts one `cve`-typed ThreatIndicator per entry, keyed by CVE ID, severity escalated to Critical when CISA has tied the CVE to a known ransomware campaign (High otherwise — mere inclusion in the catalog already signals CISA-confirmed active exploitation). - src/kev_import.rs: pure parser (`parse_kev_document`), mirroring the misp_import/opencti_import/stix_import module shape exactly. Accepts the real catalog shape (`{"vulnerabilities": [...]}`) or a bare array. KEV entries carry no IP/domain/URL/hash observable, so `dnsbl` stays empty (kept only for ThreatFeedImport parity). - src/lib.rs: `import_kev_feed` handler follows the phishing-database fetch-by-URL pattern (not the MISP/STIX/OpenCTI paste-a-document pattern) since KEV has one canonical, stable, publicly known URL that every consumer wants pulled automatically rather than hand-relayed. Reuses the existing `fetch_text_feed`/`apply_threat_feed_import` plumbing untouched. `validate_http_url` gained a third `allowed_hosts` parameter (was hardcoded to the phishing-database allowlist) so KEV gets its own `www.cisa.gov`-only default, matching the SSRF-safety posture phishing-database already has (opt-out via `allow_non_default_hosts`); all other call sites updated. - crates/waf-ids-core: new buyer-evidence-manifest endpoint entry. - docs/architecture.md, docs/security/compliance-mapping.md: documented alongside the other threat-intel adapters. Deliberately not adding a cargo-fuzz target: none of the five existing JSON-import adapters (misp_import, opencti_import, stix_import, suricata_eve, coraza_audit) have one today — CLAUDE.md's fuzzed-surface list (request scorer, state deserializer, admin-token parser, DNSBL zone export) doesn't cover this adapter family. Matched the existing convention instead: a `parse_never_panics_on_arbitrary_text` unit test, same as its siblings. Verified: cargo fmt --check, cargo test --locked --workspace (all pass except the pre-existing root-sandbox-only `load_surfaces_state_rewrite_failures` flake tracked by PR #93, unrelated to this change), cargo clippy --locked --workspace --all-targets -- -D warnings. * fix(waf): never content-match CVE threat indicators in scoring Devin Review flagged (PR #133): every KEV-imported CVE indicator was entering score_request's generic substring matcher at High/Critical severity. A legitimate request that happens to reference a cataloged CVE literally (e.g. a vulnerability-management dashboard's own traffic hitting `/api/cve/CVE-2021-44228` through the gateway) would score high enough to trip a default block-mode route -- a real false-positive/ denial-of-service risk, not a hypothetical one. A CVE identifier is vulnerability-catalog metadata, not a request- content attack observable (unlike domain/url/hash/ip indicators from the other threat-intel adapters, which genuinely can appear in malicious traffic). Fix: score_request now short-circuits indicator_type "cve" to never content-match, mirroring the existing ip-type special case. The indicator stays fully visible via /api/threats, feed freshness, KPIs, and buyer evidence -- only request-content scoring is excluded. Added a core-crate unit test (score_request_never_content_matches_cve_indicators) and an HTTP-level regression test (kev_cve_indicators_never_block_legitimate_requests: imports a KEV catalog, creates a default block-mode route, and asserts a request literally containing the cataloged CVE ID is NOT blocked). Verified both fail without the fix and pass with it. * fix(shutdown): port SIGTERM/Ctrl-C race fix from PR #132 This branch forked from main before #132's shutdown-handler fix merged, so its copy of src/main.rs still had the pre-existing race (readiness announced before the signal handler was registered), making tests/binary.rs::binary_serves_then_shuts_down_on_sigterm flaky here too -- unrelated to this PR's KEV work but blocking its CI green. Ported the identical fix rather than waiting on #132 to merge first; it will no-op once main carries it. * docs(research): ground CISA KEV severity policy in EPSS/BOD literature Devin Review flagged (PR #133) that this substantive feature PR was missing the research grounding AGENTS.md's org rule requires (commit paper PDFs + full citations, or cite+link+summarize when redistribution isn't permitted). Added a "Further reading" section to docs/architecture.md (matching docs/fuzzing.md's existing citation convention) citing: - CISA's BOD 22-01, the directive establishing KEV's confirmed-active- exploitation inclusion criterion -- why catalog membership alone already implies at least High severity in kev_import.rs. - Jacobs et al. (2021), the EPSS paper -- the data-driven basis for treating exploitation evidence as a stronger prioritization signal than static CVSS severity. - Shimizu & Hashimoto (2025, arXiv:2506.01220, CC BY 4.0) -- empirical evidence that KEV-first triage cuts urgent-remediation workload ~95% but still misses exploited CVEs EPSS catches, supporting KEV as one adapter among the existing STIX/MISP/TAXII/OpenCTI family rather than a standalone replacement. Committed the arXiv PDF (CC BY 4.0, redistribution explicitly permitted) into docs/papers/, matching the one existing precedent (the fuzzing survey PDF cited from docs/fuzzing.md). The EPSS paper is ACM/SSRN-hosted without a redistributable PDF, so it is cited+linked per AGENTS.md's explicit fallback instead of attached. * fix(security): don't route request-supplied kev_url into the fetch by default CodeQL flagged (PR #133, critical severity, rust/request-forgery at src/lib.rs:2646 on the pre-fix commit): "The URL of this request depends on a user-provided value" -- import_kev_feed fetched request.kev_url directly, so a JSON body field flowed into the outbound HTTP client call. validate_kev_import_request already allowlists the host (www.cisa.gov) unless allow_non_default_hosts is set, but that's a value-equality check a couple of calls away from the fetch, not a pattern static analysis reliably recognizes as a sanitizer for the same tainted string reused later. Removed the taint at the source instead of arguing with the analyzer: on the default (non-override) path, the fetch now uses the hardcoded KEV_DEFAULT_URL constant, never request.kev_url -- there is no request-controlled string reaching the HTTP client unless the operator explicitly sets allow_non_default_hosts: true (the same opt-in gate that already exists for the host allowlist). All existing tests point at a local mock server via that same flag, so they're unaffected and still pass. Note: the identical fetch-an-operator-supplied-URL-after-an-allowlist- check pattern also exists in the pre-existing phishing-database and TAXII-poll endpoints (unmodified by this PR) -- out of scope here, but worth the same treatment in a follow-up if CodeQL flags them too. * fix(kev): stop validating kev_url when it won't be used Devin Review flagged (PR #133): with allow_non_default_hosts false, validate_kev_import_request still checked kev_url against the CISA host allowlist even though import_kev_feed (65d60a9) now always fetches the hardcoded default in that mode -- so a validated same-host custom path was silently discarded, and the validation itself was misleading (accept-then-ignore). Chose Devin's second suggested option over restoring same-host customization: honoring a validated-but-still-request-controlled URL on the default path is exactly the pattern that triggered the original CodeQL SSRF alert, so reintroducing it isn't a real fix. Instead, kev_url is now only validated when allow_non_default_hosts is true (the one mode where it's actually fetched) -- and once opted in, any well-formed http(s) URL is accepted with no host restriction, matching how that same flag already works for phishing-database and TAXII. KEV_ALLOWED_HOSTS is removed as dead code; there is no longer a partial-trust "same host, no opt-in" tier to enforce. Replaced the now-invalid kev_feed_import_rejects_disallowed_host_by_default HTTP test (there is no more "disallowed host" rejection under the new contract) with a validate_kev_import_request unit test covering both modes directly. * fix(security): remove kev_url from the request contract entirely CodeQL's critical SSRF alert (rust/request-forgery) was still firing on the previous fix (65d60a9): gating the tainted request.kev_url behind an allow_non_default_hosts runtime flag doesn't register as a sanitizer to CodeQL's dataflow analysis -- the string still originates from the HTTP request body and still reaches fetch_text_feed on that code path, so the alert (rightly, from a pure taint-tracking standpoint) persisted. Rather than keep trying to convince the analyzer a runtime guard is safe, removed the taint source outright: kev_url and allow_non_default_hosts are gone from KevImportRequest entirely. import_kev_feed always fetches AppState::kev_catalog_url, which is deployment-time config only -- set via the new KEV_CATALOG_URL env var (validated at startup, alongside run_from_env's other env parsing) or AppState::with_kev_catalog_url() in tests -- never sourced from a client request. There is now no code path in this handler where request-supplied data reaches an outbound fetch at all. This is a stronger fix than the previous one on the merits too, not just for the analyzer: KEV genuinely has one canonical, stable, government-published URL, so per-request override was never load- bearing functionality, just a testing convenience that's now served by the AppState builder instead. Updated the three affected tests to point AppState::kev_catalog_url at a local mock server instead of the request body, and replaced the now-obsolete kev_url validation test with a plain feed-metadata validation test. CLAUDE.md's Runtime Configuration section documents the new env var. * fix(kev): decouple KEV catalog fetch from the shared request-URL sink fetch_text_feed's url parameter is fed by phishing-database's request-supplied domain_url/ip_url (a pre-existing, admin-gated "fetch from an operator-chosen URL" design on main). Routing the KEV catalog pull through that same shared function -- confirmed via diff against origin/main that fetch_text_feed/validate_http_url were otherwise byte-identical -- was enough for CodeQL's rust/request-forgery query to keep flagging the shared sink as newly touched by this PR, even after KEV_CATALOG_URL was made config-only. Give KEV its own fetch_kev_catalog function (same pattern already used by fetch_taxii_objects) so the config-only path never shares a function with the request-URL adapters, and revert validate_http_url to its original two-argument form now that KEV no longer needs a custom allowed-hosts list. Also add KEV_CATALOG_URL to clear_run_env: Devin Review flagged that an inherited value would leak across run_from_env tests, since the list omitted it while validating every other run_from_env env var. * fix(kev): restrict KEV_CATALOG_URL to CISA's own host Devin Review flagged that KEV_CATALOG_URL had no host allowlist, so an unintended inherited or misconfigured value could redirect this privileged catalog fetch -- a real SSRF sub-pattern (env-var-sourced URLs are externally influenceable via container/orchestrator inheritance, not just via request bodies), which lines up with why CodeQL kept flagging feed_http.get(url) here even after the previous commit fully decoupled the fetch from any request-derived data. Add validate_kev_catalog_url, enforced both at startup (fail fast on a bad env var) and again immediately before the fetch: the host must be www.cisa.gov or loopback (loopback only so tests can point it at a local mock server), with no override -- unlike the operator-URL adapters, KEV has no legitimate reason to fetch from anywhere else. * docs(kev): correct stale "internal mirror" language for the new host allowlist Devin Review caught that AppState::with_kev_catalog_url's doc comment still promised support for pointing KEV_CATALOG_URL at an internal mirror, which the host-allowlist fix in 3a47ce8 now rejects at startup -- a real contract mismatch, not just stale wording. There was never an actual mirror requirement (that phrase was leftover illustrative language from an earlier draft); update the builder's doc comment and CLAUDE.md's Runtime Configuration entry to describe the real contract (CISA's own host, or loopback for local test mocking) rather than inventing a mirror-allowlist feature nobody asked for. * fix: validate CVE ID syntax on KEV import; scope Windows cfg precisely CodeRabbit review, both real: - kev_import.rs: any non-empty cveID (e.g. "not-a-cve") was accepted and stored as a cve threat indicator. Add is_valid_cve_id, checking CVE.org's CVE-<4-digit year>-<4+ digit sequence> syntax case-insensitively; entries that fail it are now Skipped like a missing cveID already was. Panic-safe on arbitrary catalog text via str::get instead of direct slicing (added a multi-byte-boundary case to parse_never_panics_on_arbitrary_text to cover it). - main.rs: install_shutdown_signal's second definition was gated on cfg(not(unix)), but its body calls tokio::signal::windows::ctrl_c, which only exists on Windows -- any other non-Unix target would fail to compile there. Scope the cfg to windows specifically. * fix(threat-feeds): don't reap indicators still owned by another feed Devin Review flagged a real bug in the feed-ownership reconciliation logic introduced by an external merge (192ffba, authored outside this session): apply_threat_feed_import removed every key the refreshing feed had previously owned from the global threats collection unconditionally, without checking whether another feed's ownership record still claimed the same indicator_type+value+source key. Two feeds sharing a key (e.g. the same CVE imported under a shared `source`) meant refreshing either one made the indicator vanish from enforcement until the other feed's next refresh happened to re-add it. Track "still owned by some other feed" via the current (post-replace) ownership table and only reap a dropped key when no feed claims it any more. Also switches previous_keys from a Vec to a HashSet, which incidentally fixes a second (lower-severity) finding on the same commit: the per-threat previous_keys.contains() scan was O(n) per retained item, made O(1) here. Added feed_refresh_preserves_indicators_still_owned_by_another_feed, which fails against the pre-fix logic (the shared indicator disappears after the first feed's refresh) and passes with it -- verified by reasoning through both code paths. Not actioned (informational/acceptable trade-offs, not bugs): - "Upgraded feeds retain withdrawn indicators": state persisted before this feature existed has no ownership history, so the first refresh per feed after upgrade can't retroactively reconcile pre-existing drift. Self-heals from each feed's first post-upgrade refresh onward; there's no safe way to backfill ownership for data imported before it was tracked. - "DNSBL refresh remains append-only": reconciliation covers threats only, matching the scope of the original finding this responds to (KEV catalogs carry no DNSBL entries). Extending it to DNSBL entries for the other four adapters is a follow-up, not a regression here. * fix(kev): fail closed without write creds * fix(kev): reject mostly-unparsable catalogs; scope credential source to admin creds Devin Review, both real: - kev_import.rs: apply_threat_feed_import now reconciles (a refresh treats keys missing from the new snapshot as withdrawn and removes them). kev_material_from_value's only acceptance bar was "at least one usable cveID," so a catalog that's mostly unparsable -- a fetch truncated mid-transfer, a CISA response format regression -- would have been accepted and, via reconciliation, read as a mass withdrawal of still-exploited CVEs instead of the bad fetch it actually was. Require a real majority of entries to have parsed (skipped_entries <= threats.len()) before trusting a snapshot as authoritative. Adjusted skips_entries_with_malformed_cve_id's fixture to stay under the new bar and added rejects_catalog_where_most_entries_are_unparsable. - credentials.rs: bootstrap_secrets set the registry-wide CredentialSource to File whenever ANY key -- including a file that supplies only kev_catalog_url -- came from the credentials file, even when ADMIN_TOKEN/ADMIN_TOKENS actually came from env. CredentialSource is documented and reported via HealthStatus/support bundle as admin credential provenance specifically, so this misreported security- relevant operational state. Track admin-credential file/env provenance independently of kev_catalog_url's, matching the documented contract. Added file_only_kev_catalog_url_does_not_misreport_env_admin_token_as_file_backed. Not actioned in this commit -- flagging separately for the user's scope decision: Devin also noted that apply_threat_feed_import's reconciliation now applies uniformly to all five existing feed adapters (STIX/MISP/TAXII/OpenCTI/phishing-database), not just KEV, which changes their prior upsert-only semantics; anyone relying on incremental/partial imports under a reused feed_id across the other four adapters would now see earlier entries treated as withdrawn. This is a cross-adapter behavior/policy question outside what a bug fix can resolve unilaterally. * fix(kev): remove runtime catalog URL override * fix(kev): preserve operator indicators on feed refresh * fix(kev): preserve operator-owned threat payloads * fix(threat-feeds): report actual upserted count, not submitted count Devin Review: apply_threat_feed_import's operator-ownership skip (8b7954d) omits operator-owned threats from the upsert loop, but ThreatFeedImportResult.upserted_threats still reported feed.threats.len() -- the full submitted set, including entries that were skipped. Import clients (including KEV's response) received an inflated success count whenever a feed overlapped operator-managed data. Count actual upserts in the loop and return that. ThreatFeedStatus.threat_count is left as feed.threats.len() deliberately -- it represents catalog membership (what this feed's snapshot claims), not applied mutations, per Devin's suggested distinction. Added import_result_excludes_operator_owned_threats_from_upserted_count. --------- Co-authored-by: Claude Co-authored-by: OpenAI Codex --- CLAUDE.md | 2 +- crates/waf-ids-core/src/lib.rs | 86 ++ docs/architecture.md | 8 +- ...haining-kev-epss-cvss-arxiv-2506.01220.pdf | Bin 0 -> 232425 bytes docs/security/compliance-mapping.md | 2 +- src/credentials.rs | 28 +- src/kev_import.rs | 335 ++++++ src/lib.rs | 1028 ++++++++++++++++- src/main.rs | 4 +- 9 files changed, 1473 insertions(+), 20 deletions(-) create mode 100644 docs/papers/vulnerability-management-chaining-kev-epss-cvss-arxiv-2506.01220.pdf create mode 100644 src/kev_import.rs diff --git a/CLAUDE.md b/CLAUDE.md index f6a0a676..742e3096 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -62,7 +62,7 @@ The core stays an in-repo workspace crate on purpose (no git submodule) until it ## Runtime Configuration -Read in `run_from_env` (`src/lib.rs`): `BIND_ADDR` (default `127.0.0.1:8080`), `ADMIN_TOKEN` (write token for `X-Admin-Token`), `ADMIN_TOKENS` (comma-separated `token:actor` pairs for multi-token RBAC with per-token audit actors), `WAF_IDS_STATE_PATH` (optional JSON state file; omitted = seeded in-memory state), `DNSBL_ORIGIN` (default `dnsbl.local`), `EVENT_LIMIT` (default 1000, must be > 0), `RATE_LIMIT` / `RATE_LIMIT_WINDOW`. +Read in `run_from_env` (`src/lib.rs`): `BIND_ADDR` (default `127.0.0.1:8080`), `WAF_IDS_STATE_PATH` (optional JSON state file; omitted = seeded in-memory state), `DNSBL_ORIGIN` (default `dnsbl.local`), `EVENT_LIMIT` (default 1000, must be > 0), `RATE_LIMIT` / `RATE_LIMIT_WINDOW`, `WAF_IDS_CREDENTIALS_PATH` (optional JSON bootstrap file for process-local credentials/config), `ADMIN_TOKEN` (bootstrap transport for the shared write token), and `ADMIN_TOKENS` (bootstrap transport for comma-separated `token:actor[:role]` RBAC entries). `ADMIN_TOKEN` and `ADMIN_TOKENS` are loaded into `CredentialRegistry` before the server starts; handlers read the in-process registry/AppState copy, not raw env vars. KEV imports use the built-in CISA endpoint at runtime; only in-crate tests can override it through `AppState::with_kev_catalog_url` to point at a loopback mock server. ## Key Conventions diff --git a/crates/waf-ids-core/src/lib.rs b/crates/waf-ids-core/src/lib.rs index e3788698..f9673e0c 100644 --- a/crates/waf-ids-core/src/lib.rs +++ b/crates/waf-ids-core/src/lib.rs @@ -11,6 +11,8 @@ pub const TARGET_SALE_VALUE_KRW: u64 = 2_000_000_000; pub struct AppData { pub routes: Vec, pub threats: Vec, + #[serde(default)] + pub operator_threat_keys: Vec, pub dnsbl: Vec, pub events: Vec, pub next_event_id: u64, @@ -22,6 +24,8 @@ pub struct AppData { pub commercial: CommercialProfile, #[serde(default)] pub threat_feeds: Vec, + #[serde(default)] + pub threat_feed_ownership: Vec, } impl AppData { @@ -42,6 +46,7 @@ impl AppData { source: "seed:owasp-crs-shape".to_string(), ttl_seconds: 86_400, }], + operator_threat_keys: Vec::new(), dnsbl: vec![DnsblEntry { address: "203.0.113.10".parse().expect("seed IP address is valid"), code: "127.0.0.2".to_string(), @@ -56,6 +61,7 @@ impl AppData { next_audit_log_id: 1, commercial: CommercialProfile::seeded(), threat_feeds: Vec::new(), + threat_feed_ownership: Vec::new(), } } } @@ -179,6 +185,19 @@ pub struct ThreatFeedStatus { pub ttl_seconds: u64, } +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct ThreatFeedOwnership { + pub feed_id: String, + pub threat_keys: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +pub struct ThreatIndicatorKey { + pub indicator_type: String, + pub value: String, + pub source: String, +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct ThreatFeedImport { pub feed_id: String, @@ -533,6 +552,32 @@ pub fn upsert_threat_feed( feed } +pub fn threat_indicator_key(indicator: &ThreatIndicator) -> ThreatIndicatorKey { + ThreatIndicatorKey { + indicator_type: indicator.indicator_type.clone(), + value: indicator.value.clone(), + source: indicator.source.clone(), + } +} + +pub fn replace_threat_feed_ownership( + ownership: &mut Vec, + feed_id: String, + threat_keys: Vec, +) -> Vec { + if let Some(existing) = ownership.iter_mut().find(|item| item.feed_id == feed_id) { + let previous = existing.threat_keys.clone(); + existing.threat_keys = threat_keys; + previous + } else { + ownership.push(ThreatFeedOwnership { + feed_id, + threat_keys, + }); + Vec::new() + } +} + pub fn record_audit_log(data: &mut AppData, entry: NewAuditLogEntry) -> AuditLogEntry { let audit_log = AuditLogEntry { id: data.next_audit_log_id, @@ -845,6 +890,14 @@ pub fn score_request( let kind = indicator.indicator_type.to_ascii_lowercase(); let matched = if matches!(kind.as_str(), "ip" | "client_ip" | "source_ip" | "src_ip") { client_ip.is_some_and(|ip| indicator.value.parse::().ok() == Some(ip)) + } else if kind == "cve" { + // A CVE identifier is vulnerability-catalog metadata (e.g. from a + // CISA KEV import), not a request-content observable: it can + // legitimately appear in a vulnerability-management or security + // tool's own traffic (`/api/cve/CVE-2021-44228`), so it must never + // drive content-substring scoring. It stays visible via the + // threat-indicator, feed-freshness, and buyer-evidence APIs. + false } else { haystack.contains(&indicator.value.to_lowercase()) }; @@ -1292,6 +1345,14 @@ fn buyer_evidence_endpoints() -> Vec { "OpenCTI observable/indicator JSON ingest into threat indicators and DNSBL (admin-auth)", false, ), + buyer_evidence_endpoint( + "cisa_kev_ingest", + "POST", + "/api/threat-intel/cisa-kev", + "application/json", + "CISA Known Exploited Vulnerabilities catalog pull into CVE threat indicators (admin-auth)", + false, + ), ] } @@ -1441,6 +1502,31 @@ mod tests { assert_eq!(miss.score, 0); } + #[test] + fn score_request_never_content_matches_cve_indicators() { + // A CVE indicator (e.g. from a CISA KEV import) is vulnerability + // metadata, not a request-content signature: a security-tooling + // request can legitimately carry the literal CVE string, and that + // must never contribute to the block score. + let threats = vec![ThreatIndicator { + value: "CVE-2021-44228".to_string(), + indicator_type: "cve".to_string(), + severity: Severity::Critical, + source: "feed:cisa-kev".to_string(), + ttl_seconds: 86_400, + }]; + let hit = score_request( + "/api/cve/CVE-2021-44228", + None, + "looking up CVE-2021-44228 details", + None, + &threats, + &[], + ); + assert_eq!(hit.score, 0); + assert_eq!(hit.reason, "no matching indicator"); + } + #[test] fn score_request_saturates_instead_of_overflowing_on_many_matches() { // Regression: `score` is a u16 accumulator. With enough matching diff --git a/docs/architecture.md b/docs/architecture.md index 89291bf5..e1ee578b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -45,10 +45,16 @@ flowchart LR - **WAF**: Coraza/OWASP CRS audit JSON/NDJSON ingest is available at `POST /api/waf/coraza/audit` (admin token). Interrupted transactions and CRS rule messages become `SecurityEvent` rows and feed gateway enforcement (DNSBL + `client_ip`/`path` threat indicators) so subsequent gateway decisions block matching clients. In-process Coraza embedding remains a follow-up — do not replace CRS with hand-rolled rules. - **IDS**: Suricata EVE JSON/NDJSON ingest is available at `POST /api/ids/suricata/eve` (admin token). Alert records become `SecurityEvent` rows for SOC export/KPI; full route correlation and live EVE tailing remain follow-ups. -- **Threat Intelligence**: STIX 2.x indicator/bundle ingest is available at `POST /api/threat-intel/stix` (admin token), MISP Event/attribute JSON ingest at `POST /api/threat-intel/misp` (admin token), TAXII 2.1 collection poll at `POST /api/threat-intel/taxii/poll` (admin token; Basic/Bearer optional), and OpenCTI observable/indicator export ingest at `POST /api/threat-intel/opencti` (admin token). All update `ThreatIndicator` / `DnsblEntry` plus feed freshness. Live MISP REST pull and live OpenCTI GraphQL pull remain follow-ups. +- **Threat Intelligence**: STIX 2.x indicator/bundle ingest is available at `POST /api/threat-intel/stix` (admin token), MISP Event/attribute JSON ingest at `POST /api/threat-intel/misp` (admin token), TAXII 2.1 collection poll at `POST /api/threat-intel/taxii/poll` (admin token; Basic/Bearer optional), OpenCTI observable/indicator export ingest at `POST /api/threat-intel/opencti` (admin token), and a CISA Known Exploited Vulnerabilities (KEV) catalog pull at `POST /api/threat-intel/cisa-kev` (admin token; fetches the official catalog and upserts one `cve` threat indicator per entry, severity escalated when CISA has tied the CVE to a known ransomware campaign). All update `ThreatIndicator` / `DnsblEntry` plus feed freshness. Live MISP REST pull and live OpenCTI GraphQL pull remain follow-ups. - **DNSBL Serving**: Hickory DNS should serve authoritative DNSBL responses directly after zone export semantics stabilize. - **AI SOC**: AI triage should summarize events, map likely ATT&CK tactics, and recommend actions. Enforcement-changing recommendations require human approval. +### Further reading (CISA KEV catalog pull) + +- CISA. (2021). *Binding Operational Directive 22-01: Reducing the Significant Risk of Known Exploited Vulnerabilities.* Cybersecurity and Infrastructure Security Agency. https://www.cisa.gov/known-exploited-vulnerabilities — the directive establishing the catalog's confirmed-active-exploitation inclusion criterion, which is why `kev_import.rs` treats catalog membership alone as at least `High` severity rather than deriving it from a numeric score. +- Jacobs, J., Romanosky, S., Edwards, B., Adjerid, I., & Roytman, M. (2021). Exploit Prediction Scoring System (EPSS). *Digital Threats: Research and Practice, 2*(3), Article 20. https://doi.org/10.1145/3436242 — the seminal data-driven framework establishing that confirmed/predicted exploitation likelihood is a stronger remediation-priority signal than static CVSS severity, motivating exploitation-evidence-first indicators like KEV over severity-only scoring. +- Shimizu, N., & Hashimoto, M. (2025). Vulnerability Management Chaining: An Integrated Framework for Efficient Cybersecurity Risk Prioritization. *arXiv:2506.01220* — [`papers/vulnerability-management-chaining-kev-epss-cvss-arxiv-2506.01220.pdf`](papers/vulnerability-management-chaining-kev-epss-cvss-arxiv-2506.01220.pdf) (CC BY 4.0). Demonstrates that KEV-membership-first filtering ahead of CVSS materially reduces urgent-remediation workload versus severity-only triage, and that KEV alone still misses exploited vulnerabilities EPSS catches — supporting this adapter's role as one input among several proven feeds (STIX/MISP/TAXII/OpenCTI), not a replacement for them. + ## Security Boundaries - Default bind address is localhost. diff --git a/docs/papers/vulnerability-management-chaining-kev-epss-cvss-arxiv-2506.01220.pdf b/docs/papers/vulnerability-management-chaining-kev-epss-cvss-arxiv-2506.01220.pdf new file mode 100644 index 0000000000000000000000000000000000000000..cd339327b3d99da1e8555e8c6e3de1a7a87938ac GIT binary patch literal 232425 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 literal 0 HcmV?d00001 diff --git a/docs/security/compliance-mapping.md b/docs/security/compliance-mapping.md index 8251d794..b956bad7 100644 --- a/docs/security/compliance-mapping.md +++ b/docs/security/compliance-mapping.md @@ -11,7 +11,7 @@ This document maps the commercial baseline to common enterprise security review | Change Control | Route-scoped monitor/block modes | Approval workflow and rollback attestations | | Availability | Health endpoint, Kubernetes probes | HA storage, multi-replica state backend | | Incident Response | Operations runbook and support bundle | On-call process, SLA/SLO reporting | -| Threat Intelligence | Feed import API, STIX/MISP/OpenCTI document ingest, TAXII 2.1 poll, feed status | Signed feeds, live MISP REST / OpenCTI GraphQL pull | +| Threat Intelligence | Feed import API, STIX/MISP/OpenCTI document ingest, TAXII 2.1 poll, CISA KEV catalog pull, feed status | Signed feeds, live MISP REST / OpenCTI GraphQL pull | | DNSBL | Zone export and response-code validation | Authoritative DNS service and publication controls | | AI Governance | Human approval boundary documented | Model evals, prompt audit, recommendation traceability | diff --git a/src/credentials.rs b/src/credentials.rs index 02b7f39e..bcc07e50 100644 --- a/src/credentials.rs +++ b/src/credentials.rs @@ -1,4 +1,5 @@ -//! Secret-bearing configuration via a process-local credential registry. +//! Secret-bearing and fetch-sensitive configuration via a process-local +//! credential registry. //! //! Org guidance: runtime code must not treat raw environment variables as the //! source of secrets. Environment (and optional credentials file) are bootstrap @@ -8,7 +9,7 @@ use serde::{Deserialize, Serialize}; use std::{collections::HashMap, io::ErrorKind, path::Path}; -/// Well-known secret keys loaded into the registry at bootstrap. +/// Well-known credentials loaded into the registry at bootstrap. pub const CRED_ADMIN_TOKEN: &str = "admin_token"; pub const CRED_ADMIN_TOKENS: &str = "admin_tokens"; @@ -64,19 +65,23 @@ impl CredentialRegistry { .is_some_and(|v| !v.trim().is_empty()) } - /// Bootstrap secret-bearing credentials. + /// Bootstrap secret-bearing credentials plus the optional KEV fetch override. /// /// Precedence: JSON credentials file (when present) wins per-key; missing /// keys are filled from the env bootstrap values. Operational non-secret - /// config (bind address, limits, DNSBL origin) stays on env. + /// config (bind address, limits, DNSBL origin) stays on env. The KEV URL + /// defaults to the built-in CISA endpoint and is accepted here only as a + /// server-side override that must still satisfy the runtime allowlist. pub fn bootstrap_secrets( credentials_path: Option<&Path>, env_admin_token: Option, env_admin_tokens: Option, ) -> Result { let mut values = HashMap::new(); - let mut from_file = false; - let mut from_env = false; + // CredentialSource is documented (and reported via HealthStatus/support + // bundle) as admin-secret provenance specifically. + let mut admin_from_file = false; + let mut admin_from_env = false; if let Some(path) = credentials_path { match std::fs::read_to_string(path) { @@ -93,7 +98,7 @@ impl CredentialRegistry { let text = json_value_as_nonempty_string(raw); if let Some(text) = text { values.insert(key.to_string(), text); - from_file = true; + admin_from_file = true; } } } @@ -112,18 +117,17 @@ impl CredentialRegistry { && let Some(token) = env_admin_token.filter(|value| !value.is_empty()) { values.insert(CRED_ADMIN_TOKEN.to_string(), token); - from_env = true; + admin_from_env = true; } if !values.contains_key(CRED_ADMIN_TOKENS) && let Some(tokens) = env_admin_tokens.filter(|value| !value.is_empty()) { values.insert(CRED_ADMIN_TOKENS.to_string(), tokens); - from_env = true; + admin_from_env = true; } - - let source = if from_file { + let source = if admin_from_file { CredentialSource::File - } else if from_env { + } else if admin_from_env { CredentialSource::Env } else { CredentialSource::None diff --git a/src/kev_import.rs b/src/kev_import.rs new file mode 100644 index 00000000..68755e2b --- /dev/null +++ b/src/kev_import.rs @@ -0,0 +1,335 @@ +//! CISA Known Exploited Vulnerabilities (KEV) catalog import adapter. +//! +//! Parses the CISA KEV catalog JSON +//! () +//! into gateway [`ThreatIndicator`] rows. This is a proven federal +//! authoritative-source boundary — not a hand-rolled detection engine. +//! +//! The catalog is CVE-centric: entries carry no IP/domain/URL/hash +//! observable, so `dnsbl` stays empty. It is kept on [`KevImportMaterial`] +//! only for parity with the shared [`waf_ids_core::ThreatFeedImport`] shape +//! every adapter in this family produces. + +use waf_ids_core::{DnsblEntry, Severity, ThreatIndicator}; + +/// Parsed KEV import ready for the existing threat-feed upsert path. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct KevImportMaterial { + pub threats: Vec, + pub dnsbl: Vec, + pub skipped_entries: usize, +} + +/// Extract CVE indicators from a CISA KEV catalog JSON document. +/// +/// Accepts the real catalog shape (`{"vulnerabilities": [...], ...}`) or a +/// bare JSON array of vulnerability entries. +pub fn kev_material_from_value( + value: &serde_json::Value, + source: &str, + ttl_seconds: u64, +) -> Result { + let entries = match value { + serde_json::Value::Object(_) => value + .get("vulnerabilities") + .and_then(|v| v.as_array()) + .ok_or("KEV document must have a \"vulnerabilities\" array")?, + serde_json::Value::Array(items) => items, + _ => { + return Err( + "KEV document must be a catalog object or an array of vulnerability entries" + .to_string(), + ); + } + }; + if entries.is_empty() { + return Err("KEV catalog contained no vulnerability entries".to_string()); + } + + let mut threats = Vec::new(); + let mut skipped_entries = 0usize; + for entry in entries { + match kev_entry_outcome(entry, source, ttl_seconds) { + KevEntryOutcome::Mapped(threat) => threats.push(threat), + KevEntryOutcome::Skipped => skipped_entries += 1, + } + } + + if threats.is_empty() { + return Err("no KEV entries carried a usable cveID".to_string()); + } + // A refreshed import now reconciles: entries missing from this snapshot + // are treated as withdrawn and removed from enforcement (see + // apply_threat_feed_import). A catalog that's mostly unparsable -- + // truncated mid-transfer, or a CISA response format regression -- would + // otherwise look like a mass withdrawal of still-exploited CVEs instead + // of the bad fetch it actually is. Require a real majority of entries to + // have parsed before trusting this snapshot as authoritative. + if skipped_entries >= threats.len() { + return Err(format!( + "KEV catalog mostly unparsable: {skipped_entries} entries skipped vs {} usable -- refusing to treat as an authoritative snapshot", + threats.len() + )); + } + + Ok(KevImportMaterial { + threats, + dnsbl: Vec::new(), + skipped_entries, + }) +} + +/// Parse a CISA KEV catalog JSON body string. +pub fn parse_kev_document( + body: &str, + source: &str, + ttl_seconds: u64, +) -> Result { + let trimmed = body.trim(); + if trimmed.is_empty() { + return Err("empty KEV catalog body".to_string()); + } + let value: serde_json::Value = + serde_json::from_str(trimmed).map_err(|error| format!("invalid KEV JSON: {error}"))?; + kev_material_from_value(&value, source, ttl_seconds) +} + +enum KevEntryOutcome { + Mapped(ThreatIndicator), + Skipped, +} + +fn kev_entry_outcome(entry: &serde_json::Value, source: &str, ttl_seconds: u64) -> KevEntryOutcome { + let Some(cve_id) = entry + .get("cveID") + .and_then(|v| v.as_str()) + .map(str::trim) + .filter(|s| is_valid_cve_id(s)) + else { + return KevEntryOutcome::Skipped; + }; + + // CISA's own inclusion criteria (confirmed active exploitation in the + // wild) already implies high severity; entries CISA has additionally + // tied to a known ransomware campaign are escalated to critical. + let known_ransomware = entry + .get("knownRansomwareCampaignUse") + .and_then(|v| v.as_str()) + .is_some_and(|s| s.eq_ignore_ascii_case("known")); + let severity = if known_ransomware { + Severity::Critical + } else { + Severity::High + }; + + KevEntryOutcome::Mapped(ThreatIndicator { + value: cve_id.to_ascii_uppercase(), + indicator_type: "cve".to_string(), + severity, + source: source.to_string(), + ttl_seconds, + }) +} + +/// Checks the `CVE-<4-digit year>-<4+ digit sequence>` syntax CVE.org +/// defines (), +/// case-insensitively. A malformed `cveID` (typo, placeholder, truncated +/// feed) would otherwise become an indistinguishable-looking `cve` threat +/// indicator with no signal that it never matched a real CVE record. +fn is_valid_cve_id(value: &str) -> bool { + // `str::get` (unlike slicing) returns None instead of panicking on a + // byte range that isn't a valid char boundary, so this stays panic-safe + // on arbitrary catalog input. + let Some(rest) = value + .get(0..4) + .filter(|prefix| prefix.eq_ignore_ascii_case("cve-")) + .map(|_| &value[4..]) + else { + return false; + }; + let Some((year, sequence)) = rest.split_once('-') else { + return false; + }; + year.len() == 4 + && year.bytes().all(|b| b.is_ascii_digit()) + && sequence.len() >= 4 + && sequence.bytes().all(|b| b.is_ascii_digit()) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn sample_catalog() -> &'static str { + r#"{ + "title": "CISA Catalog of Known Exploited Vulnerabilities", + "catalogVersion": "2026.08.27", + "dateReleased": "2026-08-27T17:00:36.6632Z", + "count": 2, + "vulnerabilities": [ + { + "cveID": "cve-2023-49105", + "vendorProject": "ownCloud", + "product": "ownCloud", + "vulnerabilityName": "ownCloud Improper Authentication Vulnerability", + "dateAdded": "2026-08-27", + "shortDescription": "ownCloud contains an improper authentication vulnerability.", + "requiredAction": "Apply mitigations in accordance with vendor instructions.", + "dueDate": "2026-08-30", + "knownRansomwareCampaignUse": "Unknown", + "notes": "https://owncloud.org/security", + "cwes": ["CWE-287"] + }, + { + "cveID": "CVE-2021-44228", + "vendorProject": "Apache", + "product": "Log4j2", + "vulnerabilityName": "Apache Log4j2 Remote Code Execution Vulnerability", + "dateAdded": "2021-12-10", + "shortDescription": "Apache Log4j2 JNDI features do not protect against attacker controlled LDAP.", + "requiredAction": "Apply mitigations in accordance with vendor instructions.", + "dueDate": "2021-12-24", + "knownRansomwareCampaignUse": "Known", + "notes": "", + "cwes": ["CWE-917", "CWE-400"] + } + ] + }"# + } + + #[test] + fn maps_catalog_entries_and_escalates_ransomware_severity() { + let material = parse_kev_document(sample_catalog(), "feed:cisa-kev", 86_400).unwrap(); + assert_eq!(material.threats.len(), 2); + assert!(material.dnsbl.is_empty()); + assert_eq!(material.skipped_entries, 0); + + let owncloud = material + .threats + .iter() + .find(|t| t.value == "CVE-2023-49105") + .expect("owncloud CVE normalized to uppercase"); + assert_eq!(owncloud.indicator_type, "cve"); + assert_eq!(owncloud.severity, Severity::High); + assert_eq!(owncloud.source, "feed:cisa-kev"); + assert_eq!(owncloud.ttl_seconds, 86_400); + + let log4j = material + .threats + .iter() + .find(|t| t.value == "CVE-2021-44228") + .expect("log4j CVE present"); + assert_eq!(log4j.severity, Severity::Critical); + } + + #[test] + fn accepts_bare_array_of_entries() { + let raw = r#"[{"cveID":"CVE-2024-0001","knownRansomwareCampaignUse":"Unknown"}]"#; + let material = parse_kev_document(raw, "feed:cisa-kev", 3600).unwrap(); + assert_eq!(material.threats.len(), 1); + assert_eq!(material.threats[0].value, "CVE-2024-0001"); + } + + #[test] + fn skips_entries_missing_cve_id() { + let raw = r#"{"vulnerabilities": [ + {"vendorProject": "NoId Inc", "knownRansomwareCampaignUse": "Unknown"}, + {"cveID": "CVE-2024-9998", "knownRansomwareCampaignUse": "Unknown"}, + {"cveID": "CVE-2024-9999", "knownRansomwareCampaignUse": "Unknown"} + ]}"#; + let material = parse_kev_document(raw, "feed:cisa-kev", 3600).unwrap(); + assert_eq!(material.threats.len(), 2); + assert_eq!(material.skipped_entries, 1); + } + + #[test] + fn skips_entries_with_malformed_cve_id() { + let raw = r#"{"vulnerabilities": [ + {"cveID": "not-a-cve", "knownRansomwareCampaignUse": "Unknown"}, + {"cveID": "CVE-24-0001", "knownRansomwareCampaignUse": "Unknown"}, + {"cveID": "CVE-2024-0001", "knownRansomwareCampaignUse": "Unknown"}, + {"cveID": "CVE-2024-9998", "knownRansomwareCampaignUse": "Unknown"}, + {"cveID": "CVE-2024-9999", "knownRansomwareCampaignUse": "Unknown"} + ]}"#; + let material = parse_kev_document(raw, "feed:cisa-kev", 3600).unwrap(); + assert_eq!(material.threats.len(), 3); + assert!( + material + .threats + .iter() + .any(|threat| threat.value == "CVE-2024-9999") + ); + assert_eq!(material.skipped_entries, 2); + } + + #[test] + fn rejects_catalog_where_most_entries_are_unparsable() { + // A snapshot that's mostly garbage (truncated fetch, upstream format + // regression) must not be trusted as authoritative -- a refresh now + // reconciles, so treating this as "the current catalog" would read + // as a mass withdrawal of still-tracked CVEs. + let raw = r#"{"vulnerabilities": [ + {"cveID": "not-a-cve"}, + {"cveID": "also-not-a-cve"}, + {"cveID": "CVE-24-0001"}, + {"cveID": "CVE-2024-9999", "knownRansomwareCampaignUse": "Unknown"} + ]}"#; + let error = parse_kev_document(raw, "feed:cisa-kev", 3600).unwrap_err(); + assert!(error.contains("mostly unparsable"), "got: {error}"); + } + + #[test] + fn rejects_catalog_where_usable_and_skipped_entries_tie() { + let raw = r#"{"vulnerabilities": [ + {"cveID": "CVE-2024-0001", "knownRansomwareCampaignUse": "Unknown"}, + {"vendorProject": "missing-id"}, + {"cveID": "CVE-2024-0002", "knownRansomwareCampaignUse": "Unknown"}, + {"cveID": "not-a-cve"} + ]}"#; + let error = parse_kev_document(raw, "feed:cisa-kev", 3600).unwrap_err(); + assert!(error.contains("mostly unparsable"), "got: {error}"); + } + + #[test] + fn validates_cve_id_syntax() { + assert!(is_valid_cve_id("CVE-2024-0001")); + assert!(is_valid_cve_id("cve-2024-0001")); + assert!(is_valid_cve_id("CVE-2021-44228")); + assert!(is_valid_cve_id("CVE-2024-123456")); + assert!(!is_valid_cve_id("not-a-cve")); + assert!(!is_valid_cve_id("CVE-24-0001")); + assert!(!is_valid_cve_id("CVE-2024-001")); + assert!(!is_valid_cve_id("CVE-2024-")); + assert!(!is_valid_cve_id("CVE-")); + assert!(!is_valid_cve_id("")); + assert!(!is_valid_cve_id("CV")); + // A multi-byte char straddling the byte-4 prefix boundary must not panic. + assert!(!is_valid_cve_id("CVE\u{20ac}1234-0001")); + } + + #[test] + fn rejects_empty_and_non_kev_documents() { + assert!(parse_kev_document("", "s", 60).is_err()); + assert!(parse_kev_document("not-json", "s", 60).is_err()); + assert!(parse_kev_document(r#"{"foo":1}"#, "s", 60).is_err()); + assert!(parse_kev_document(r#"{"vulnerabilities": []}"#, "s", 60).is_err()); + assert!( + parse_kev_document(r#"{"vulnerabilities": [{"vendorProject":"x"}]}"#, "s", 60).is_err() + ); + } + + #[test] + fn parse_never_panics_on_arbitrary_text() { + for sample in [ + "", + "{", + "[]", + "null", + "\0", + "{\"vulnerabilities\":[]}", + "{\"vulnerabilities\":[{\"cveID\":\"CVE\u{20ac}1234-0001\"}]}", + ] { + let _ = parse_kev_document(sample, "s", 60); + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 8f54751d..ab902cae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,9 +22,10 @@ use tokio::{ use waf_ids_core::{ AppData, BLOCK_SCORE, buyer_evidence_manifest_at, commercial_readiness_snapshot_at, enforce_event_limit, kpi_snapshot_at, prometheus_exposition, rate_limit_step, record_audit_log, - select_route, signature_catalog, threat_feed_freshness_snapshot, upsert_dnsbl, upsert_route, - upsert_threat, upsert_threat_feed, validate_commercial_profile, validate_dnsbl, validate_route, - validate_threat, validate_threat_feed_import, + replace_threat_feed_ownership, select_route, signature_catalog, threat_feed_freshness_snapshot, + threat_indicator_key, upsert_dnsbl, upsert_route, upsert_threat, upsert_threat_feed, + validate_commercial_profile, validate_dnsbl, validate_route, validate_threat, + validate_threat_feed_import, }; pub use waf_ids_core::{ AuditLogEntry, BuyerEvidenceEndpoint, BuyerEvidenceManifest, BuyerEvidenceRuntimeCounts, @@ -37,6 +38,7 @@ pub use waf_ids_core::{ mod coraza_audit; mod credentials; +mod kev_import; mod misp_import; mod opencti_import; mod stix_import; @@ -71,6 +73,10 @@ pub struct AppState { // Optional LLM SOC-analysis backend (OpenAI-compatible, e.g. the // contextual-orchestrator gateway). `None` unless configured. soc_llm: Option, + // Non-test runtime always fetches the built-in CISA KEV URL. Tests can + // override it to point at a loopback mock server. + #[cfg(test)] + kev_catalog_url: Option, } /// Configuration for the optional LLM-backed SOC analysis. Points at an @@ -135,9 +141,31 @@ impl AppState { max_body_bytes: 1_048_576, clearfolio: None, soc_llm: None, + #[cfg(test)] + kev_catalog_url: None, } } + /// Override the CISA KEV catalog URL (default: the real CISA feed). + /// Deployment-time config only, for pointing at a local mock server in + /// tests -- see `validate_kev_catalog_url`, which restricts the fetch to + /// CISA's own host (or loopback) with no mirror override. Builder-style. + #[cfg(test)] + pub fn with_kev_catalog_url(mut self, url: impl Into) -> Self { + self.kev_catalog_url = Some(url.into()); + self + } + + #[cfg(test)] + fn kev_catalog_url(&self) -> &str { + self.kev_catalog_url.as_deref().unwrap_or(KEV_DEFAULT_URL) + } + + #[cfg(not(test))] + fn kev_catalog_url(&self) -> &str { + KEV_DEFAULT_URL + } + /// Set the maximum accepted request body size in bytes; larger requests are /// rejected with 413 before the handler runs. Builder-style. pub fn with_max_body_size(mut self, max_body_bytes: usize) -> Self { @@ -424,6 +452,27 @@ fn phishing_database_default_severity() -> Severity { Severity::High } +const KEV_DEFAULT_FEED_ID: &str = "cisa-kev"; +const KEV_DEFAULT_SOURCE: &str = "feed:cisa-kev"; +const KEV_DEFAULT_URL: &str = + "https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json"; +const KEV_DEFAULT_TTL_SECONDS: u64 = 86_400; +// Runtime fetches stay fixed to the official CISA endpoint. Loopback remains +// allowed so integration tests can point AppState at a local mock server. +const KEV_ALLOWED_HOSTS: &[&str] = &["www.cisa.gov"]; + +fn kev_default_feed_id() -> String { + KEV_DEFAULT_FEED_ID.to_string() +} + +fn kev_default_source() -> String { + KEV_DEFAULT_SOURCE.to_string() +} + +fn kev_default_ttl_seconds() -> u64 { + KEV_DEFAULT_TTL_SECONDS +} + fn default_true() -> bool { true } @@ -473,6 +522,7 @@ pub fn build_app(state: AppState) -> Router { .route("/api/threat-intel/misp", post(import_misp_document)) .route("/api/threat-intel/taxii/poll", post(poll_taxii_collection)) .route("/api/threat-intel/opencti", post(import_opencti_document)) + .route("/api/threat-intel/cisa-kev", post(import_kev_feed)) .route("/api/clearfolio/config", get(clearfolio_config)) .route("/api/clearfolio/documents/{kind}", post(clearfolio_submit)) .route("/api/clearfolio/jobs/{job_id}", get(clearfolio_status)) @@ -727,6 +777,25 @@ struct PhishingDatabaseImportRequest { allow_non_default_hosts: bool, } +#[derive(Debug, Clone, Deserialize, Serialize)] +struct KevImportRequest { + #[serde(default = "kev_default_feed_id")] + feed_id: String, + #[serde(default = "kev_default_source")] + source: String, + #[serde(default = "kev_default_ttl_seconds")] + ttl_seconds: u64, +} + +#[derive(Debug, Serialize)] +struct KevImportResult { + feed_id: String, + upserted_threats: usize, + upserted_dnsbl: usize, + skipped_entries: usize, + last_updated_unix: u64, +} + #[derive(Serialize)] struct SocAnalyzeResponse { event_id: u64, @@ -890,6 +959,7 @@ async fn create_threat( match state .mutate_and_persist(|data| { let saved = upsert_threat(&mut data.threats, indicator.clone()); + mark_operator_threat_key(data, &saved); record_successful_audit_log( data, actor, @@ -2018,6 +2088,93 @@ fn validate_phishing_database_import_request( Ok(()) } +fn validate_kev_import_request(request: &KevImportRequest) -> Result<(), &'static str> { + if request.feed_id.trim().is_empty() { + return Err("feed_id is required"); + } + if request.source.trim().is_empty() { + return Err("source is required"); + } + if request.ttl_seconds == 0 { + return Err("ttl_seconds must be greater than zero"); + } + Ok(()) +} + +async fn import_kev_feed( + State(state): State, + headers: HeaderMap, + Json(request): Json, +) -> Response { + if !has_write_admin_credential(&state) { + return error( + StatusCode::SERVICE_UNAVAILABLE, + "KEV import requires a configured write-capable admin credential", + ); + } + if !admin_authorized(&state, &headers) { + return error(StatusCode::UNAUTHORIZED, "missing or invalid X-Admin-Token"); + } + if let Err(message) = validate_kev_import_request(&request) { + return error(StatusCode::BAD_REQUEST, message); + } + + // Always fetches the deployment-configured CISA KEV URL (default: the + // real CISA feed; overridable only via server-side config, never by the + // request body) -- there is no request-controlled URL construction here + // at all, unlike the operator-URL adapters (phishing-database, TAXII). + // Uses its own fetch_kev_catalog rather than the shared fetch_text_feed + // so this config-only path never shares a function with (and can't be + // conflated by static analysis with) phishing-database's request-URL fetch. + let body_text = match fetch_kev_catalog(&state).await { + Ok(text) => text, + Err(message) => return error(StatusCode::BAD_GATEWAY, message), + }; + let material = match kev_import::parse_kev_document( + &body_text, + request.source.trim(), + request.ttl_seconds, + ) { + Ok(material) => material, + Err(message) => { + return error( + StatusCode::BAD_GATEWAY, + format!("invalid fetched KEV catalog: {message}"), + ); + } + }; + + let actor = audit_actor(&state, &headers); + let feed = ThreatFeedImport { + feed_id: request.feed_id.trim().to_string(), + source: request.source.trim().to_string(), + ttl_seconds: request.ttl_seconds, + threats: material.threats, + dnsbl: material.dnsbl, + }; + if let Err(message) = validate_threat_feed_import(&feed) { + return error( + StatusCode::BAD_GATEWAY, + format!("invalid fetched feed data: {message}"), + ); + } + let skipped_entries = material.skipped_entries; + match apply_threat_feed_import(&state, actor, "import_kev_feed", feed).await { + Ok(result) => ( + StatusCode::CREATED, + Json(KevImportResult { + feed_id: result.feed_id, + upserted_threats: result.upserted_threats, + upserted_dnsbl: result.upserted_dnsbl, + skipped_entries, + last_updated_unix: result.last_updated_unix, + }), + ) + .into_response(), + Err(message) => error(StatusCode::INTERNAL_SERVER_ERROR, message), + } +} + fn validate_http_url(value: &str, allow_non_default_hosts: bool) -> Result<(), &'static str> { let parsed = reqwest::Url::parse(value).map_err(|_| "feed URL must be an absolute URL")?; let host = parsed.host_str().ok_or("feed URL host is required")?; @@ -2037,6 +2194,71 @@ fn validate_http_url(value: &str, allow_non_default_hosts: bool) -> Result<(), & Ok(()) } +// Deliberately separate from `fetch_text_feed`: that helper's `url` argument is +// fed by operator-supplied request URLs for phishing-database imports. KEV does +// not support a runtime URL override, so this fetch path stays structurally +// independent and fixed to the built-in CISA host; loopback is allowed only for +// tests that inject a local mock via `with_kev_catalog_url`. +fn validate_kev_catalog_url(url: &str) -> Result<(), String> { + validate_http_url(url, /* allow_non_default_hosts */ true) + .map_err(|message| format!("invalid KEV catalog URL {url}: {message}"))?; + let parsed = reqwest::Url::parse(url).map_err(|_| format!("invalid KEV catalog URL {url}"))?; + let host = parsed + .host_str() + .ok_or_else(|| format!("invalid KEV catalog URL {url}: host is required"))?; + if !KEV_ALLOWED_HOSTS + .iter() + .any(|allowed| host.eq_ignore_ascii_case(allowed)) + && !is_loopback_host(host) + { + return Err(format!( + "KEV catalog URL {url} host is not on the CISA KEV allowlist" + )); + } + Ok(()) +} + +async fn fetch_kev_catalog(state: &AppState) -> Result { + use futures_util::StreamExt; + + let url = state.kev_catalog_url(); + validate_kev_catalog_url(url)?; + let response = state + .feed_http + .get(url) + .timeout(std::time::Duration::from_secs( + PHISHING_DATABASE_FETCH_TIMEOUT_SECS, + )) + .send() + .await + .map_err(|error| format!("failed to fetch KEV catalog {url}: {error}"))?; + let status = response.status(); + if !status.is_success() { + return Err(format!("KEV catalog {url} returned HTTP {status}")); + } + if let Some(len) = response.content_length() + && len as usize > PHISHING_DATABASE_MAX_BODY_BYTES + { + return Err(format!( + "KEV catalog {url} body too large: {len} bytes (limit: {PHISHING_DATABASE_MAX_BODY_BYTES})" + )); + } + let mut bytes = Vec::new(); + let mut stream = response.bytes_stream(); + while let Some(chunk) = stream.next().await { + let chunk = chunk + .map_err(|error| format!("failed to read KEV catalog body from {url}: {error}"))?; + if bytes.len().saturating_add(chunk.len()) > PHISHING_DATABASE_MAX_BODY_BYTES { + return Err(format!( + "KEV catalog {url} body too large: limit {PHISHING_DATABASE_MAX_BODY_BYTES} bytes exceeded while streaming" + )); + } + bytes.extend_from_slice(&chunk); + } + String::from_utf8(bytes) + .map_err(|error| format!("KEV catalog {url} is not valid UTF-8 text: {error}")) +} + fn is_loopback_host(host: &str) -> bool { host.eq_ignore_ascii_case("localhost") || host @@ -2374,6 +2596,19 @@ fn admin_authorized(state: &AppState, headers: &HeaderMap) -> bool { presented.is_some_and(|actual| actual == expected) } +fn has_write_admin_credential(state: &AppState) -> bool { + if !state.admin_tokens.is_empty() { + return state + .admin_tokens + .values() + .any(|principal| principal.can_write); + } + state + .admin_token + .as_deref() + .is_some_and(|token| !token.is_empty()) +} + fn audit_actor(state: &AppState, headers: &HeaderMap) -> String { // Prefer the actor bound to the presented RBAC token, then an explicit // actor header, then a generic label. The token itself is never logged. @@ -2460,6 +2695,13 @@ fn threat_resource_id(indicator: &ThreatIndicator) -> String { ) } +fn mark_operator_threat_key(data: &mut AppData, indicator: &ThreatIndicator) { + let key = threat_indicator_key(indicator); + if !data.operator_threat_keys.contains(&key) { + data.operator_threat_keys.push(key); + } +} + async fn apply_threat_feed_import( state: &AppState, actor: String, @@ -2469,8 +2711,42 @@ async fn apply_threat_feed_import( let imported_at = now_unix(); state .mutate_and_persist(|data| { + let operator_owned: HashSet<_> = data.operator_threat_keys.iter().cloned().collect(); + let threat_keys: Vec<_> = feed.threats.iter().map(threat_indicator_key).collect(); + let previous_keys: HashSet<_> = replace_threat_feed_ownership( + &mut data.threat_feed_ownership, + feed.feed_id.clone(), + threat_keys, + ) + .into_iter() + .collect(); + if !previous_keys.is_empty() { + // A key this feed is dropping might still be owned by another + // feed (e.g. two feeds importing the same CVE under a shared + // `source`) -- only reap it once no feed's ownership record + // claims it any more, so a refresh on one feed can't make a + // still-relevant indicator vanish from enforcement. Also keep + // indicators an operator independently upserted via /api/threats. + let still_owned: HashSet<_> = data + .threat_feed_ownership + .iter() + .filter(|ownership| ownership.feed_id != feed.feed_id) + .flat_map(|ownership| ownership.threat_keys.iter().cloned()) + .collect(); + data.threats.retain(|threat| { + let key = threat_indicator_key(threat); + !previous_keys.contains(&key) + || still_owned.contains(&key) + || operator_owned.contains(&key) + }); + } + let mut upserted_threats = 0usize; for threat in feed.threats.iter().cloned() { + if operator_owned.contains(&threat_indicator_key(&threat)) { + continue; + } upsert_threat(&mut data.threats, threat); + upserted_threats += 1; } for entry in feed.dnsbl.iter().cloned() { upsert_dnsbl(&mut data.dnsbl, entry); @@ -2488,7 +2764,7 @@ async fn apply_threat_feed_import( ); let result = ThreatFeedImportResult { feed_id: feed.feed_id.clone(), - upserted_threats: feed.threats.len(), + upserted_threats, upserted_dnsbl: feed.dnsbl.len(), last_updated_unix: imported_at, }; @@ -2788,6 +3064,9 @@ input,select{font:inherit;min-height:44px;padding:0 12px;border:1px solid var(--

OpenCTI threat intelligence

POST admin-authenticated OpenCTI GraphQL/list export JSON to /api/threat-intel/opencti (optional query: feed_id, source, ttl_seconds). Maps IPv4/IPv6, Domain-Name, Url, file hashes, and STIX indicators into threats/DNSBL. Live OpenCTI GraphQL pull is a follow-up.

+

CISA KEV catalog

+

POST admin-authenticated JSON to /api/threat-intel/cisa-kev with optional feed_id, source, and ttl_seconds. Fetches the deployment-configured CISA Known Exploited Vulnerabilities catalog URL (server-side config only, not part of this request) and upserts a cve threat indicator per entry (severity escalated to critical when CISA has tied the CVE to a known ransomware campaign).

+