Split out of issue #3616540, whose own scope — finite read budgets (2.7.0) and classification/destination egress policy (2.9.0) — is complete and released. The design pass for that issue named this as slice C and said it may become its own issue; recording it here rather than leaving it implied.
GitHub working mirror: https://github.com/Wilkes-Liberty/mcp_sentinel/issues/136
PROBLEM / MOTIVATION
Two gaps remain between what DLP does today and what a classification-aware stack should do.
First, DLP does not know about classification. A DLP pattern can detect a value class (an SSN, a card number) but cannot say "this is restricted", so a detector hit and an egress ceiling are unrelated decisions. A pattern that names a label would let a detected value tighten the effective ceiling for the response it appears in.
Second, DLP's coverage is narrower than the claim it invites. The service's own scope note is explicit: value-pattern scanning applies to governed GraphQL field results and to audit change diffs, and nothing else. JSON:API, REST, Tool and context responses are not scanned. That gap is honest in the code and should be either closed or stated in the product surfaces.
PROPOSED RESOLUTION
Tighten-only integration: a DLP hit may lower the effective egress ceiling for the response it appears in, and may never raise it. Then extend value scanning to the remaining governed read paths, or record explicitly which paths it does not cover and why.
The structural obstacle for JSON:API and REST is already named in the DLP service: hook_entity_field_access can only deny, not rewrite, and Drupal's normalizer stack has no stable per-value alter hook. The honest options there are refusal rather than masking, a normalizer decorator, or a documented residual — settling that choice is the first task of this issue.
ACCEPTANCE CRITERIA
- A DLP pattern may declare a classification label, and a hit tightens the effective ceiling for that response; it can never widen one.
- Coverage on each governed read path is either implemented or recorded as a named residual in the module documentation. No path is silently unscanned while the product surface implies otherwise.
- Denials and maskings keep the existing stable reason codes and bounded, non-sensitive evidence.
- Tests cover a hit that tightens, a hit that cannot widen, and each path's actual behaviour in both directions.
API CHANGES
dlp_patterns entries gain an optional classification label. No change to existing pattern semantics when the key is absent.
Comments
Comment #14
jmcerdaReleased in 2.13.0 (commit 2ed09dd on 1.x). Marking Fixed.
A dlp_patterns row may declare an optional classification label. A hit may lower the effective egress ceiling and never raise it. GraphQL field results and Tool success context are scanned; path tests prove Tool tighten, at-ceiling mask, and cannot-widen. JSON:API, REST, the context schema document, and governed drush SQL remain named residuals (dlp_jsonapi_unscanned, dlp_rest_unscanned, dlp_context_unscanned, dlp_drush_unscanned). Residual scanners stay out of scope.
https://www.drupal.org/project/mcp_sentinel/releases/2.13.0
Comment #16
jmcerdaReleased in 2.13.0 (commit 2ed09dd on 1.x). Marking Fixed.
A dlp_patterns row may declare an optional classification label. A hit may lower the effective egress ceiling and never raise it. GraphQL field results and Tool success context are scanned; path tests prove Tool tighten, at-ceiling mask, and cannot-widen. JSON:API, REST, the context schema document, and governed drush SQL remain named residuals (dlp_jsonapi_unscanned, dlp_rest_unscanned, dlp_context_unscanned, dlp_drush_unscanned). Residual scanners stay out of scope.
https://www.drupal.org/project/mcp_sentinel/releases/2.13.0