You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The content-manager plugin stores ruleset resources (decoders, KVDBs, and filters) as JSON documents in their respective OpenSearch indices. When the Wazuh Dashboard reads these documents and renders them for editing, it serializes the document field back into YAML for display. Conversely, when a user saves a resource via the Dashboard, the content is sent to the plugin REST API as JSON.
This round-trip introduces a type-fidelity problem rooted in how JavaScript handles numeric values: any floating-point number whose fractional part is zero is coerced to an integer at runtime. For example, 5.0 becomes 5. Although the numeric value is unchanged, the Engine treats float and int as distinct types and rejects the payload with a type-mismatch validation error.
The fix has two sides:
Indexer → Dashboard (read path): The plugin must store a top-level yaml field alongside document for decoders, KVDBs, and filters. Storing YAML directly avoids JSON parsing by the Dashboard and preserves the original numeric types as authored. Decoder resources already have an equivalent field named decoder; this issue renames it to yaml and extends the same pattern to KVDBs and filters.
Dashboard → Indexer (write path): The plugin REST API must accept Content-Type: application/yaml request bodies for create and update operations on decoders, KVDBs, and filters. Accepting YAML on ingress prevents the Dashboard from ever serializing the content as JSON and losing type precision before it reaches the Engine.
Functional requirements
Decoder, KVDB, and filter resources must each expose a top-level yaml field containing the YAML representation of their document content.
The yaml field must be stored at the same level as document, hash, space, and offset in the indexed document.
The yaml field must be populated on every create and update operation, including those triggered by the CTI sync pipeline.
The index mappings for wazuh-threatintel-decoders, wazuh-threatintel-kvdbs, and wazuh-threatintel-filters must be updated to add a top-level yaml field. The existing decoder field in wazuh-threatintel-decoders must be removed.
The Decoder Java model must be updated to rename the decoder field to yaml. The KVDB and filter Java models must be updated to add a yaml field.
The REST API create (POST) and update (PUT) endpoints for decoders, KVDBs, and filters must accept Content-Type: application/yaml request bodies.
When a YAML body is received, the plugin must parse it into the resource model and store the original YAML string verbatim in the yaml field, without converting it through JSON. The JSON representaton of the resource must be generated from the parsed YAML content and stored in the document field.
When a JSON body is received, the plugin must generate the yaml field by serializing the parsed document content to YAML before indexing.
The OpenAPI specification must be updated to document the yaml field in the response schemas and the application/yaml content type in the request bodies for the affected endpoints.
All existing unit and integration tests must be updated to replace references to decoder with yaml and to cover the new yaml field for KVDBs and filters.
New unit tests must verify YAML round-trip fidelity for numeric types, specifically that 5.0 is preserved as a float and not coerced to 5.
Implementation restrictions
The YAML serialization logic in the Decoder model must be extracted into a shared utility (e.g., YamlUtils) so that decoders, KVDBs, and filters reuse it without duplication.
The yaml field must be stored at the top level of the indexed document; it must not be nested inside document.
Do not modify the document, hash, space, or offset top-level fields.
YAML support for policies, integrations, and rules is out of scope unless extracting the shared utility requires changes to their base class.
Plan
Update wazuh-threatintel-decoders mapping: rename the decoder field to yaml.
Update wazuh-threatintel-kvdbs and wazuh-threatintel-filters mappings: add a top-level yaml field with the same field type as yaml in wazuh-threatintel-decoders.
Extract the YAML serialization logic from Decoder into a shared utility class (e.g., YamlUtils).
Update the Decoder Java model: rename the decoder field and its @JsonProperty annotation to yaml; replace the inline YAML generation with a call to YamlUtils.
Update the KVDB and filter Java models to add a yaml field with the appropriate @JsonProperty annotation and populate it via YamlUtils.
Update the KVDB and filter REST POST and PUT handlers to negotiate Content-Type: application/yaml and parse incoming YAML bodies without routing through JSON.
Update the decoder, KVDB, and filter REST POST and PUT handlers to populate the yaml field from the parsed document when the request body is JSON.
Update FixtureFactory and all test fixtures for decoders, KVDBs, and filters to use the yaml field.
Add unit tests for YAML round-trip fidelity (float 5.0 preserved, not coerced to 5) for all three resource types.
Update integration tests (DecoderCUDIT, FilterCUDIT, KvdbCUDIT) to exercise both application/json and application/yaml request bodies and assert the yaml field in responses.
Update the OpenAPI specification (openapi.yml) to replace decoder with yaml in decoder response schemas, add yaml to KVDB and filter response schemas, and add application/yaml to the request body definitions for all affected endpoints.
Description
The content-manager plugin stores ruleset resources (decoders, KVDBs, and filters) as JSON documents in their respective OpenSearch indices. When the Wazuh Dashboard reads these documents and renders them for editing, it serializes the
documentfield back into YAML for display. Conversely, when a user saves a resource via the Dashboard, the content is sent to the plugin REST API as JSON.This round-trip introduces a type-fidelity problem rooted in how JavaScript handles numeric values: any floating-point number whose fractional part is zero is coerced to an integer at runtime. For example,
5.0becomes5. Although the numeric value is unchanged, the Engine treatsfloatandintas distinct types and rejects the payload with a type-mismatch validation error.The fix has two sides:
Indexer → Dashboard (read path): The plugin must store a top-level
yamlfield alongsidedocumentfor decoders, KVDBs, and filters. Storing YAML directly avoids JSON parsing by the Dashboard and preserves the original numeric types as authored. Decoder resources already have an equivalent field nameddecoder; this issue renames it toyamland extends the same pattern to KVDBs and filters.Dashboard → Indexer (write path): The plugin REST API must accept
Content-Type: application/yamlrequest bodies for create and update operations on decoders, KVDBs, and filters. Accepting YAML on ingress prevents the Dashboard from ever serializing the content as JSON and losing type precision before it reaches the Engine.Functional requirements
yamlfield containing the YAML representation of theirdocumentcontent.yamlfield must be stored at the same level asdocument,hash,space, andoffsetin the indexed document.yamlfield must be populated on every create and update operation, including those triggered by the CTI sync pipeline.wazuh-threatintel-decoders,wazuh-threatintel-kvdbs, andwazuh-threatintel-filtersmust be updated to add a top-levelyamlfield. The existingdecoderfield inwazuh-threatintel-decodersmust be removed.DecoderJava model must be updated to rename thedecoderfield toyaml. The KVDB and filter Java models must be updated to add ayamlfield.POST) and update (PUT) endpoints for decoders, KVDBs, and filters must acceptContent-Type: application/yamlrequest bodies.yamlfield, without converting it through JSON. The JSON representaton of the resource must be generated from the parsed YAML content and stored in thedocumentfield.yamlfield by serializing the parseddocumentcontent to YAML before indexing.yamlfield in the response schemas and theapplication/yamlcontent type in the request bodies for the affected endpoints.decoderwithyamland to cover the newyamlfield for KVDBs and filters.5.0is preserved as a float and not coerced to5.Implementation restrictions
Decodermodel must be extracted into a shared utility (e.g.,YamlUtils) so that decoders, KVDBs, and filters reuse it without duplication.yamlfield must be stored at the top level of the indexed document; it must not be nested insidedocument.document,hash,space, oroffsettop-level fields.Plan
wazuh-threatintel-decodersmapping: rename thedecoderfield toyaml.wazuh-threatintel-kvdbsandwazuh-threatintel-filtersmappings: add a top-levelyamlfield with the same field type asyamlinwazuh-threatintel-decoders.Decoderinto a shared utility class (e.g.,YamlUtils).DecoderJava model: rename thedecoderfield and its@JsonPropertyannotation toyaml; replace the inline YAML generation with a call toYamlUtils.yamlfield with the appropriate@JsonPropertyannotation and populate it viaYamlUtils.Content-Type: application/yamland parse incoming YAML bodies without routing through JSON.yamlfield from the parsed document when the request body is JSON.FixtureFactoryand all test fixtures for decoders, KVDBs, and filters to use theyamlfield.5.0preserved, not coerced to5) for all three resource types.DecoderCUDIT,FilterCUDIT,KvdbCUDIT) to exercise bothapplication/jsonandapplication/yamlrequest bodies and assert theyamlfield in responses.openapi.yml) to replacedecoderwithyamlin decoder response schemas, addyamlto KVDB and filter response schemas, and addapplication/yamlto the request body definitions for all affected endpoints.