Skip to content

Replace domain validation boolean with tri-state mode#7611

Merged
Linker44 merged 21 commits intomainfrom
domain-validation-monitor-mode
Mar 11, 2026
Merged

Replace domain validation boolean with tri-state mode#7611
Linker44 merged 21 commits intomainfrom
domain-validation-monitor-mode

Conversation

@Linker44
Copy link
Copy Markdown
Contributor

@Linker44 Linker44 commented Mar 10, 2026

Ticket ENG-2569

Description Of Changes

Replace the FIDES__SECURITY__DISABLE_DOMAIN_VALIDATION boolean env var with a tri-state FIDES__SECURITY__DOMAIN_VALIDATION_MODE that accepts enabled, monitor, or disabled.

In monitor mode, domain violations are logged as warnings instead of blocking requests, giving operators a safe migration path: observe violations first, then flip to enabled to enforce. The default is monitor.

Dev mode now defaults to monitor instead of disabled, so developers still see domain violation warnings during local development.

Code Changes

  • src/fides/config/security_settings.py - Add DomainValidationMode enum, replace disable_domain_validation: bool field with domain_validation_mode: DomainValidationMode
  • src/fides/api/util/saas_util.py - Replace is_domain_validation_disabled() with get_domain_validation_mode() returning the enum; dev mode maps to monitor
  • src/fides/api/util/domain_util.py - Add monitor param to validate_value_against_allowed_list(); logs warning instead of raising when monitor=True
  • src/fides/api/service/connectors/saas/authenticated_client.py - Use new mode enum for runtime request domain validation
  • src/fides/api/schemas/connection_configuration/connection_secrets_saas.py - Use new mode enum for secret save-time validation
  • src/fides/api/schemas/saas/saas_config.py - Use new mode enum for connector template default value validation (lazy import to avoid circular dependency)
  • tests/ops/schemas/connection_configuration/test_connection_secrets_saas.py - Update mocks to use get_domain_validation_mode + enum values
  • tests/ops/service/connectors/saas/test_authenticated_client.py - Update mocks to use get_domain_validation_mode + enum values

Steps to Confirm

  1. Set FIDES__SECURITY__DOMAIN_VALIDATION_MODE=monitor and save a disallowed domain on a SaaS connector — should succeed with a warning in the logs
  2. Set FIDES__SECURITY__DOMAIN_VALIDATION_MODE=enabled and repeat — should be rejected with a ValueError
  3. Set FIDES__SECURITY__DOMAIN_VALIDATION_MODE=disabled and repeat — should succeed silently
  4. Run with no env var set — default is monitor, violations should log warnings

Pre-Merge Checklist

  • Issue requirements met
  • All CI pipelines succeeded
  • CHANGELOG.md updated
    • Add a db-migration This indicates that a change includes a database migration label to the entry if your change includes a DB migration
    • Add a high-risk This issue suggests changes that have a high-probability of breaking existing code label to the entry if your change includes a high-risk change (i.e. potential for performance impact or unexpected regression) that should be flagged
    • Updates unreleased work already in Changelog, no new entry necessary
  • UX feedback:
    • All UX related changes have been reviewed by a designer
    • No UX review needed
  • Followup issues:
    • Followup issues created
    • No followup issues
  • Database migrations:
    • Ensure that your downrev is up to date with the latest revision on main
    • Ensure that your downgrade() migration is correct and works
      • If a downgrade migration is not possible for this change, please call this out in the PR description!
    • No migrations
  • Documentation:
    • Documentation complete, PR opened in fidesdocs
    • Documentation issue created in fidesdocs
    • If there are any new client scopes created as part of the pull request, remember to update public-facing documentation that references our scope registry
    • No documentation updates required

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Changed

    • Domain validation now supports three modes — enabled, monitor, and disabled — replacing the previous binary toggle. Monitor mode logs warnings instead of blocking disallowed domains; default remains monitor. Configuration now accepts the mode setting.
  • Tests

    • Updated tests to use mode-based behavior and added coverage for monitor-mode warning emission, wildcard/empty-value cases, and varied validation scenarios.
  • Changelog

    • Added an entry documenting the new domain validation modes.

…/monitor/disabled)

Replace FIDES__SECURITY__DISABLE_DOMAIN_VALIDATION boolean with
FIDES__SECURITY__DOMAIN_VALIDATION_MODE enum that accepts "enabled",
"monitor", or "disabled". Monitor mode validates domains but logs
warnings instead of blocking, giving operators a safe way to observe
violations before enforcing. Default is "monitor".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
fides-plus-nightly Ignored Ignored Preview Mar 11, 2026 6:19pm
fides-privacy-center Ignored Ignored Mar 11, 2026 6:19pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Replace the binary domain-validation flag with a tri-state DomainValidationMode (enabled / monitor / disabled); update configuration, domain utilities, SaaS schemas, AuthenticatedClient, and tests to use the mode; validate_value_against_allowed_list gains a mode parameter that logs in monitor mode instead of raising.

Changes

Cohort / File(s) Summary
Configuration & Enum
src/fides/config/security_settings.py
Add DomainValidationMode enum and replace disable_domain_validation: bool with domain_validation_mode: DomainValidationMode (default: monitor); add lowercase coercion validator.
Domain utilities
src/fides/api/util/domain_util.py
Add get_domain_validation_mode(); change validate_value_against_allowed_list to accept mode: DomainValidationMode and log warnings in monitor instead of raising; add logger and update messaging.
Removed helper
src/fides/api/util/saas_util.py
Remove is_domain_validation_disabled(); logic centralized in get_domain_validation_mode().
SaaS schemas
src/fides/api/schemas/.../connection_secrets_saas.py, src/fides/api/schemas/saas/saas_config.py
Replace boolean gate with get_domain_validation_mode() checks; skip validation when mode == disabled; pass mode=domain_mode to allowed-values validation.
Authenticated client
src/fides/api/service/connectors/saas/authenticated_client.py
Cache domain mode on init; treat disabled as skipping host extraction; pass mode=self._domain_validation_mode to request-domain validation.
Tests
tests/ops/schemas/connection_configuration/test_connection_secrets_saas.py, tests/ops/service/connectors/saas/test_authenticated_client.py
Replace patches of is_domain_validation_disabled with get_domain_validation_mode, use DomainValidationMode enum values, add tests asserting monitor-mode warning logging and update expectations.
Changelog
changelog/7611-domain-validation-monitor-mode.yaml
Add changelog entry documenting replacement of boolean toggle with tri-state mode and PR reference.
Manifest / metadata
manifest_file, requirements.txt, pyproject.toml
Minor manifest/test metadata adjustments accompanying code and tests changes.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Auth as AuthenticatedClient
    participant Schema as SaaS_Schema
    participant Util as domain_util

    Client->>Auth: perform operation needing domain check
    Auth->>Auth: read cached domain_validation_mode
    Auth->>Schema: validate param / extract allowed hosts
    Schema->>Util: get_domain_validation_mode()
    Util-->>Schema: DomainValidationMode (enabled/monitor/disabled) rgba(0,128,0,0.5)
    Schema->>Util: validate_value_against_allowed_list(value, allowed_values, param_name, mode=domain_mode)
    alt mode == enabled
        Util->>Schema: raise ValueError on mismatch rgba(255,0,0,0.5)
    else mode == monitor
        Util->>Schema: log warning on mismatch rgba(255,165,0,0.5)
        Schema-->>Auth: continue (no exception)
    else mode == disabled
        Util-->>Schema: skip validation (no-op) rgba(128,128,128,0.5)
    end
    Auth-->>Client: proceed or error based on validation outcome
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Vagoasdf
  • RobertKeyser
  • erosselli

Poem

