-
Notifications
You must be signed in to change notification settings - Fork 0
chore: restack legacy manifest rename on hardened main #143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
f194d7a
test: stage adaptive SOC orchestration contract
seonghobae 11506af
feat: stage adaptive SOC orchestration default
seonghobae bc50579
ci: apply and verify wardnet adaptive default
seonghobae eb61643
feat(ai): delegate SOC analysis to adaptive orchestration
github-actions[bot] 4250362
test(ai): scope the auto-orchestration contract to SOC payload
seonghobae def964b
docs(ai): define the adaptive SOC orchestration boundary
seonghobae 9174a72
build(deps): bump github/codeql-action/upload-sarif to 4.37.6 (#73)
dependabot[bot] 8c8d4d5
Merge remote-tracking branch 'origin/main' into fix/pr76-rebase
seonghobae 1cc4927
fix: address PR review follow-ups on the adaptive orchestrator default
seonghobae 3f25ea5
build(deps): bump github/codeql-action/upload-sarif (#92)
dependabot[bot] 43f373f
Merge branch 'main' into agent/adaptive-orchestrator-default
seonghobae edcb1a6
build(deps): bump futures-util from 0.3.33 to 0.3.34 (#91)
dependabot[bot] a4b85a5
Merge branch 'main' into agent/adaptive-orchestrator-default
opencode-agent[bot] 1071176
Merge pull request #76 from ContextualWisdomLab/agent/adaptive-orches…
seonghobae c6501e9
fix(deploy): disable service account token automount (KSV-0036)
claude be45e69
fix(shutdown): register SIGTERM handler before announcing readiness
claude e67a939
fix(shutdown): register Windows Ctrl-C handler synchronously too
claude 8319bed
fix(deploy): disable service account token automount (KSV-0036) (#132)
seonghobae b2bcee3
feat(threat-intel): recognize the CISA Known Exploited Vulnerabilitie…
seonghobae cc15cc2
fix(deploy): remove distributable administrator credential (#137)
seonghobae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # Changelog | ||
|
|
||
| ## Unreleased | ||
|
|
||
| ### Security | ||
|
|
||
| - Removed the distributable Kubernetes administrator `Secret` and historical placeholder credential. Production deployments must provision `waf-ids-ai-soc-admin` / `ADMIN_TOKEN` through the external secret-management control plane; the workload's `secretKeyRef` is explicitly non-optional. | ||
| - Added a structural regression contract that rejects shipped administrator Secret objects, placeholder credentials, decoy workloads, init-container false positives, and optional administrator Secret references. | ||
|
|
||
| ### Operations | ||
|
|
||
| - Documented administrator credential provisioning, rotation, rollout verification, rollback, evidence handling, and the boundary with the separate runtime-authentication fail-closed work tracked in issue #78. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,8 @@ pub const TARGET_SALE_VALUE_KRW: u64 = 2_000_000_000; | |
| pub struct AppData { | ||
| pub routes: Vec<RouteConfig>, | ||
| pub threats: Vec<ThreatIndicator>, | ||
| #[serde(default)] | ||
| pub operator_threat_keys: Vec<ThreatIndicatorKey>, | ||
| pub dnsbl: Vec<DnsblEntry>, | ||
| pub events: Vec<SecurityEvent>, | ||
| pub next_event_id: u64, | ||
|
|
@@ -22,6 +24,8 @@ pub struct AppData { | |
| pub commercial: CommercialProfile, | ||
| #[serde(default)] | ||
| pub threat_feeds: Vec<ThreatFeedStatus>, | ||
| #[serde(default)] | ||
| pub threat_feed_ownership: Vec<ThreatFeedOwnership>, | ||
| } | ||
|
|
||
| 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<ThreatIndicatorKey>, | ||
| } | ||
|
|
||
| #[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<ThreatFeedOwnership>, | ||
| feed_id: String, | ||
| threat_keys: Vec<ThreatIndicatorKey>, | ||
| ) -> Vec<ThreatIndicatorKey> { | ||
| 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::<IpAddr>().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 | ||
|
Comment on lines
+893
to
+900
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } else { | ||
| haystack.contains(&indicator.value.to_lowercase()) | ||
| }; | ||
|
|
@@ -1292,6 +1345,14 @@ fn buyer_evidence_endpoints() -> Vec<BuyerEvidenceEndpoint> { | |
| "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 | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| # 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 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. | ||
|
|
||
| ## 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 | ||
| 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. 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 | ||
|
|
||
| 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 | ||
|
|
||
| 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 |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Upgrades lose existing threat ownership
Legacy state loads both ownership lists empty. Feed refreshes leave withdrawn entries active and can overwrite or later delete manually managed entries.
Prompt for agents
Was this helpful? React with 👍 or 👎 to provide feedback.