Skip to content
Merged

Dev #419

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "6.1.0"
".": "6.2.0"
}
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,28 @@ this file at release-prep. See [`changelog.d/README.md`](changelog.d/README.md).

<!-- towncrier release notes start -->

## [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)


Expand Down
56 changes: 55 additions & 1 deletion docs/development/techvault-suricata-content-preflight.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<decoded_as>json</decoded_as>` 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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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. |
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,97 +1,97 @@
<!-- Suricata IDS Integration Rules for APTL Lab -->
<group name="aptl,suricata,ids,">

<!-- Base Suricata alert decoder -->
<rule id="303000" level="0">
<decoded_as>json</decoded_as>
<field name="event_type">alert</field>
<description>Suricata IDS alert</description>
<group>suricata,ids,</group>
</rule>
<!-- These rules refine the Wazuh built-in Suricata chain
(ruleset/rules/0475-suricata_rules.xml). They must not declare their own
<decoded_as>json</decoded_as> parent. Wazuh binds each JSON event to one
decoded_as parent and the built-in 86600 loads first, so a rival parent
never wins and its children never fire. Each refinement chains off the
built-in rule for its event type: alerts off 86601 and DNS off 86603.
Flow has no built-in rule, so flow chains off the base rule 86600. -->

<!-- Suricata low severity (1-2) -->
<rule id="303001" level="3">
<if_sid>303000</if_sid>
<if_sid>86601</if_sid>
<field name="alert.severity">^[12]$</field>
<description>Suricata IDS: $(alert.signature)</description>
<group>suricata,ids,</group>
</rule>

<!-- Suricata medium severity (3) -->
<rule id="303002" level="6">
<if_sid>303000</if_sid>
<if_sid>86601</if_sid>
<field name="alert.severity">^3$</field>
<description>Suricata IDS (medium): $(alert.signature)</description>
<group>suricata,ids,</group>
</rule>

<!-- Suricata high severity (4+) -->
<rule id="303003" level="10">
<if_sid>303000</if_sid>
<if_sid>86601</if_sid>
<field name="alert.severity">^[4-9]$</field>
<description>Suricata IDS (high): $(alert.signature)</description>
<group>suricata,ids,</group>
</rule>

<!-- Network scan detected -->
<rule id="303010" level="6">
<if_sid>303000</if_sid>
<if_sid>86601</if_sid>
<field name="alert.category">Attempted Information Leak|attempted-recon</field>
<description>Network reconnaissance: $(alert.signature) from $(src_ip)</description>
<group>suricata,ids,recon,</group>
</rule>

<!-- Web attack detected by Suricata -->
<rule id="303020" level="10">
<if_sid>303000</if_sid>
<if_sid>86601</if_sid>
<field name="alert.category">Web Application Attack|web-application-attack</field>
<description>Web attack (network): $(alert.signature) from $(src_ip)</description>
<group>suricata,ids,web_attack,</group>
</rule>

<!-- Lateral movement detected -->
<rule id="303030" level="10">
<if_sid>303000</if_sid>
<if_sid>86601</if_sid>
<field name="alert.signature">Lateral Movement</field>
<description>Lateral movement detected: $(alert.signature)</description>
<group>suricata,ids,lateral_movement,</group>
</rule>

<!-- C2 / Trojan activity -->
<rule id="303040" level="12">
<if_sid>303000</if_sid>
<if_sid>86601</if_sid>
<field name="alert.category">A Network Trojan was Detected|trojan-activity</field>
<description>C2/Trojan activity: $(alert.signature) from $(src_ip)</description>
<group>suricata,ids,c2,</group>
</rule>

<!-- DNS tunneling -->
<rule id="303050" level="10">
<if_sid>303000</if_sid>
<if_sid>86601</if_sid>
<field name="alert.signature">DNS Tunneling|DNS Exfiltration</field>
<description>DNS tunneling/exfiltration: $(alert.signature)</description>
<group>suricata,ids,exfiltration,dns,</group>
</rule>

<!-- Credential theft -->
<rule id="303060" level="12">
<if_sid>303000</if_sid>
<if_sid>86601</if_sid>
<field name="alert.category">credential-theft</field>
<description>Credential theft detected: $(alert.signature)</description>
<group>suricata,ids,credential_theft,</group>
</rule>

<!-- Suricata flow events (for network monitoring) -->
<rule id="303100" level="0">
<decoded_as>json</decoded_as>
<if_sid>86600</if_sid>
<field name="event_type">flow</field>
<description>Suricata network flow</description>
<group>suricata,flow,</group>
</rule>

<!-- Suricata DNS events -->
<rule id="303110" level="0">
<decoded_as>json</decoded_as>
<if_sid>86603</if_sid>
<field name="event_type">dns</field>
<description>Suricata DNS event</description>
<group>suricata,dns,</group>
Expand Down
22 changes: 11 additions & 11 deletions packs/techvault-participant-study/associated-artifacts.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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": [],
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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": [],
Expand Down Expand Up @@ -733,5 +733,5 @@
"description": "Exact defensive stdio MCP source packages for the SOC workstation."
}
},
"set_digest": "sha256:fdde7b1a8b9377f7ddd473417de1f3fd3e24549e4560d8d6392f1727b3af5357"
"set_digest": "sha256:03baae367b452527be4affd7f29369bf5aa32a2a3c1c82f73bfbc759d642af14"
}
9 changes: 9 additions & 0 deletions packs/techvault-participant-study/docs/lineage.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading
Loading