🐰 A three-way hop for domains today,
Enabled, monitor, or tucked away.
I nibble logs when rules make a fuss,
I only shout when errors bother us,
Hoppity security—cheerfully okay!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary change: replacing a boolean domain validation toggle with a tri-state mode system.
Docstring Coverage ✅ Passed Docstring coverage is 85.71% which is sufficient. The required threshold is 80.00%.
Description check ✅ Passed The pull request description is comprehensive and well-structured, covering all required sections: description of changes, code changes list, steps to confirm, and pre-merge checklist completion.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch domain-validation-monitor-mode

Comment @coderabbitai help to get the list of available commands and usage tips.

@Linker44 Linker44 marked this pull request as ready for review March 10, 2026 16:31
@Linker44 Linker44 requested a review from a team as a code owner March 10, 2026 16:31
@Linker44 Linker44 requested review from RobertKeyser, Vagoasdf and johnewart and removed request for a team and johnewart March 10, 2026 16:31
@Linker44 Linker44 self-assigned this Mar 10, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 10, 2026

Greptile Summary

This PR replaces the FIDES__SECURITY__DISABLE_DOMAIN_VALIDATION boolean with a tri-state FIDES__SECURITY__DOMAIN_VALIDATION_MODE enum (enabled / monitor / disabled), adding a safe migration path via monitor mode that logs warnings instead of blocking requests. The default is monitor, and dev mode now downgrades enabled to monitor rather than bypassing validation entirely.

Key changes:

  • DomainValidationMode enum added to security_settings.py; a mode="before" validator normalises the env-var string to lowercase before enum coercion
  • get_domain_validation_mode() consolidated into domain_util.py (breaking the previous circular import with saas_util.py)
  • validate_value_against_allowed_list() extended with a mode parameter; monitor logs a structured warning and returns, enabled raises ValueError with updated guidance
  • AuthenticatedClient captures the mode once at construction time and forwards it on every _validate_request_domain call
  • Schema validators in connection_secrets_saas.py and saas_config.py call get_domain_validation_mode() inline and pass the result through
  • Tests updated to mock get_domain_validation_mode with enum values; new monitor-mode tests correctly use caplog
  • One minor style issue: import logging is placed inside the test_validation_monitor_mode_logs_warning test method instead of at the top of test_authenticated_client.py

Confidence Score: 4/5

  • Safe to merge; the only finding is a trivial misplaced import in a test file.
  • The core logic across all changed files is correct and well-tested: all three modes are exercised, the circular-import issue raised in the previous review round has been resolved, and the caplog fixture is used properly for warning assertions. The single deduction is for the import logging statement placed inside a test method body rather than at the top of the file, which violates project import-placement conventions.
  • tests/ops/service/connectors/saas/test_authenticated_client.py — move import logging to the top of the file.

Important Files Changed

Filename Overview
src/fides/config/security_settings.py Introduces DomainValidationMode enum and replaces disable_domain_validation: bool with domain_validation_mode: DomainValidationMode. Adds a mode="before" validator that lowercases the string value before enum coercion, making the env var case-insensitive. Clean implementation with no issues.
src/fides/api/util/domain_util.py Adds get_domain_validation_mode() (moved from saas_util.py to break a circular import) and extends validate_value_against_allowed_list() with a mode parameter. Monitor mode logs a structured warning instead of raising; enabled mode raises ValueError with updated guidance text. Logic is correct for all three modes.
src/fides/api/service/connectors/saas/authenticated_client.py Captures _domain_validation_mode once at construction time and passes it to validate_value_against_allowed_list. The disabled check in _extract_allowed_hosts correctly short-circuits to None, and _validate_request_domain forwards the stored mode. No issues.
src/fides/api/schemas/connection_configuration/connection_secrets_saas.py Migrates secret save-time validation to use get_domain_validation_mode() and the enum. The guard domain_mode != DomainValidationMode.disabled correctly skips the call entirely when disabled. No issues.
src/fides/api/schemas/saas/saas_config.py Migrates connector template default-value validation to the new enum. The top-level import of get_domain_validation_mode from domain_util (resolving the previous circular-import thread) and the domain_mode != DomainValidationMode.disabled guard are both correct.
tests/ops/schemas/connection_configuration/test_connection_secrets_saas.py Tests updated to mock get_domain_validation_mode with enum return values; new test_disallowed_domain_warns_in_monitor_mode uses caplog correctly. import logging is properly at the top of the file.
tests/ops/service/connectors/saas/test_authenticated_client.py Tests updated with new monitor-mode coverage and caplog assertions. One minor issue: import logging is placed inside test_validation_monitor_mode_logs_warning instead of at the top of the file.

Last reviewed commit: a815acb

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
tests/ops/service/connectors/saas/test_authenticated_client.py (1)

293-300: Consider adding a test for monitor mode behavior.

The tests cover enabled and disabled modes, but there's no explicit test verifying that monitor mode logs a warning without raising an exception. This would ensure the new logging path works correctly.

📝 Example test for monitor mode
`@mock.patch`(
    "fides.api.service.connectors.saas.authenticated_client.get_domain_validation_mode",
    return_value=DomainValidationMode.monitor,
)
def test_validation_monitor_mode_logs_warning(self, mock_mode, caplog):
    """Monitor mode should log a warning but not raise."""
    client = _make_client_with_allowed_values({"domain": ["api.stripe.com"]})
    with caplog.at_level("WARNING"):
        client._validate_request_domain("evil.example.com")  # Should not raise
    assert "Domain validation violation (monitor mode)" in caplog.text
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/ops/service/connectors/saas/test_authenticated_client.py` around lines
293 - 300, Add a new test that asserts monitor mode logs a warning but does not
raise: patch get_domain_validation_mode to return DomainValidationMode.monitor,
create the client via _make_client_with_allowed_values({"domain":
["api.stripe.com"]}), call client._validate_request_domain("evil.example.com")
inside a caplog.at_level("WARNING") context, and assert the warning message
(e.g. contains "Domain validation violation (monitor mode)") appears in
caplog.text; this verifies the _validate_request_domain path for monitor mode
without expecting an exception.
tests/ops/schemas/connection_configuration/test_connection_secrets_saas.py (1)

149-153: Add explicit monitor-mode coverage.

These updates only exercise enabled and disabled, but monitor is the new default and has different semantics: allow the value and emit a warning. Without a test here, the migration path can regress silently.

Example test to cover the missing path
+import logging
+
     `@patch`(
         "fides.api.schemas.connection_configuration.connection_secrets_saas.get_domain_validation_mode",
         return_value=DomainValidationMode.disabled,
     )
     def test_disallowed_domain_passes_when_validation_disabled(
         self, mock_mode, saas_config_with_allowed_values
     ):
         """Domain validation should be skipped when disabled."""
         schema = SaaSSchemaFactory(saas_config_with_allowed_values).get_saas_schema()
         schema.model_validate({"domain": "evil.example.com", "api_key": "sk_test_123"})
+
+    `@patch`(
+        "fides.api.schemas.connection_configuration.connection_secrets_saas.get_domain_validation_mode",
+        return_value=DomainValidationMode.monitor,
+    )
+    def test_disallowed_domain_warns_in_monitor_mode(
+        self, mock_mode, saas_config_with_allowed_values, caplog
+    ):
+        schema = SaaSSchemaFactory(saas_config_with_allowed_values).get_saas_schema()
+
+        with caplog.at_level(logging.WARNING):
+            schema.model_validate(
+                {"domain": "evil.example.com", "api_key": "sk_test_123"}
+            )
+
+        assert "not in the list of allowed values" in caplog.text

Also applies to: 159-162, 171-175, 182-186, 206-210, 225-229, 248-252

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/ops/schemas/connection_configuration/test_connection_secrets_saas.py`
around lines 149 - 153, The tests currently patch get_domain_validation_mode
only for DomainValidationMode.enabled/disabled; add explicit coverage for the
monitor mode by creating parallel test cases (e.g., extend
test_allowed_domain_passes and the other affected tests referenced) that patch
get_domain_validation_mode to return DomainValidationMode.monitor and assert the
behavior: the value is allowed but a warning is emitted (check for a logged
warning or returned warning flag as appropriate). Locate occurrences where
get_domain_validation_mode is patched and duplicate the test logic for the
monitor variant, ensuring assertions verify both acceptance of the value and
emission of a warning rather than an error or silence.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/ops/schemas/connection_configuration/test_connection_secrets_saas.py`:
- Around line 149-153: The tests currently patch get_domain_validation_mode only
for DomainValidationMode.enabled/disabled; add explicit coverage for the monitor
mode by creating parallel test cases (e.g., extend test_allowed_domain_passes
and the other affected tests referenced) that patch get_domain_validation_mode
to return DomainValidationMode.monitor and assert the behavior: the value is
allowed but a warning is emitted (check for a logged warning or returned warning
flag as appropriate). Locate occurrences where get_domain_validation_mode is
patched and duplicate the test logic for the monitor variant, ensuring
assertions verify both acceptance of the value and emission of a warning rather
than an error or silence.

In `@tests/ops/service/connectors/saas/test_authenticated_client.py`:
- Around line 293-300: Add a new test that asserts monitor mode logs a warning
but does not raise: patch get_domain_validation_mode to return
DomainValidationMode.monitor, create the client via
_make_client_with_allowed_values({"domain": ["api.stripe.com"]}), call
client._validate_request_domain("evil.example.com") inside a
caplog.at_level("WARNING") context, and assert the warning message (e.g.
contains "Domain validation violation (monitor mode)") appears in caplog.text;
this verifies the _validate_request_domain path for monitor mode without
expecting an exception.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 82157187-6264-4073-8a27-395ec4351544

📥 Commits

Reviewing files that changed from the base of the PR and between 5acf39d and 83c47ef.

📒 Files selected for processing (9)
  • changelog/7611-domain-validation-monitor-mode.yaml
  • src/fides/api/schemas/connection_configuration/connection_secrets_saas.py
  • src/fides/api/schemas/saas/saas_config.py
  • src/fides/api/service/connectors/saas/authenticated_client.py
  • src/fides/api/util/domain_util.py
  • src/fides/api/util/saas_util.py
  • src/fides/config/security_settings.py
  • tests/ops/schemas/connection_configuration/test_connection_secrets_saas.py
  • tests/ops/service/connectors/saas/test_authenticated_client.py

@Linker44
Copy link
Copy Markdown
Contributor Author

Added monitor mode test coverage in both test_connection_secrets_saas.py and test_authenticated_client.py — each verifies that a disallowed domain passes without raising while logging a warning.

- Add monitor mode test coverage in both test files
- Move get_domain_validation_mode from saas_util to domain_util to fix circular import

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fides/api/util/domain_util.py`:
- Around line 13-17: get_domain_validation_mode currently unconditionally
returns DomainValidationMode.monitor when CONFIG.dev_mode is true; change it so
an explicitly configured mode in CONFIG.security.domain_validation_mode takes
precedence. Update get_domain_validation_mode to: if
CONFIG.security.domain_validation_mode is set (not None / explicitly provided)
return that value; otherwise, if CONFIG.dev_mode is true return
DomainValidationMode.monitor; else return CONFIG.security.domain_validation_mode
(or the default). Reference symbols: get_domain_validation_mode,
CONFIG.dev_mode, CONFIG.security.domain_validation_mode,
DomainValidationMode.monitor.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ac667bf9-beab-4626-afe0-c6ec492228bd

📥 Commits

Reviewing files that changed from the base of the PR and between 83c47ef and 32a07c7.

📒 Files selected for processing (7)
  • src/fides/api/schemas/connection_configuration/connection_secrets_saas.py
  • src/fides/api/schemas/saas/saas_config.py
  • src/fides/api/service/connectors/saas/authenticated_client.py
  • src/fides/api/util/domain_util.py
  • src/fides/api/util/saas_util.py
  • tests/ops/schemas/connection_configuration/test_connection_secrets_saas.py
  • tests/ops/service/connectors/saas/test_authenticated_client.py
💤 Files with no reviewable changes (1)
  • src/fides/api/util/saas_util.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/ops/service/connectors/saas/test_authenticated_client.py
  • src/fides/api/schemas/saas/saas_config.py

Dev mode no longer overrides an explicit disabled setting back to monitor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Linker44
Copy link
Copy Markdown
Contributor Author

Updated get_domain_validation_mode to only downgrade enabledmonitor in dev mode. If someone explicitly sets disabled, dev mode won't override that back to monitor.

Linker44 and others added 2 commits March 10, 2026 17:23
Add field validator to lowercase the value before enum coercion,
so ENABLED, Monitor, DISABLED etc. all work.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fides/api/util/domain_util.py`:
- Around line 78-83: Replace the tenant-specific warning: when the code path
using the variable monitor calls logger.warning with violation_msg and a
hardcoded reference to DOMAIN_VALIDATION_MODE, change it to a generic,
non-identifying message that does not include violation_msg or raw
domain/allowlist values and does not mention a specific env value; update the
logger.warning invocation in domain_util.py (the site where monitor and
violation_msg are used) to a short, mode-agnostic message such as "Domain
validation violation detected; details suppressed by current configuration." so
no customer-specific identifiers are written to logs and avoid referencing
get_domain_validation_mode() or hardcoded '=enabled' text.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 64f6ac20-710b-4a44-8b92-d8ad59f5eb33

📥 Commits

Reviewing files that changed from the base of the PR and between 32a07c7 and 82f4b43.

📒 Files selected for processing (1)
  • src/fides/api/util/domain_util.py

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/fides/config/security_settings.py`:
- Around line 150-156: The Field for domain_validation_mode currently defaults
to DomainValidationMode.monitor which causes fresh prod installs to be
warning-only; change the default in the domain_validation_mode Field to
DomainValidationMode.enabled so enforcement is the default, and keep any
downgrade-to-monitor behavior limited to the dev-only logic in
get_domain_validation_mode(); ensure you update the Field default
(domain_validation_mode) and do not alter get_domain_validation_mode() except to
rely on it for dev-only overrides.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bc57e7f0-d114-4d95-b4cd-263d8610a26e

📥 Commits

Reviewing files that changed from the base of the PR and between 82f4b43 and eb183ee.

📒 Files selected for processing (1)
  • src/fides/config/security_settings.py

Remove inaccurate hint about DOMAIN_VALIDATION_MODE=enabled since
dev mode downgrades that to monitor anyway.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Linker44 and others added 2 commits March 10, 2026 17:39
Avoids boolean trap — callers now pass the mode directly instead
of encoding behavior as a boolean.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Linker44
Copy link
Copy Markdown
Contributor Author

@greptileai

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/fides/api/schemas/connection_configuration/connection_secrets_saas.py (1)

82-95: Consider hoisting get_domain_validation_mode() outside the loop.

The call to get_domain_validation_mode() is inside the for name, value in values.items() loop, but the mode is a global configuration that won't change during iteration. Moving it before the loop (e.g., near line 54) avoids redundant calls.

♻️ Suggested refactor
     `@model_validator`(mode="before")
     `@classmethod`
     def required_components_supplied(cls, values: Dict) -> Dict[str, Any]:  # type: ignore
         """Validate that the minimum required components have been supplied."""
         # check required components are present
         required_components = [
             name
             for name, attributes in cls.model_fields.items()
             if attributes.is_required()
         ]
         min_fields_present = all(
             values.get(component) for component in required_components
         )
         if not min_fields_present:
             raise ValueError(
                 f"{cls.__name__} must be supplied all of: [{', '.join(required_components)}]."  # type: ignore
             )

+        domain_mode = get_domain_validation_mode()
+
         # check the types and values are consistent with the option and multivalue fields
         for name, value in values.items():
             connector_param = cls.get_connector_param(name)
             if connector_param:
                 # ... existing options/multiselect validation ...

                 param_type = connector_param.get("param_type")
                 allowed_values = connector_param.get("allowed_values")
-                domain_mode = get_domain_validation_mode()
                 if (
                     param_type == "endpoint"
                     and allowed_values is not None
                     and len(allowed_values) > 0
                     and isinstance(value, str)
                     and domain_mode != DomainValidationMode.disabled
                 ):
                     validate_value_against_allowed_list(
                         value,
                         allowed_values,
                         name,
                         mode=domain_mode,
                     )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/fides/api/schemas/connection_configuration/connection_secrets_saas.py`
around lines 82 - 95, Hoist the call to get_domain_validation_mode() out of the
per-item loop so it is computed once, then reuse that stored mode inside the
loop where validate_value_against_allowed_list(...) is called; specifically,
compute mode = get_domain_validation_mode() before iterating over values.items()
and replace the in-loop domain_mode references with the cached mode to avoid
repeated calls during the for name, value in values.items() iteration.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/fides/api/schemas/connection_configuration/connection_secrets_saas.py`:
- Around line 82-95: Hoist the call to get_domain_validation_mode() out of the
per-item loop so it is computed once, then reuse that stored mode inside the
loop where validate_value_against_allowed_list(...) is called; specifically,
compute mode = get_domain_validation_mode() before iterating over values.items()
and replace the in-loop domain_mode references with the cached mode to avoid
repeated calls during the for name, value in values.items() iteration.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 40827cd7-6241-4211-9148-3c9f3da94241

📥 Commits

Reviewing files that changed from the base of the PR and between eb183ee and a815acb.

📒 Files selected for processing (4)
  • src/fides/api/schemas/connection_configuration/connection_secrets_saas.py
  • src/fides/api/schemas/saas/saas_config.py
  • src/fides/api/service/connectors/saas/authenticated_client.py
  • src/fides/api/util/domain_util.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/fides/api/service/connectors/saas/authenticated_client.py
  • src/fides/api/util/domain_util.py

Linker44 and others added 4 commits March 10, 2026 21:23
domain_util.py was using the stdlib `logging` module while the rest of
the codebase uses `loguru`, so warnings were silently dropped. Switch to
loguru and use {} placeholder style.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In enabled mode, the domain validation ValueError was caught by the
retry_send decorator and logged as a generic NetworkError. Introduce a
DomainValidationError exception with a dedicated DomainBlocked error
group so the violation message surfaces in logs instead of "Unknown
exception connecting to ...".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DomainValidationError was being wrapped in a generic ConnectionException
("Operational Error connecting to ...") which hid the actual violation
from the user. Handle it separately in retry_send to preserve the
message.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Linker44 Linker44 requested a review from RobertKeyser March 11, 2026 15:03
- format_value_for_toml now quotes string values whose schema type
  wasn't resolved (e.g. enum fields like domain_validation_mode)
- Remove caplog/capsys assertion from monitor-mode test since loguru
  doesn't write to either; the test still verifies no exception is raised

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Linker44 Linker44 enabled auto-merge March 11, 2026 17:13
@Linker44 Linker44 disabled auto-merge March 11, 2026 17:30
Linker44 and others added 2 commits March 11, 2026 15:03
…llowed_list

The function defaults to monitor mode which only logs warnings. Tests
expecting DomainValidationError need enabled mode to trigger raises.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Resolve import conflict in authenticated_client.py by keeping all
three imports from saas_util.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Linker44 Linker44 enabled auto-merge March 11, 2026 18:05
Linker44 and others added 2 commits March 11, 2026 15:05
This function was removed by the branch (replaced by
get_domain_validation_mode in domain_util) but reintroduced during
the merge with main. Fixes mypy, check_install, and collect-tests CI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Linker44 Linker44 added this pull request to the merge queue Mar 11, 2026
Merged via the queue into main with commit 0b4dac6 Mar 11, 2026
57 checks passed
@Linker44 Linker44 deleted the domain-validation-monitor-mode branch March 11, 2026 18:56
mfbrown pushed a commit that referenced this pull request Mar 12, 2026
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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