diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 8ace915..e1e352c 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "6.1.0"
+ ".": "6.2.0"
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 246f361..1d61fe2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,28 @@ this file at release-prep. See [`changelog.d/README.md`](changelog.d/README.md).
+## [6.2.0](https://github.com/OpenRAE/env-packs/compare/v6.1.0...v6.2.0) (2026-10-03)
+
+
+### Features
+
+* add missing infrastructure kits ([#383](https://github.com/OpenRAE/env-packs/issues/383)) ([fc07c71](https://github.com/OpenRAE/env-packs/commit/fc07c71a0ac8c94b45611a9d54da34067536b9cf))
+* add TechVault participant study pack ([#394](https://github.com/OpenRAE/env-packs/issues/394)) ([acf2d47](https://github.com/OpenRAE/env-packs/commit/acf2d47ff3d60a26d7f5dd934c5afeb068a2d1ac))
+
+
+### Bug Fixes
+
+* **deps:** bump coverage from 7.16.0 to 7.16.1 ([#385](https://github.com/OpenRAE/env-packs/issues/385)) ([5a1a50c](https://github.com/OpenRAE/env-packs/commit/5a1a50c310e4f042864bf1bf713a0d849112d50a))
+* **deps:** bump uvicorn from 0.52.4 to 0.53.0 ([#387](https://github.com/OpenRAE/env-packs/issues/387)) ([0198fca](https://github.com/OpenRAE/env-packs/commit/0198fca735917f35fa7485062ad8aab81d58c9e5))
+* update TechVault study for RAES 6.0.1 ([#402](https://github.com/OpenRAE/env-packs/issues/402)) ([e047447](https://github.com/OpenRAE/env-packs/commit/e0474479d4885f75c50a70d444afa1c123446d93))
+
+
+### Documentation
+
+* demonstrate two-audience delivery bundles ([#382](https://github.com/OpenRAE/env-packs/issues/382)) ([443248d](https://github.com/OpenRAE/env-packs/commit/443248d9e236c6b10cc62b01a4f8a87d663ff9eb))
+* evaluate advanced reusable kit families ([#380](https://github.com/OpenRAE/env-packs/issues/380)) ([7fde5a5](https://github.com/OpenRAE/env-packs/commit/7fde5a5769ff63d5fa6b3220e29bfe9a38405b26))
+* **kits:** demonstrate defensive-tooling composition ([#381](https://github.com/OpenRAE/env-packs/issues/381)) ([abfd531](https://github.com/OpenRAE/env-packs/commit/abfd531bb620906a0880f863ebe04c324ced9c55))
+
## [6.1.0](https://github.com/OpenRAE/env-packs/compare/v6.0.1...v6.1.0) (2026-09-16)
diff --git a/docs/development/techvault-suricata-content-preflight.md b/docs/development/techvault-suricata-content-preflight.md
index 3913da9..ae85cde 100644
--- a/docs/development/techvault-suricata-content-preflight.md
+++ b/docs/development/techvault-suricata-content-preflight.md
@@ -52,6 +52,28 @@ The Wazuh `suricata_rules.xml` content is a different layer: it interprets EVE
events after Suricata produces them. It is not a Suricata sensor rule source and
must not be counted, placed, or validated as one.
+That Wazuh layer extends the Wazuh 4.12 built-in Suricata chain; it must not
+compete with it for JSON decoding. Built-in rule `86600` is the event base and
+built-in rule `86601` is the Suricata-alert parent. Alert refinements
+`303001`-`303060`, including web-attack rule `303020`, inherit from `86601`.
+The DNS refinement `303110` inherits from built-in DNS rule `86603`. Wazuh
+4.12 has no built-in flow rule, so the flow refinement `303100` inherits from
+`86600`. Both keep their `event_type` predicates. A refinement parented by
+`86600` for an event type that also has a built-in child loses to that
+sibling and never fires. The pack must not define rule `303000` or any
+other custom `json` parent. Leaving an unused rival
+decoder in the file is not acceptable: decoder selection happens before the
+custom children can repair the chain.
+
+Static author validation should enforce that bounded parent/absence contract
+on the already resolved artifact, while Wazuh remains the authority for XML
+rule syntax and evaluation. A representative Suricata EVE alert must also be
+evaluated by the Wazuh 4.12 native rule-test/runtime path and select `303020` at
+level 10; XML well-formedness, substring presence, rule loading, or a resulting
+generic `86601` alert is not behavioral proof. Preserve the custom rule ids,
+levels, predicates, descriptions, and groups unless a separately reviewed
+content change requires otherwise.
+
The runtime join is one chain, not independent declarations:
`associated artifact -> RAES content source -> content placement -> engine
@@ -67,7 +89,7 @@ allowed to mask missing or changed pack inputs.
## Canonical contracts to reuse
-Pinned `raes==3.3.0` already owns the portable semantic surfaces:
+Pinned `raes==6.0.1` already owns the portable semantic surfaces:
- `RuntimeNetworkDetectionEngine` and its rule sources, network sets, output
streams, file references, evidence references, and control channels are the
@@ -105,6 +127,15 @@ and blank lines from at least one active local rule, but it must not claim to
parse Suricata syntax; exact validity, variable resolution, selected files, and
effective loaded-rule counts require the native engine check.
+The same boundary applies to the Wazuh XML: strengthen the existing TechVault
+artifact check rather than adding a Wazuh schema, validator family, exception
+hierarchy, or a second artifact reader. The check must be structural enough to
+reject rule `303000`, every custom `decoded_as` declaration, and a refinement
+not parented by the built-in rule for its event type.
+Malformed XML produces one stable, bounded pack-contract diagnostic without
+including XML bodies or raw parser exceptions. Native Wazuh testing owns rule
+evaluation and catches semantics that the static parent check cannot prove.
+
Static inspection cannot prove that the selected engine accepts and loads the
configuration. Runtime verification must additionally use Suricata's native
configuration test, start from a clean admitted pack with no old volumes or
@@ -121,6 +152,7 @@ Any intended design crosses all of these layers:
| RAES shape and semantic validation | Parse through pinned RAES and preserve closed shapes, unique ids, absolute file-reference rules, service/source references, and explicit content classifications. RAES currently does not prove every content-placement-to-engine-path or forwarding-to-control-channel join; add narrow TechVault contract assertions without creating a parallel production schema. |
| Pack validation and author CI | Reuse the static validator, anti-extension boundary, participant-facing content leak scan, and deterministic bounded diagnostics. Unexpected defects still raise; invalid authored input remains a `ValidationResult` diagnostic. |
| Artifact identity and filesystem policy | Put static configuration and local rules in associated artifacts and resolve them only through the canonical manifest/resolver path and exact-copy profile. Preserve size budgets and no-follow, containment, canonical-name, file-type, and digest checks. Evidence identifies artifact, pack-set, and realized-byte digests without including file bodies or host paths. |
+| Wazuh rule admission | Resolve the exact XML through `resolve_pack_artifact()`, enforce only the bounded built-in-parent topology in the existing TechVault validator, and use Wazuh 4.12 itself for syntax/evaluation. The rule file is static read-only content; it introduces no auth surface, environment binding, secret, process argument, network listener, or writable state. |
| Secret handling | Rule/config assets contain no credentials. `MISP_API_KEY` remains a value-less `operator_secret`, resolved at the runtime secret boundary; it must not enter pack bytes, argv, logs, engine diagnostics, or evidence. Do not dump the complete environment to prove the sync agent ran. |
| Control-channel authorization | `auth_required: false` is acceptable only for the private Unix socket shared narrowly by the Suricata process and its declared sync agent. Both ends, the path, capability, ownership, permissions, and mount must agree. Never publish the socket to a participant or host-facing interface. |
| OS/container exposure | Keep the fixed configuration path in the existing process invocation and keep rule/config bodies out of argv and shell interpolation. Static content is read-only; only the generated MISP directory, command socket, and logs receive narrowly scoped writes. Account for UID/GID, modes, mount collisions, traversal, `/proc`, and symlink substitution. Do not expand the existing network capabilities to repair content placement. |
@@ -138,6 +170,16 @@ If the sensor cannot observe that declared path, the result is evidence for the
#284 packet-processing gap; it is not permission to copy rules after startup or
weaken the expected detection.
+The base and participant-study packs are separate publishable identities but
+intentionally carry byte-identical content assets. Change both XML copies
+together and preserve the existing cross-pack identity test. Because the XML is
+an exact associated artifact referenced from SDL, its new digest must flow into
+each SDL `exact_artifact`, each external-concept binding must be retargeted by
+the existing SDL-binding refresh tool, and each complete manifest must then be
+derived from the final tree. Do not hand-patch the payload checksum, size, SDL
+checksum, binding digest, or set digest. The existing pack-local validator is
+also duplicated by pack convention and must retain identical rule-chain logic.
+
## Extensibility boundary
The reusable seam is a source-neutral mapping from a declared engine rule
@@ -156,6 +198,14 @@ copy hook. Packet-acquisition/interface selection remains an independently
variable seam owned by #284 and must not be baked into the recovered content
contract.
+For Wazuh correlation, the extension seam is the small data set of custom rule
+families and their built-in parent (`86601` for alerts, `86603` for DNS, and
+`86600` for flow), coupled explicitly to the declared Wazuh 4.12 contract. A new
+custom alert should extend that mapping and its malformed-variant coverage, not
+introduce another decoder parent. A future Wazuh-version change must revalidate
+the built-in ids with the native engine before changing the mapping; the ids are
+not a reason to add runtime templating or a new portable parameter.
+
## Non-goals and rejected shortcuts
- Do not preserve, rename, or tolerate LilRAE's checkout-local copy as a
@@ -169,6 +219,10 @@ contract.
- Do not count Wazuh correlation XML as Suricata rules, or treat EVE file
existence, Wazuh ingestion, or an unrelated alert as proof of the intended
sensor detection.
+- Do not retain `303000`, add any custom JSON decoder parent, chain alert rules
+ directly to `86600`, or accept generic `86601` as proof that `303020` fired.
+- Do not reproduce Wazuh's grammar or matching engine in Python. A static
+ parent-topology check is a regression guard, not a Wazuh evaluator.
- Do not add pack-local RAES semantics, a duplicate Suricata grammar/parser,
another content identity, reload, observation, error, or provenance model, or
downstream catalog/deployment vocabulary.
diff --git a/packs/techvault-participant-study/assets/content/suricata_rules.xml b/packs/techvault-participant-study/assets/content/suricata_rules.xml
index 5691d61..cac20ed 100644
--- a/packs/techvault-participant-study/assets/content/suricata_rules.xml
+++ b/packs/techvault-participant-study/assets/content/suricata_rules.xml
@@ -1,17 +1,17 @@
-
-
- json
- alert
- Suricata IDS alert
- suricata,ids,
-
+
- 303000
+ 86601
^[12]$
Suricata IDS: $(alert.signature)
suricata,ids,
@@ -19,7 +19,7 @@
- 303000
+ 86601
^3$
Suricata IDS (medium): $(alert.signature)
suricata,ids,
@@ -27,7 +27,7 @@
- 303000
+ 86601
^[4-9]$
Suricata IDS (high): $(alert.signature)
suricata,ids,
@@ -35,7 +35,7 @@
- 303000
+ 86601
Attempted Information Leak|attempted-recon
Network reconnaissance: $(alert.signature) from $(src_ip)
suricata,ids,recon,
@@ -43,7 +43,7 @@
- 303000
+ 86601
Web Application Attack|web-application-attack
Web attack (network): $(alert.signature) from $(src_ip)
suricata,ids,web_attack,
@@ -51,7 +51,7 @@
- 303000
+ 86601
Lateral Movement
Lateral movement detected: $(alert.signature)
suricata,ids,lateral_movement,
@@ -59,7 +59,7 @@
- 303000
+ 86601
A Network Trojan was Detected|trojan-activity
C2/Trojan activity: $(alert.signature) from $(src_ip)
suricata,ids,c2,
@@ -67,7 +67,7 @@
- 303000
+ 86601
DNS Tunneling|DNS Exfiltration
DNS tunneling/exfiltration: $(alert.signature)
suricata,ids,exfiltration,dns,
@@ -75,7 +75,7 @@
- 303000
+ 86601
credential-theft
Credential theft detected: $(alert.signature)
suricata,ids,credential_theft,
@@ -83,7 +83,7 @@
- json
+ 86600
flow
Suricata network flow
suricata,flow,
@@ -91,7 +91,7 @@
- json
+ 86603
dns
Suricata DNS event
suricata,dns,
diff --git a/packs/techvault-participant-study/associated-artifacts.json b/packs/techvault-participant-study/associated-artifacts.json
index 69e6ad1..5cd36f7 100644
--- a/packs/techvault-participant-study/associated-artifacts.json
+++ b/packs/techvault-participant-study/associated-artifacts.json
@@ -323,11 +323,11 @@
"uri": "raes-environment-pack:/assets/content/suricata_rules.xml",
"checksum": {
"algorithm": "sha256",
- "value": "b1fdf64371c5ea24f8e1ce47ea2d0aba185f2f6697702c4bb092c2f3d696547c"
+ "value": "438bc86177deb65e8c32be2572e99d03ad46a6e1a36cd634371a9103bb656e49"
},
- "size_bytes": 3442,
- "created_at": "2026-08-04T00:00:00Z",
- "source": "aptl@9320c7af3d03debdd3d1b558af466f8d7262884c",
+ "size_bytes": 3711,
+ "created_at": "2026-10-06T00:00:00Z",
+ "source": "environment-pack-author adapted from aptl@ba418763a87eb250f7631de09afdc5f708cdf451",
"satisfies_refs": [],
"sensitivity": "internal",
"description": null
@@ -515,9 +515,9 @@
"uri": "raes-environment-pack:/docs/lineage.md",
"checksum": {
"algorithm": "sha256",
- "value": "c2ae17a949ec3b75b000d087d6741dcc7ac8243c93453721b91b368ede620051"
+ "value": "5d59244358edb5376d819140119b7ae68e81b9b7ed8bcf22782b935d7a7bdeb1"
},
- "size_bytes": 2847,
+ "size_bytes": 3409,
"created_at": "2026-08-02T00:00:00Z",
"source": "environment-pack-author",
"satisfies_refs": [],
@@ -595,7 +595,7 @@
"uri": "raes-environment-pack:/sdl/techvault-participant-study.bindings.json",
"checksum": {
"algorithm": "sha256",
- "value": "7c4c678ebe41cedfb06d9cf879bc8db7886229a54e8f699f0310045b2bddd854"
+ "value": "71906925489fe25ed791ff47540fd5dacf5d01be117fcd31e8806c1648dbec78"
},
"size_bytes": 44611,
"created_at": "2026-09-13T00:00:00Z",
@@ -627,7 +627,7 @@
"uri": "raes-environment-pack:/sdl/techvault-participant-study.sdl.yaml",
"checksum": {
"algorithm": "sha256",
- "value": "bacbfb918bff2fab5bc730bce2ac1668fbc409e007dd84f17d47496d23cb73e0"
+ "value": "b35a6a48b9d03abd8a12fcfefdcbe04ea8c95d9a0e0c3f9c679bf01f5ce5938d"
},
"size_bytes": 166927,
"created_at": "2026-08-02T00:00:00Z",
@@ -659,9 +659,9 @@
"uri": "raes-environment-pack:/validation/validate_techvault.py",
"checksum": {
"algorithm": "sha256",
- "value": "8bf93d838fe0714ad195f638075ba9c291cd6ef1f64ca72ada0b3d1e72e7e96c"
+ "value": "26d40ec4bab6b574c371fd32c8763bcd1c3100761c73b5ac559780426cf07fbf"
},
- "size_bytes": 65339,
+ "size_bytes": 67181,
"created_at": "2026-08-02T00:00:00Z",
"source": "environment-pack-author",
"satisfies_refs": [],
@@ -733,5 +733,5 @@
"description": "Exact defensive stdio MCP source packages for the SOC workstation."
}
},
- "set_digest": "sha256:fdde7b1a8b9377f7ddd473417de1f3fd3e24549e4560d8d6392f1727b3af5357"
+ "set_digest": "sha256:03baae367b452527be4affd7f29369bf5aa32a2a3c1c82f73bfbc759d642af14"
}
diff --git a/packs/techvault-participant-study/docs/lineage.md b/packs/techvault-participant-study/docs/lineage.md
index be8f043..91bdd64 100644
--- a/packs/techvault-participant-study/docs/lineage.md
+++ b/packs/techvault-participant-study/docs/lineage.md
@@ -22,6 +22,15 @@ zero-indicator MISP rule file and three hash-list sidecars are also copied from
the pinned source, then become mutable runtime state under the declared sync
agent.
+The Wazuh Suricata correlation rules carry the rule-chain repair from APTL
+commit `ba418763a87eb250f7631de09afdc5f708cdf451`. The migrated file declared a
+rival `decoded_as` JSON parent, `303000`, that never won against the Wazuh
+built-in parent, so web-attack rule `303020` never fired. Each custom rule now
+chains off the built-in rule for its event type: `86601` for alerts, `86603`
+for DNS, and `86600` for flow. Unlike that commit, the pack removes `303000`
+and chains DNS off `86603`, so that no level-0 rule hides an alert or shadows
+the DNS refinement.
+
Directory-valued sources were captured as deterministic uncompressed tar
artifacts. Generated SSH keys and SOC certificates were deliberately not copied
from runtime state: RAES generated-artifact declarations retain that lifecycle
diff --git a/packs/techvault-participant-study/sdl/techvault-participant-study.bindings.json b/packs/techvault-participant-study/sdl/techvault-participant-study.bindings.json
index 6ce0264..79ac48d 100644
--- a/packs/techvault-participant-study/sdl/techvault-participant-study.bindings.json
+++ b/packs/techvault-participant-study/sdl/techvault-participant-study.bindings.json
@@ -10,7 +10,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.ping-tool",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -87,7 +87,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.debug",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -164,7 +164,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.debug",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -241,7 +241,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.api-token",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -318,7 +318,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.api-file",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -395,7 +395,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.api-user",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -472,7 +472,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.admin",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -549,7 +549,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.login",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -626,7 +626,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.search",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -703,7 +703,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.upload",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -780,7 +780,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.login",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -857,7 +857,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.api-token",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -934,7 +934,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.search",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -1011,7 +1011,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.comment",
- "artifact_digest": "sha256:4fbffb486f2c9500c4ebe8b3f82da334a52d493f6a147dc43a1c6f12febbfb7e"
+ "artifact_digest": "sha256:ba66f4851bfd6b9db20e10eac7fb52911d9246561d64f7c7c7ef2509ff5d7027"
},
"scheme": {
"scheme_id": "mitre-cwe",
diff --git a/packs/techvault-participant-study/sdl/techvault-participant-study.sdl.yaml b/packs/techvault-participant-study/sdl/techvault-participant-study.sdl.yaml
index 8f8925d..d21f55d 100644
--- a/packs/techvault-participant-study/sdl/techvault-participant-study.sdl.yaml
+++ b/packs/techvault-participant-study/sdl/techvault-participant-study.sdl.yaml
@@ -2505,7 +2505,7 @@ content:
exact_artifact:
artifact_id: techvault-wazuh-suricata-rules
version: 0.1.1
- digest: sha256:b1fdf64371c5ea24f8e1ce47ea2d0aba185f2f6697702c4bb092c2f3d696547c
+ digest: sha256:438bc86177deb65e8c32be2572e99d03ad46a6e1a36cd634371a9103bb656e49
media_type: application/xml
permitted_routes:
- mechanism: *wazuh-content-copy
diff --git a/packs/techvault-participant-study/validation/validate_techvault.py b/packs/techvault-participant-study/validation/validate_techvault.py
index 92a9e02..29ddab3 100644
--- a/packs/techvault-participant-study/validation/validate_techvault.py
+++ b/packs/techvault-participant-study/validation/validate_techvault.py
@@ -10,6 +10,7 @@
import sys
from collections.abc import Mapping
from typing import Any
+from xml.etree import ElementTree
import yaml
@@ -92,6 +93,16 @@
"nodes.wazuh-manager.runtime.security_monitoring_managers.wazuh-manager."
"content_sets.suricata-rules"
)
+# Each custom Wazuh Suricata refinement and the Wazuh 4.12 built-in rule it
+# chains off: 86601 (alert), 86603 (DNS), or 86600 (base, no built-in flow rule).
+_WAZUH_SURICATA_RULE_PARENTS = {
+ **dict.fromkeys(
+ ("303001", "303002", "303003", "303010", "303020", "303030", "303040", "303050", "303060"),
+ ("86601",),
+ ),
+ "303100": ("86600",),
+ "303110": ("86603",),
+}
_VARIABLE_REF = re.compile(r"\$([A-Z][A-Z0-9_]*)")
_SID = re.compile(r"(?:^|;)\s*sid\s*:\s*(\d+)\s*;")
_BUILD_MECHANISM = "materialization-specification"
@@ -590,7 +601,47 @@ def _validate_evidence_contract(
except (PackDigestError, OSError, ValueError):
wazuh_rules = b""
wazuh_rules = overrides.get("techvault-wazuh-suricata-rules", wazuh_rules)
- if b' None:
+ """Check the custom rule parents, not Wazuh rule evaluation.
+
+ A custom ``decoded_as`` parent competes with the built-in Suricata parent
+ and never wins, so its children never fire.
+ """
+
+ if b"" + data + b"")
+ except ElementTree.ParseError:
+ _error(errors, "detection-path-mismatch", "Wazuh rule XML")
+ return
+ rules = list(root.iter("rule"))
+ parents = {
+ rule.get("id"): tuple(
+ sid.strip()
+ for if_sid in rule.findall("if_sid")
+ for sid in (if_sid.text or "").split(",")
+ )
+ for rule in rules
+ }
+ if (
+ len(parents) != len(rules)
+ or parents != _WAZUH_SURICATA_RULE_PARENTS
+ or any(rule.find("decoded_as") is not None for rule in rules)
+ ):
+ _error(errors, "detection-path-mismatch", "Wazuh rule chain")
+ web_attack = next((rule for rule in rules if rule.get("id") == "303020"), None)
+ categories = (
+ ""
+ if web_attack is None
+ else str(web_attack.findtext("field[@name='alert.category']", ""))
+ )
+ if "web-application-attack" not in categories.split("|"):
_error(errors, "detection-path-mismatch", "Wazuh rule 303020")
diff --git a/packs/techvault/assets/content/suricata_rules.xml b/packs/techvault/assets/content/suricata_rules.xml
index 5691d61..cac20ed 100644
--- a/packs/techvault/assets/content/suricata_rules.xml
+++ b/packs/techvault/assets/content/suricata_rules.xml
@@ -1,17 +1,17 @@
-
-
- json
- alert
- Suricata IDS alert
- suricata,ids,
-
+
- 303000
+ 86601
^[12]$
Suricata IDS: $(alert.signature)
suricata,ids,
@@ -19,7 +19,7 @@
- 303000
+ 86601
^3$
Suricata IDS (medium): $(alert.signature)
suricata,ids,
@@ -27,7 +27,7 @@
- 303000
+ 86601
^[4-9]$
Suricata IDS (high): $(alert.signature)
suricata,ids,
@@ -35,7 +35,7 @@
- 303000
+ 86601
Attempted Information Leak|attempted-recon
Network reconnaissance: $(alert.signature) from $(src_ip)
suricata,ids,recon,
@@ -43,7 +43,7 @@
- 303000
+ 86601
Web Application Attack|web-application-attack
Web attack (network): $(alert.signature) from $(src_ip)
suricata,ids,web_attack,
@@ -51,7 +51,7 @@
- 303000
+ 86601
Lateral Movement
Lateral movement detected: $(alert.signature)
suricata,ids,lateral_movement,
@@ -59,7 +59,7 @@
- 303000
+ 86601
A Network Trojan was Detected|trojan-activity
C2/Trojan activity: $(alert.signature) from $(src_ip)
suricata,ids,c2,
@@ -67,7 +67,7 @@
- 303000
+ 86601
DNS Tunneling|DNS Exfiltration
DNS tunneling/exfiltration: $(alert.signature)
suricata,ids,exfiltration,dns,
@@ -75,7 +75,7 @@
- 303000
+ 86601
credential-theft
Credential theft detected: $(alert.signature)
suricata,ids,credential_theft,
@@ -83,7 +83,7 @@
- json
+ 86600
flow
Suricata network flow
suricata,flow,
@@ -91,7 +91,7 @@
- json
+ 86603
dns
Suricata DNS event
suricata,dns,
diff --git a/packs/techvault/associated-artifacts.json b/packs/techvault/associated-artifacts.json
index 36284ae..41b60e8 100644
--- a/packs/techvault/associated-artifacts.json
+++ b/packs/techvault/associated-artifacts.json
@@ -323,11 +323,11 @@
"uri": "raes-environment-pack:/assets/content/suricata_rules.xml",
"checksum": {
"algorithm": "sha256",
- "value": "b1fdf64371c5ea24f8e1ce47ea2d0aba185f2f6697702c4bb092c2f3d696547c"
+ "value": "438bc86177deb65e8c32be2572e99d03ad46a6e1a36cd634371a9103bb656e49"
},
- "size_bytes": 3442,
- "created_at": "2026-08-04T00:00:00Z",
- "source": "aptl@9320c7af3d03debdd3d1b558af466f8d7262884c",
+ "size_bytes": 3711,
+ "created_at": "2026-10-06T00:00:00Z",
+ "source": "environment-pack-author adapted from aptl@ba418763a87eb250f7631de09afdc5f708cdf451",
"satisfies_refs": [],
"sensitivity": "internal",
"description": null
@@ -515,9 +515,9 @@
"uri": "raes-environment-pack:/docs/lineage.md",
"checksum": {
"algorithm": "sha256",
- "value": "0571973983982a7f97a7c1acbafda23833139d3d24d18a8c5691b8dd53ac64d1"
+ "value": "6fa6c0b34c17ca0ee1f97ffce08acbfb359e8d699dba61c6230044c1c956be75"
},
- "size_bytes": 2348,
+ "size_bytes": 2910,
"created_at": "2026-08-02T00:00:00Z",
"source": "environment-pack-author",
"satisfies_refs": [],
@@ -595,7 +595,7 @@
"uri": "raes-environment-pack:/sdl/techvault.bindings.json",
"checksum": {
"algorithm": "sha256",
- "value": "007b85f63ec0b1e2904942fcbc2bb0f94648f68e7e460561ac047ccbec95eda4"
+ "value": "5a2993423c919ce80e975eb0b30f73fe8dda5ba84929d2905201dbe632e3884f"
},
"size_bytes": 44611,
"created_at": "2026-09-13T00:00:00Z",
@@ -627,7 +627,7 @@
"uri": "raes-environment-pack:/sdl/techvault.sdl.yaml",
"checksum": {
"algorithm": "sha256",
- "value": "e9ba7711835219a46a1886fe7b52f56a32e80b9b0a255401f218d1732dd9ef5f"
+ "value": "5fdf94d823e221e932ffd2fdf03353c8586941b108cb098d8dbfc17d60030813"
},
"size_bytes": 141602,
"created_at": "2026-08-02T00:00:00Z",
@@ -659,9 +659,9 @@
"uri": "raes-environment-pack:/validation/validate_techvault.py",
"checksum": {
"algorithm": "sha256",
- "value": "8bf93d838fe0714ad195f638075ba9c291cd6ef1f64ca72ada0b3d1e72e7e96c"
+ "value": "26d40ec4bab6b574c371fd32c8763bcd1c3100761c73b5ac559780426cf07fbf"
},
- "size_bytes": 65339,
+ "size_bytes": 67181,
"created_at": "2026-08-02T00:00:00Z",
"source": "environment-pack-author",
"satisfies_refs": [],
@@ -733,5 +733,5 @@
"description": "Exact defensive stdio MCP source packages for the SOC workstation."
}
},
- "set_digest": "sha256:df00ea2a2672864ad8c711a3eab3a8a7bffff4db058b4a9acde032a61b2a1504"
+ "set_digest": "sha256:1229f94f31bd35d3997d47ef8316ffebb3d2d2919c995838e458420b70456fcf"
}
diff --git a/packs/techvault/docs/lineage.md b/packs/techvault/docs/lineage.md
index 8c91cfa..4e10087 100644
--- a/packs/techvault/docs/lineage.md
+++ b/packs/techvault/docs/lineage.md
@@ -14,6 +14,15 @@ zero-indicator MISP rule file and three hash-list sidecars are also copied from
the pinned source, then become mutable runtime state under the declared sync
agent.
+The Wazuh Suricata correlation rules carry the rule-chain repair from APTL
+commit `ba418763a87eb250f7631de09afdc5f708cdf451`. The migrated file declared a
+rival `decoded_as` JSON parent, `303000`, that never won against the Wazuh
+built-in parent, so web-attack rule `303020` never fired. Each custom rule now
+chains off the built-in rule for its event type: `86601` for alerts, `86603`
+for DNS, and `86600` for flow. Unlike that commit, the pack removes `303000`
+and chains DNS off `86603`, so that no level-0 rule hides an alert or shadows
+the DNS refinement.
+
Directory-valued sources were captured as deterministic uncompressed tar
artifacts. Generated SSH keys and SOC certificates were deliberately not copied
from runtime state: RAES generated-artifact declarations retain that lifecycle
diff --git a/packs/techvault/sdl/techvault.bindings.json b/packs/techvault/sdl/techvault.bindings.json
index 1c189f7..608f89d 100644
--- a/packs/techvault/sdl/techvault.bindings.json
+++ b/packs/techvault/sdl/techvault.bindings.json
@@ -10,7 +10,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.ping-tool",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -87,7 +87,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.debug",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -164,7 +164,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.debug",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -241,7 +241,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.api-token",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -318,7 +318,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.api-file",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -395,7 +395,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.api-user",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -472,7 +472,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.admin",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -549,7 +549,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.login",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -626,7 +626,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.search",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -703,7 +703,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.upload",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -780,7 +780,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.login",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -857,7 +857,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.api-token",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -934,7 +934,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.search",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
@@ -1011,7 +1011,7 @@
"owning_contract_id": "sdl-authoring-input-v1",
"lifecycle_phase": "normalized-authoring",
"canonical_ref": "nodes.webapp.runtime.applications.techvault-portal.routes.comment",
- "artifact_digest": "sha256:b705580d343537c7bf3c7ef76ec4b2b1f8b832984b4b8b16106ea8ee536e955d"
+ "artifact_digest": "sha256:32662db3e3235bbd1354b671783b0b262593ab54a27b06c248700c15f3d1a33c"
},
"scheme": {
"scheme_id": "mitre-cwe",
diff --git a/packs/techvault/sdl/techvault.sdl.yaml b/packs/techvault/sdl/techvault.sdl.yaml
index 6200e6a..95d6d22 100644
--- a/packs/techvault/sdl/techvault.sdl.yaml
+++ b/packs/techvault/sdl/techvault.sdl.yaml
@@ -2505,7 +2505,7 @@ content:
exact_artifact:
artifact_id: techvault-wazuh-suricata-rules
version: 0.1.1
- digest: sha256:b1fdf64371c5ea24f8e1ce47ea2d0aba185f2f6697702c4bb092c2f3d696547c
+ digest: sha256:438bc86177deb65e8c32be2572e99d03ad46a6e1a36cd634371a9103bb656e49
media_type: application/xml
permitted_routes:
- mechanism: *wazuh-content-copy
diff --git a/packs/techvault/validation/validate_techvault.py b/packs/techvault/validation/validate_techvault.py
index 92a9e02..29ddab3 100644
--- a/packs/techvault/validation/validate_techvault.py
+++ b/packs/techvault/validation/validate_techvault.py
@@ -10,6 +10,7 @@
import sys
from collections.abc import Mapping
from typing import Any
+from xml.etree import ElementTree
import yaml
@@ -92,6 +93,16 @@
"nodes.wazuh-manager.runtime.security_monitoring_managers.wazuh-manager."
"content_sets.suricata-rules"
)
+# Each custom Wazuh Suricata refinement and the Wazuh 4.12 built-in rule it
+# chains off: 86601 (alert), 86603 (DNS), or 86600 (base, no built-in flow rule).
+_WAZUH_SURICATA_RULE_PARENTS = {
+ **dict.fromkeys(
+ ("303001", "303002", "303003", "303010", "303020", "303030", "303040", "303050", "303060"),
+ ("86601",),
+ ),
+ "303100": ("86600",),
+ "303110": ("86603",),
+}
_VARIABLE_REF = re.compile(r"\$([A-Z][A-Z0-9_]*)")
_SID = re.compile(r"(?:^|;)\s*sid\s*:\s*(\d+)\s*;")
_BUILD_MECHANISM = "materialization-specification"
@@ -590,7 +601,47 @@ def _validate_evidence_contract(
except (PackDigestError, OSError, ValueError):
wazuh_rules = b""
wazuh_rules = overrides.get("techvault-wazuh-suricata-rules", wazuh_rules)
- if b' None:
+ """Check the custom rule parents, not Wazuh rule evaluation.
+
+ A custom ``decoded_as`` parent competes with the built-in Suricata parent
+ and never wins, so its children never fire.
+ """
+
+ if b"" + data + b"")
+ except ElementTree.ParseError:
+ _error(errors, "detection-path-mismatch", "Wazuh rule XML")
+ return
+ rules = list(root.iter("rule"))
+ parents = {
+ rule.get("id"): tuple(
+ sid.strip()
+ for if_sid in rule.findall("if_sid")
+ for sid in (if_sid.text or "").split(",")
+ )
+ for rule in rules
+ }
+ if (
+ len(parents) != len(rules)
+ or parents != _WAZUH_SURICATA_RULE_PARENTS
+ or any(rule.find("decoded_as") is not None for rule in rules)
+ ):
+ _error(errors, "detection-path-mismatch", "Wazuh rule chain")
+ web_attack = next((rule for rule in rules if rule.get("id") == "303020"), None)
+ categories = (
+ ""
+ if web_attack is None
+ else str(web_attack.findtext("field[@name='alert.category']", ""))
+ )
+ if "web-application-attack" not in categories.split("|"):
_error(errors, "detection-path-mismatch", "Wazuh rule 303020")
diff --git a/pyproject.toml b/pyproject.toml
index 19d6c86..20ef555 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
[project]
name = "raes-env-packs"
# Static version, bumped by release-please on release (ADR 0008).
-version = "6.1.0"
+version = "6.2.0"
description = "RAES environment-pack definition, schemas, template, and authoring/validation tooling."
readme = "README.md"
# Floor follows the pinned raes runtime dependency, which requires >=3.11
diff --git a/tests/test_techvault_pack.py b/tests/test_techvault_pack.py
index 4ebf10d..cd7aef6 100644
--- a/tests/test_techvault_pack.py
+++ b/tests/test_techvault_pack.py
@@ -1129,6 +1129,9 @@ def replace_artifact(artifact_id, before, after):
def replace_local(before: bytes, after: bytes):
return replace_artifact(local_artifact, before, after)
+ def replace_wazuh(before: bytes, after: bytes):
+ return replace_artifact(wazuh_artifact, before, after)
+
def null_rule_files(sdl, assets):
config = yaml.safe_load(assets[config_artifact].decode("utf-8"))
config["rule-files"] = None
@@ -1500,6 +1503,71 @@ def null_rule_files(sdl, assets):
lambda sdl, assets: assets.update({wazuh_artifact: b""}),
"suricata.detection-path-mismatch: Wazuh rule 303020",
),
+ "Wazuh web-attack category mismatch": (
+ replace_wazuh(
+ b"Web Application Attack|web-application-attack",
+ b"Web Application Attack",
+ ),
+ "suricata.detection-path-mismatch: Wazuh rule 303020",
+ ),
+ "Wazuh rival decoded_as parent": (
+ replace_wazuh(
+ b'\n 86601',
+ b'\n'
+ b" json\n"
+ b' alert\n'
+ b" Suricata IDS alert\n"
+ b" \n"
+ b' \n 303000',
+ ),
+ "suricata.detection-path-mismatch: Wazuh rule chain",
+ ),
+ "Wazuh custom decoded_as declaration": (
+ replace_wazuh(
+ b'\n 86601',
+ b'\n 86601\n'
+ b" json",
+ ),
+ "suricata.detection-path-mismatch: Wazuh rule chain",
+ ),
+ "Wazuh alert refinement off the base rule": (
+ replace_wazuh(
+ b'\n 86601',
+ b'\n 86600',
+ ),
+ "suricata.detection-path-mismatch: Wazuh rule chain",
+ ),
+ "Wazuh DNS refinement off the base rule": (
+ replace_wazuh(
+ b'\n 86603',
+ b'\n 86600',
+ ),
+ "suricata.detection-path-mismatch: Wazuh rule chain",
+ ),
+ "Wazuh flow refinement off the alert rule": (
+ replace_wazuh(
+ b'\n 86600',
+ b'\n 86601',
+ ),
+ "suricata.detection-path-mismatch: Wazuh rule chain",
+ ),
+ "Wazuh duplicate rule id": (
+ replace_wazuh(b']>\n'
+ + assets[wazuh_artifact]
+ }
+ ),
+ "suricata.detection-path-mismatch: Wazuh rule XML",
+ ),
}
artifact_ids = (