Skip to content

Add error code and message in sarif file #826

Merged
gillarramendi merged 11 commits intomainfrom
gotzon.illarramendi/add-error-code-in-sarif
Mar 10, 2026
Merged

Add error code and message in sarif file #826
gillarramendi merged 11 commits intomainfrom
gotzon.illarramendi/add-error-code-in-sarif

Conversation

@gillarramendi
Copy link
Copy Markdown
Contributor

@gillarramendi gillarramendi commented Mar 2, 2026

What problem are you trying to solve?

The objective is to increase visibility on Secret rule validation error. Currently the error are logged but are not propagated to the DataDog backend, so they are lost.

What is your solution?

MatchStatus::Error now includes multiple errors. Each error contains a type, error code and message (liked PR).
Code and message are included on the SARIF generated file as PropertyBag inside custom property datadogSecretValidationErrors

Example:

      "tags":
      [
          "DATADOG_CATEGORY:SECURITY",
          "DATADOG_SECRET_VALIDATION_STATUS:VALIDATION_ERROR"
      ],
      "datadogSecretValidationErrors":
      [
          {
              "type": "UnknownResponseType",
              "statusCode": 404,
              "message": "Unknown response type (body_length: 0, body_prefix: '')"
          }
      ]

Alternatives considered

Could have combined error details into existing status tag, but separate property provide better queryability.

What the reviewer should know

  • All tests pass with new test coverage for ValidationError scenarios
  • Breaking change: SecretValidationStatus no longer implements Copy (now Clone only)
  • SARIF output is backward compatible - only adds new tags for ValidationError cases
  • sds dependency switched to last release

Comment thread crates/secrets/Cargo.toml Outdated
@datadog-official
Copy link
Copy Markdown

datadog-official Bot commented Mar 2, 2026

🎯 Code Coverage (details)
Patch Coverage: 91.40%
Overall Coverage: 84.83% (+0.09%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 5d39024 | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

@gillarramendi gillarramendi marked this pull request as ready for review March 2, 2026 11:12
@gillarramendi gillarramendi requested a review from a team as a code owner March 2, 2026 11:12
fbryden
fbryden previously approved these changes Mar 2, 2026
Copy link
Copy Markdown
Contributor

@fbryden fbryden left a comment

Choose a reason for hiding this comment

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

LGTM!
Thank you Gotzon!

ChouraquiBen
ChouraquiBen previously approved these changes Mar 4, 2026
Copy link
Copy Markdown

@ChouraquiBen ChouraquiBen left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@gillarramendi gillarramendi dismissed stale reviews from ChouraquiBen and fbryden via 60ea79f March 5, 2026 14:49
@jasonforal
Copy link
Copy Markdown
Collaborator

I think the fact we need to name the tags things like DATADOG_SECRET_VALIDATION_ERROR_TYPE.0 and DATADOG_SECRET_VALIDATION_ERROR_TYPE.1 to flatten/encode array-like data hints that we're modeling this incorrectly.

The SARIF spec has Property Bags (which tags are a special case within). Why don't we add a property for this validation info?

{
  "properties": {
    "tags": [
      "DATADOG_CATEGORY:SECURITY",
      "DATADOG_SECRET_VALIDATION_STATUS:VALIDATION_ERROR"
    ],
    "datadogSecretValidationErrors": [
      { "type": "HttpError", "statusCode": 400, "message": "Invalid token" },
      { "type": "UnknownResponseType", "statusCode": 0, "message": "Connection timeout" }
    ]
  }
}

@gillarramendi
Copy link
Copy Markdown
Contributor Author

I think the fact we need to name the tags things like DATADOG_SECRET_VALIDATION_ERROR_TYPE.0 and DATADOG_SECRET_VALIDATION_ERROR_TYPE.1 to flatten/encode array-like data hints that we're modeling this incorrectly.

The SARIF spec has Property Bags (which tags are a special case within). Why don't we add a property for this validation info?

{
  "properties": {
    "tags": [
      "DATADOG_CATEGORY:SECURITY",
      "DATADOG_SECRET_VALIDATION_STATUS:VALIDATION_ERROR"
    ],
    "datadogSecretValidationErrors": [
      { "type": "HttpError", "statusCode": 400, "message": "Invalid token" },
      { "type": "UnknownResponseType", "statusCode": 0, "message": "Connection timeout" }
    ]
  }
}

I like the idea of using custom property datadogSecretValidationErrors.
Updated the PR, @jasonforal can you please take another look?

@jasonforal
Copy link
Copy Markdown
Collaborator

I wouldn't have get_validation_errors_data return a serde_json::Value, because then you have to do all the unit tests to roundtrip JSON to check schema conformance. You can instead lean on serde and the structs you already have:

So you'd have function signature

fn get_validation_errors_data(&self) -> Option<&[ValidationErrorInfo]>

with a simple implementation like

fn get_validation_errors_data(&self) -> Option<&[ValidationErrorInfo]> {
    let Secret(_, SecretValidationStatus::ValidationError(error_infos)) = &self else {
        return None;
    };
    (!error_infos.is_empty()).then_some(error_infos.as_slice())
}

You'd then change the serde hooks on ValidationErrorInfo to represent your desired naming, e.g.

#[derive(Serialize, Deserialize)
#[serde(rename_all="camelCase")]
pub struct ValidationErrorInfo {
    #[serde(rename="type")]
    pub error_type: ValidationErrorType,
    pub status_code: u16,
    pub message: String,
}

And then in the call site, it becomes:

let json_array = serde_json::to_value(errors_data)?;
properties.additional_properties.insert(
    "datadogSecretValidationErrors".to_string(),
    json_array,
);

And so you don't need to test serialization/deserialization because you can assume serde handles that correctly.


However, when it comes to testing, we're currently mixing two things:
A. Correctness (the data values are what they should be)
B. Serialization (the data looks like what it should)

By unit testing using assert_json_include, you're trying to infer A by testing B.

Instead, you should only test A (and let serde's guarantees implicitly prove B without needing a specific test). So your unit test shouldn't care about JSON at all. In pseudo-code, you'll do something like

let jsonValue = sarif_report.runs[0].results.unwrap()[0].properties.unwrap().additional_properties.get("datadogSecretValidationErrors").unwrap();
let parsed: Vec<ValidationErrorInfo> = serde_json::from_value(jsonValue).unwrap();
// ... assert on Rust struct equivalence
assert_eq!(parsed, vec![ValidationErrorInfo { ... }, ...])

@jasonforal
Copy link
Copy Markdown
Collaborator

And then if you need to prove schema conformance, you'd add a very simple test for each struct:

// pseudo code
#[test]
fn serialize_validation_error_info() {
    let v = ValidationErrorInfo {
       error_type: ...
       status_code: ...
       message: ...
    }
    let expected = "<a hardcoded json string>"
    // and then compare this -- this is effectively testing your serde(rename) directives and serialization/deserialization
    assert_eq!(serde_json::to_value(v)..., expected) //
}

The important thing to note here is that all that unit test does is test serialization/deserialization -- not any logic like where the struct appears. So you would have separate tests for A and B (per the message above)

@gillarramendi
Copy link
Copy Markdown
Contributor Author

  • Updated get_validation_errors_data to remove serialization logic in commit: cfb8f59
  • Created another test case for ValidationErrorInfo serialization 5d39024

@gillarramendi gillarramendi merged commit 1efa83d into main Mar 10, 2026
105 of 106 checks passed
@gillarramendi gillarramendi deleted the gotzon.illarramendi/add-error-code-in-sarif branch March 10, 2026 08:56
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.

4 participants