Skip to content

Add security config validation based on configuration provider#22226

Merged
NouemanKHAL merged 49 commits into
masterfrom
noueman/add-source-and-provider-base-check
Mar 20, 2026
Merged

Add security config validation based on configuration provider#22226
NouemanKHAL merged 49 commits into
masterfrom
noueman/add-source-and-provider-base-check

Conversation

@NouemanKHAL

@NouemanKHAL NouemanKHAL commented Dec 22, 2025

Copy link
Copy Markdown
Member

What does this PR do?

  • Add a security module SecurityConfig to the base check that reads provider
    trust settings from the Agent configuration (trusted providers, file path
    allowlist, excluded checks)
  • Introduce require_trusted_provider: true as a spec property for sensitive fields, file paths (tls_cert, tls_private_key, tls_ca_cert, kerberos_cache, kerberos_keytab, JMX store/key paths) and the object-typed auth_token
  • Generate SECURE_FIELD_NAMES in config models and validate marked fields during
    model loading, blocking values from untrusted providers unless they're in the file
    path allowlist
  • Add a GLOBAL_SECURE_FIELDS fallback in the base check for integrations with older
    generated models
  • For auth_token specifically, only enforce validation when reader.type == 'file',
    checking reader.path against the allowlist, other reader types (e.g. oauth) pass
    through
    - Regenerate config models across all integrations_ ( Will be done in a separate PR after datadog-checks-base release with these changes)

Depends on: DataDog/datadog-agent#44544

Motivation

https://datadoghq.atlassian.net/browse/AI-5322

Verification Process

  • Automated unit tests
  • Testing in a kubernetes lab environment using both an existing agent docker image and a pipeline docker image from this testing branch where I update the release.json ints core hash to target the latest commit on this branch, and have a http_check configured via pod annotation and testing for the expected output. (currently waiting for CI to redeploy the environment with the new agent docker image from the pipeline)

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Add the qa/skip-qa label if the PR doesn't need to be tested during QA.
  • If you need to backport this PR to another branch, you can add the backport/<branch-name> label to the PR and it will automatically open a backport PR once this one is merged

@codecov

codecov Bot commented Dec 22, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.38462% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.33%. Comparing base (f410c11) to head (ec38a1b).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@datadog-datadog-prod-us1

This comment has been minimized.

NouemanKHAL and others added 9 commits March 19, 2026 14:45
Cover three security-critical code paths that had zero test
coverage: GLOBAL_SECURE_FIELDS fallback blocking, allowlist
bypass, and excluded_checks bypass.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Use specific ConfigurationError in pytest.raises to avoid
masking unexpected exceptions.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
dd_run_check wraps all errors as Exception, so match on
ConfigurationError in the traceback string to verify the
correct exception type is raised internally.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add (?s) dotall flag so ConfigurationError match works across
newlines in dd_run_check's traceback output.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…cking

Add an object-typed `auth_token` field with `require_trusted_provider: true`
to the test spec/model and a test asserting that non-string secure fields
are blocked from untrusted providers.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Remove the `isinstance(value, str)` early return that let non-string values
bypass validation. Non-string values (e.g. object-typed auth_token) from
untrusted providers are now blocked; the allowlist escape is applied only to
string file paths.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Comment thread datadog_checks_base/datadog_checks/base/utils/models/validation/security.py Outdated
Comment thread datadog_checks_base/datadog_checks/base/checks/base.py Outdated

@AAraKKe AAraKKe left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Minimum base checks tests are not running and I think this would actually break unless we bump the minimum base check of all integrations that have been updated. Maybe we can split this into multiple PRs?

Just requesting changes to block the merge in case we rush merge without noticing that.

NouemanKHAL and others added 3 commits March 20, 2026 14:58
Reset integration model regenerations, changelogs, and unrelated
dependency changes so the branch only contains datadog_checks_base/ diffs.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
AAraKKe
AAraKKe previously approved these changes Mar 20, 2026

@AAraKKe AAraKKe left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks @NouemanKHAL mostly questions from my side, I am approving and let you decide whether to merge and handle the suggestion later.

I still think the nomenclature of this feature is very confusing and hard to follow 😅

Comment thread datadog_checks_base/datadog_checks/base/checks/base.py Outdated
Comment thread datadog_checks_base/datadog_checks/base/checks/base.py
return True
if security_config.is_provider_trusted(security_config.provider):
return True
if isinstance(value, str):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

question: how do you know this is a path to validate in is_file_path_allowed? A string can be anything, why not making an actual validation?

if isinstance(value, str) and Path(value).is_file()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

By design, these security validations were designed for file path parameters only. But it's true, it could be better to handle and have proper error handling in case of misuse of the parameter.
Will address in a follow-up PR if you don't mind.

return True
if isinstance(value, str):
return security_config.is_file_path_allowed(value)
# auth_token is the only non-string field with require_trusted_provider;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

question: is this ok? How do you know this is the case? As in, what happens if tomorrow there is a new configuration option that requires trusted provider? Are we overfitting the solution to the currently known fields or we know for sure this is only going to be used for files.

@NouemanKHAL NouemanKHAL Mar 20, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

By design, these security validations were designed for file path parameters only.

Comment thread datadog_checks_base/datadog_checks/base/utils/models/validation/security.py Outdated
Comment thread datadog_checks_base/tests/models/test_security.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants