Closed Bug 2058222 Opened 1 month ago Closed 24 days ago

Add live support for ContentAnalysis and DataLossPrevention policies

Categories

(Enterprise Products :: Firefox, enhancement)

enhancement

Tracking

(Not tracked)

VERIFIED FIXED

People

(Reporter: jmendez, Unassigned, NeedInfo)

References

(Blocks 1 open bug)

Details

Attachments

(2 files)

No description provided.

When implementing this, be sure to update use of setPrefIfPresentAndLock in these policies to be robust to a scenario where a policy property was previously present and then was removed for the same active policy (see PR comment for example/context).

Authored by https://github.com/jonathanmendez
https://github.com/mozilla/enterprise-firefox/commit/0adfa3decc38a9500aee4c8498180dbcbed7b69b
[enterprise-main] Bug 2058222 - Add live support for ContentaAnalysis and DataLossPrevention policies

Authored by https://github.com/jonathanmendez
https://github.com/mozilla/enterprise-firefox/commit/f872e93cb147cef6c728ae6d7983a2280590c288
[enterprise-main] Merge pull request #1218 from jonathanmendez/dlp-policy-live

Status: NEW → RESOLVED
Closed: 24 days ago
Resolution: --- → FIXED

@jmendez Could you help provide a test plan for anything that QA can test with reasonable efforts? You can take a look at the other bugs that added live support. Each one of them has a test plan comment.

Flags: needinfo?(jmendez)

This is a test plan put together by claude. At this point I have only briefly skimmed and edited it. From my initial scan it looks correct, but I will keep the needinfo live here for me to review this more thoroughly.

Test Plan

This bug makes both ContentAnalysis (external agent) and DataLossPrevention (built-in engine) live: they can be added, edited, swapped, and removed without a restart, and the two arbitrate against each other on every update.

Prerequisite note (please read first)

Full rule enforcement by the built-in engine (an actual warn/block dialog quoting the rule's Message) requires the ability to retrieve the DLP module from the console, which as of this writing is not yet implemented. Without it, interception still fires and fails closed, showing Unable to connect to Firefox Enterprise DLP Engine. Paste denied. That message is not a bug -- it is the expected fail-closed path, and it is a good liveness signal: it proves the interception point turned on live in an already-running tab. Every test case below is written to work in that state. FallbackResult: "block" is used throughout because "allow" would let the action through silently with nothing to observe.

Setup

Windows/macOS/Linux desktop, Firefox Enterprise 155+, fresh profile. Probe domains:

  • chatgpt.com -- matched by the paste rule
  • dropbox.com -- matched by the upload rule
  • example.com -- matched by nothing (control)

Before applying any policy, open a second browser window and a tab on https://example.com/, and leave both open for the whole run. The bugs fixed here were only observable when activation happened after the window and the content process already existed -- a window opened after the policy arrives would have masked them.

How to verify the result of each test case

  1. about:policies#active -- lists ContentAnalysis / DataLossPrevention and their current config. Reload after each change.

  2. The DLP indicator (shield-ish button in the toolbar/titlebar) -- present only while content analysis (from either policy) is active. Hover for the tooltip: Data loss prevention (DLP) by <agent name>. Click for more info. Click it for the Data protection panel, which also names the agent. The agent name is how you tell the two providers apart: the built-in engine is always Firefox Enterprise DLP Engine; the external agent uses whatever AgentName the policy set.

  3. about:support > Content Analysis section -- Active, Connected to agent, Agent Path, Request Count. Reload the page after each change; it does not update live. Request Count resetting to 0 means the backend was rebuilt; continuing from its previous value means the change was absorbed by the existing backend.

  4. about:config, filter browser.contentanalysis. -- check values, and that policy-set prefs are locked (not editable). After policy removal they must be unlocked and back at their defaults.

  5. Actual behavior -- in the tab that was already open before the policy arrived, navigate to a probe domain and paste into a text field (or start a file upload / print, per the rule). Expect either the rule's own warn/block dialog (with the WASM provider extension installed) or Unable to connect to <agent name>. (without it). On example.com nothing should happen.

At every step, confirm the change takes effect without restarting the browser, and that it lands in both the original window and the second window.

Test cases

0. Pre-setup baseline

With no policies active, confirm:

  1. No DLP indicator in either window.
  2. about:support > Content Analysis: Active = false.
  3. about:config: browser.contentanalysis.enabled = false, unlocked; browser.contentanalysis.allow_url_regex_list = ^about:(?!blank|srcdoc).* (its shipped default -- note this value, case 7 checks it comes back); browser.contentanalysis.dlp_rules = empty.
  4. Paste into a field on chatgpt.com -- nothing is intercepted.
1. Apply DataLossPrevention (built-in engine on, live)

In the console, set DataLossPrevention:

{
  "FallbackResult": "block",
  "Rules": [
    {
      "Name": "warn-ai-paste",
      "Enabled": true,
      "Actions": ["TextPaste"],
      "Domains": ["chatgpt.com"],
      "Type": "warn",
      "Message": "Pasting work data into AI services may violate company policy."
    }
  ]
}

Expected:

  1. about:policies#active lists DataLossPrevention with this config.
  2. The indicator appears in both already-open windows with no restart. Tooltip and panel read Firefox Enterprise DLP Engine.
  3. Open a third window -- it shows the indicator too.
  4. about:support: Active = true.
  5. about:config, all locked: enabled = true, use_wasm_backend = true, agent_name = Firefox Enterprise DLP Engine, agent_timeout = 300, show_blocked_result = true, bypass_for_same_tab_operations = false, deny_url_regex_list = empty, default_result = 0, timeout_result = 0, dlp_rules contains warn-ai-paste. Interception points: interception_point.clipboard.enabled and interception_point.drag_and_drop.enabled = true; download, file_upload, print = false (a TextPaste rule enables only the points it needs).
  6. In the tab that was open before the policy arrived, go to chatgpt.com and paste into a text field -- the paste is intercepted. Paste on example.com -- unaffected. (This is the content-process check: before this fix an already-running content process kept the stale "inactive" answer and skipped analysis entirely, so please do not open a fresh tab for this step.)
2. Update I -- edit the rules live
{
  "FallbackResult": "warn",
  "Rules": [
    { "Name": "warn-ai-paste", "Enabled": true, "Actions": ["TextPaste"], "Domains": ["chatgpt.com"], "Type": "warn" },
    { "Name": "block-cloud-upload", "Enabled": true, "Actions": ["FileUpload"], "Domains": ["dropbox.com"], "Type": "block" }
  ]
}

Expected:

  1. dlp_rules now lists both rules; interception_point.file_upload.enabled flips to true, download and print stay false.
  2. default_result and timeout_result both = 1 (warn).
  3. about:support: Request Count continues from its previous value rather than resetting to 0 -- a rules-only edit must not rebuild the engine.
  4. A file upload on dropbox.com is now intercepted; the paste rule still works.
3. Update II -- a disabled rule must not leave its hooks running

Set "Enabled": false on block-cloud-upload, leaving everything else the same.

Expected: interception_point.file_upload.enabled returns to false, uploads on dropbox.com are no longer intercepted, and dlp_rules still contains both rules (the engine applies the Enabled flag itself, so seeing both listed is correct).

4. Update III -- external agent takes over live

Add ContentAnalysis without touching DataLossPrevention (this is the diffing case: only the ContentAnalysis callbacks run, but arbitration is still recomputed from the whole active set):

{
  "ContentAnalysis": {
    "Enabled": true,
    "AgentName": "Acme DLP",
    "PipePathName": "acme_pipe_a"
  },
  "DataLossPrevention": {
    "FallbackResult": "block",
    "Rules": [
      { "Name": "warn-ai-paste", "Enabled": true, "Actions": ["TextPaste"], "Domains": ["chatgpt.com"], "Type": "warn" }
    ]
  }
}

Expected:

  1. use_wasm_backend = false -- the enabled external agent wins over the built-in engine.
  2. dlp_rules is empty: the built-in rules are withdrawn while the agent is authoritative.
  3. Indicator tooltip/panel now read Acme DLP, in both windows, live.
  4. about:support: Agent Path shows the pipe path, Connected to agent = false (no agent is running), Request Count reset to 0 -- the backend was swapped, not reused.
  5. Paste into a field on any page -- Unable to connect to Acme DLP. (the external agent's default interception points are broader than the built-in engine's, so this is expected on example.com too).
5. Update IV -- external connection change vs. an unrelated change
  1. Change PipePathName to acme_pipe_b (everything else identical). Expected: pipe_path_name = acme_pipe_b, still the external agent, and Request Count reset to 0 (connection settings are baked in at construction, so this must rebuild).
  2. Now change only ShowBlockedResult to false. Expected: show_blocked_result = false, and Request Count does not reset -- an unrelated change must not churn the agent connection.
6. Update V -- flip Enabled with both policies present

Set ContentAnalysis.Enabled to false, keeping both policies and their other fields.

Expected: a disabled ContentAnalysis block does not suppress the built-in engine, so use_wasm_backend flips back to true, dlp_rules contains warn-ai-paste again, agent_name is back to Firefox Enterprise DLP Engine (check the tooltip), and Request Count resets to 0. Flipping it back to true returns to Acme DLP. Repeat once or twice -- it must survive repeated flips without a restart.

7. Update VI -- no stale configuration across a provider switch
  1. Set only:
{
  "ContentAnalysis": {
    "Enabled": true,
    "AgentName": "Acme DLP",
    "PipePathName": "acme_pipe_b",
    "AllowUrlRegexList": "https://allowed\\.example\\.com/.*",
    "DenyUrlRegexList": "https://denied\\.example\\.com/.*"
  }
}

Confirm allow_url_regex_list and deny_url_regex_list hold those values.

  1. Now replace the whole set with only the DataLossPrevention policy from case 1.

Expected:

  • use_wasm_backend = true, dlp_rules populated, tooltip = Firefox Enterprise DLP Engine.
  • deny_url_regex_list = empty.
  • allow_url_regex_list = ^about:(?!blank|srcdoc).* -- back to its shipped default, not the agent's value and not empty.
  • pipe_path_name, client_signature, max_connections, is_per_user are unlocked and no longer hold the agent's values.
8. Remove

Remove both ContentAnalysis and DataLossPrevention from the policy set.

Expected:

  1. about:policies#active lists neither.
  2. The indicator is gone from every open window, live.
  3. about:support: Active = false.
  4. about:config: every browser.contentanalysis.* pref is unlocked and back at its default -- enabled = false, dlp_rules empty, agent_name = A DLP agent, allow_url_regex_list = ^about:(?!blank|srcdoc).*. (Note: the interception_point.*.enabled prefs revert to their built-in defaults, most of which are true. That is correct -- nothing is intercepted because enabled is false.)
  5. In the tab that has been open the whole time, paste on chatgpt.com and upload on dropbox.com -- neither is intercepted, and no error notification appears.
9. Regression check -- ContentAnalysis present but disabled, alone

Set only:

{ "ContentAnalysis": { "Enabled": false, "AgentName": "Acme DLP" } }

Expected (pre-existing behavior, must be preserved): enabled = false and locked, use_wasm_backend = false and locked, the rest of the block's config locked at the policy's values, no indicator, nothing intercepted. Removing the policy then unlocks everything as in case 8.

This is a test plan put together by claude. At this point I have only briefly skimmed and edited it. From my initial scan it looks correct, but I will keep the needinfo live here for me to review this more thoroughly.

Thanks @jmendez! Once you think it's good to be tested with, you can flag qe-verify +.

Flags: qe-verify+
QA Contact: pmagyari

Verified fixed using Firefox Enterprise 155.0 (20260828072535) on Windows 11, MacOS 25 and Ubuntu 24 using the attached DLP add-on and setting up a sample content analysis agent then going through the test-cases from comment 5.
Both ContentAnalysis and DataLossPrevention can be added, edited, removed live without a browser restart.

Status: RESOLVED → VERIFIED
Flags: qe-verify+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: