Skip to content

[K9VULN-11259] Implement Config V2#809

Merged
jasonforal merged 13 commits intomainfrom
jf/K9VULN-11259
Feb 17, 2026
Merged

[K9VULN-11259] Implement Config V2#809
jasonforal merged 13 commits intomainfrom
jf/K9VULN-11259

Conversation

@jasonforal
Copy link
Collaborator

Note

The commits are additive and tightly-scoped. You'll want to review commit-by-commit.

What this PR does

  • Fully implements the config v2 schema (switching all internal logic to operate on v2 data structures):
    • The main analyzer (datadog-static-analyzer and git hook)
    • The IDE extension (datadog-static-analyzer-server endpoints for config editing)
    • The server (datadog-static-analyzer-server POST requests to /analyze)
  • Artificially disables v2 parsing unless the code is running in a unit test. This lets us ensure test coverage of all the v2 changes without making them public to users.
    • This is done because merging with remote configuration requires the analyzer to send its local configuration. The backend has not implement v2 yet, so it will always error.

Summary

For both v1 and v2, parsing a configuration file happens in two stages. 1) The file is parsed into a "YamlConfigFile" struct. Then, that struct is translated into a "ConfigFile".

If a configuration file is a v1 file, it gets convert from a file_v1::YamlConfigFile to a file_v2::YamlConfigFile (operating at this level this makes it easy to provide a CLI tool to convert files):

let local_config: Option<file_v2::ConfigFile> = local_yaml.map(|v| match v {
WithVersion::V1(v1) => file_v2::YamlConfigFile::from(v1).into(),
WithVersion::V2(v2) => v2.into(),
});

From there, a file_v2::YamlConfigFile is always translated into a file_v2::ConfigFile, which all program logic uses.

Notes for reviewer

For the IDE, the only relevant commits are:

  • 400b164, which switches the implementation to use an enum, holding either a v1 config or v2 config. This allows for the IDE to perform all actions (ignoring rules, etc.) on either a v1 or v2 config.
  • ff4df07 adds tests for v2 alongside the existing v1 tests. Note: not all tests are required for v2. I've added notes where v2 tests were omitted, e.g.:
    // NOTE:
    // Translating this specific test is not required for v2 because
    // `it_keeps_existing_properties_when_ignoring_other_rules` already demonstrates
    // (`only-paths` and `severity` are conceptually the same: properties of a RuleConfig)

For the analyzer, please:

  • Check that the v1 -> v2 YAML conversion logic is correct and that the tests are exhaustive. (949f6e1)
  • e495f67 converts the datadog-static-analyzer binary to use v2 structs under the hood. Check that
    • ...there are no regressions in default (unconfigured) settings (e.g. confirm that v1's "ignore-gitignore" defaulting to false has the same logical effect as v2's "use-gitignore" defaulting to true)
    • ...the behavior with fetching default rulesets is logically correct (some details have changed -- e.g. we no longer use the presence of a config file to determine whether to fetch default rulesets or not)
    • ...duplicate rulesets are not submitted to the analyzer (e.g. a v2 that lists "java-security" in use-rulesets, but "java-security" also exists in the default ruleset list.

What's Next

Once the backend implements v2:

  1. f95139e will be reverted.
  2. v2 configuration files will be added to all integration tests.

(At this point, we can start using v2 everywhere)

  1. schema.json will be updated to include v2.
  2. Docs will be updated.

@jasonforal jasonforal requested review from a team as code owners February 10, 2026 00:10
@datadog-official
Copy link

datadog-official bot commented Feb 10, 2026

🎯 Code Coverage
Patch Coverage: 82.71%
Overall Coverage: 84.97% (+0.10%)

View detailed report

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: e7e3d79 | Docs | Datadog PR Page | Was this helpful? Give us feedback!

.use_rulesets
.get_or_insert_with(|| Vec::with_capacity(rulesets.len()));
for ruleset_name in rulesets {
// if list.iter().find(|&name| ruleset_name.as_ref() ==)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left over.

}

// test behaviors
// add empty rulesets to v2 doesn't instantiate a use_rulesets
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO? :)

|| prettify_yaml(&fixed),
|original_content| reconcile_comments(original_content, &fixed, true),
|| prettify_yaml(&yaml),
|original_content| reconcile_comments(original_content, &yaml, true),
Copy link
Contributor

@robertohuertasm-datadog robertohuertasm-datadog Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reconcile_comments function may not work with V2 structure. The test may only care about V1, so the fact that they pass may not indicate that it works with V2 as well. We should probably extend the tests to cover v2 as well.

Copy link
Contributor

@robertohuertasm-datadog robertohuertasm-datadog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🚀

@jasonforal jasonforal merged commit e520c24 into main Feb 17, 2026
98 of 99 checks passed
@jasonforal jasonforal deleted the jf/K9VULN-11259 branch February 17, 2026 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants