Skip to content

feat: Add UuidRecognizer for detecting UUIDs (v1-v8)#2175

Open
watsos wants to merge 11 commits into
data-privacy-stack:mainfrom
watsos:feature/uuid-recognizer
Open

feat: Add UuidRecognizer for detecting UUIDs (v1-v8)#2175
watsos wants to merge 11 commits into
data-privacy-stack:mainfrom
watsos:feature/uuid-recognizer

Conversation

@watsos

@watsos watsos commented Jul 20, 2026

Copy link
Copy Markdown

Change Description

Adds a new predefined generic recognizer, UuidRecognizer, to detect UUIDs in the
standard 8-4-4-4-12 hyphenated hexadecimal format (entity type UUID).

Describe your changes
Why: Presidio has recognizers for other infrastructure/log-adjacent identifiers
(IpRecognizer, MacAddressRecognizer) but no recognizer for UUIDs, despite them
being a very common identifier in logs, API responses, database keys, and
distributed systems.

Details:

  • Supports RFC 4122 versions 1–5 and RFC 9562 version 7 (timestamp-based)
  • Validates version and variant nibbles in invalidate_result to reduce false
    positives, following the same broad-match-then-validate pattern as
    MacAddressRecognizer
  • Filters the nil UUID (00000000-0000-0000-0000-000000000000) as a
    non-identifying sentinel value
  • Confidence score: 0.5 (rigid format, but non-checksummed)
  • Context words: uuid, guid, unique identifier
  • Added to default_recognizers.yaml (enabled by default, no country_code)
  • Updated CHANGELOG.md under Unreleased

Issue reference

No existing issue — checked open issues for duplicates before starting, none found.

Fixes #XX
None

Checklist

  • I have reviewed the contribution guidelines
  • I agree to follow this project's Code of Conduct
  • I confirm that I have the right to submit this contribution and that it does not knowingly contain proprietary or confidential code.
  • My code includes unit tests
  • All unit tests and lint checks pass locally
  • My PR contains documentation updates / additions if required

Copilot AI review requested due to automatic review settings July 20, 2026 23:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a new predefined generic analyzer recognizer (UuidRecognizer) to detect UUIDs (entity type UUID) in the standard 8-4-4-4-12 hyphenated hex format, with additional validation to reduce false positives.

Changes:

  • Introduces UuidRecognizer with a broad UUID regex + post-match validation for RFC 4122 v1–v5 and RFC 9562 v7 (including variant/version checks and nil-UUID filtering).
  • Registers the new recognizer in the predefined recognizers package and enables it by default via default_recognizers.yaml.
  • Adds unit tests for valid/invalid UUIDs and updates the recognizer registry test count; updates CHANGELOG.md.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
presidio-analyzer/presidio_analyzer/predefined_recognizers/generic/uuid_recognizer.py New UuidRecognizer implementation (pattern + invalidate_result validation).
presidio-analyzer/presidio_analyzer/predefined_recognizers/init.py Exports UuidRecognizer via package imports and __all__.
presidio-analyzer/presidio_analyzer/conf/default_recognizers.yaml Adds UuidRecognizer to default registry configuration (enabled by default).
presidio-analyzer/tests/test_uuid_recognizer.py New unit tests covering UUID versions, context boosting, multiple matches, and invalid cases.
presidio-analyzer/tests/test_recognizer_registry.py Updates expected recognizer count to reflect the added predefined recognizer.
CHANGELOG.md Documents the new recognizer under Analyzer → Added.

Comment on lines +1 to +2
import re
from typing import List, Optional
Comment thread CHANGELOG.md
Comment on lines +8 to +10
#### Added
- Added `UuidRecognizer` (generic, entity type `UUID`) to detect UUIDs in the standard 8-4-4-4-12 hyphenated hexadecimal format, covering RFC 4122 versions 1-5 and RFC 9562 version 7 (timestamp-based). Validates version and variant nibbles and filters the nil UUID to reduce false positives.

Copilot AI review requested due to automatic review settings July 21, 2026 01:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (1)

presidio-analyzer/presidio_analyzer/predefined_recognizers/generic/uuid_recognizer.py:2

  • re is imported but never used; this will fail linting (and is redundant since PatternRecognizer compiles patterns internally).
import re
from typing import List, Optional

Comment on lines +57 to +74
def invalidate_result(self, pattern_text: str) -> bool:
"""
Check if the pattern text is a valid UUID format.

Validates the RFC 4122/9562 version nibble and variant bits to
reduce false positives from arbitrary hex-hyphen strings, and
filters out the nil UUID (all zeros), which is a well-known
sentinel value rather than an identifying value.

:param pattern_text: Text detected as pattern by regex
:return: True if invalidated (invalid or non-identifying UUID)
"""
if pattern_text.lower() == self.NIL_UUID:
return True

groups = pattern_text.split("-")
if len(groups) != 5:
return True
from .generic.mac_recognizer import MacAddressRecognizer
from .generic.phone_recognizer import PhoneRecognizer
from .generic.url_recognizer import UrlRecognizer
from .generic.uuid_recognizer import UuidRecognizer
Comment thread presidio-analyzer/tests/test_uuid_recognizer.py
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 21, 2026 01:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

presidio-analyzer/presidio_analyzer/predefined_recognizers/generic/uuid_recognizer.py:2

  • re is imported but never used in this recognizer; this will fail linting (unused import).
import re
from typing import List, Optional

Copilot AI review requested due to automatic review settings July 21, 2026 01:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment on lines +29 to +35
# Version 1 (time-based)
("Trace: f47ac10b-58cc-1372-8567-0e02b2c3d479",
1, ((7, 43),), ((0.5, 0.5),)),

# Version 5 (SHA-1 name-based)
("Object id 74738ff5-5367-5958-9aee-98fffdcd1876 created",
1, ((10, 46),), ((0.5, 0.5),)),
Copilot AI review requested due to automatic review settings July 21, 2026 02:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

presidio-analyzer/tests/test_uuid_recognizer.py:26

  • This UUID sample is v3 (the version nibble is 3 in 3ca4), but it’s grouped under the “Version 4 (random)” section; update it to a v4 UUID (or move it to a v3 section) so the test case matches the comment.
        ("User UUID: 6fa459ea-ee8a-3ca4-894e-db77e160355e",

Copilot AI review requested due to automatic review settings July 22, 2026 02:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

presidio-analyzer/tests/test_uuid_recognizer.py:27

  • The comment labels the second example as “Version 4”, but the UUID 6fa459ea-ee8a-3ca4-894e-db77e160355e is version 3 (the version nibble is 3). Updating the test comment avoids misleading future debugging/maintenance.
        # Version 4 (random) - most common
        ("Request ID: 550e8400-e29b-41d4-a716-446655440000",
         1, ((12, 48),), ((0.5, 0.5),)),
        ("User UUID: 6fa459ea-ee8a-3ca4-894e-db77e160355e",
         1, ((11, 47),), ((0.5, 0.5),)),

@SharonHart

Copy link
Copy Markdown
Contributor

@watsos care looking into the comments?
Also, is there any motivation behind skipping v6 and v8?

Copilot AI review requested due to automatic review settings July 23, 2026 14:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Comment on lines +10 to +15
Supports the standard 8-4-4-4-12 hyphenated hexadecimal format for
UUID versions 1-8: versions 1-5 (RFC 4122, including the nil UUID
special case), version 6 (RFC 9562, reordered time-based), version 7
(RFC 9562, unix timestamp-based, increasingly common in modern
distributed systems, databases, and logs), and version 8
(RFC 9562, vendor/implementation-specific).
Comment thread docs/supported_entities.md Outdated
|PHONE_NUMBER|A telephone number. The `PhoneRecognizer` can be extended programmatically for country-specific detection by configuring `supported_regions` and `supported_entity` (e.g. Philippines: `PhoneRecognizer(supported_regions=["PH"], supported_entity="PH_MOBILE_NUMBER")`, Turkey: `PhoneRecognizer(supported_regions=["TR"], supported_entity="TR_PHONE_NUMBER")`)|Custom logic, pattern match and context|
|MEDICAL_LICENSE|Common medical license numbers.|Pattern match, context and checksum|
|URL|A URL (Uniform Resource Locator), unique identifier used to locate a resource on the Internet|Pattern match, context and top level url validation|
|UUID|A Universally Unique Identifier (UUID) in the standard 8-4-4-4-12 hyphenated hexadecimal format. Covers RFC 4122 versions 1-5 and RFC 9562 versions 6-8.|Pattern match, validation of version/variant nibbles, and context|
Comment thread CHANGELOG.md

### Analyzer
#### Added
- Added `UuidRecognizer` (generic, entity type `UUID`) to detect UUIDs in the standard 8-4-4-4-12 hyphenated hexadecimal format, covering RFC 4122 versions 1-5 and RFC 9562 versions 6-8. Validates version and variant nibbles and filters the nil UUID to reduce false positives.
@watsos

watsos commented Jul 23, 2026

Copy link
Copy Markdown
Author

Good catch — no principled reason, that was just an oversight in the original scope. Just pushed a fix adding both:

v6 (RFC 9562, reordered time-based, better DB index locality than v1)
v8 (RFC 9562, vendor/implementation-specific)

Updated VALID_VERSIONS to {1-8}, added test cases for both, and updated the docstring/changelog/docs to reflect full 1-8 coverage.

Copilot AI review requested due to automatic review settings July 23, 2026 14:32
@watsos watsos changed the title feat: Add UuidRecognizer for detecting UUIDs (v1-v5, v7) feat: Add UuidRecognizer for detecting UUIDs (v1-v8) Jul 23, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (3)

presidio-analyzer/tests/test_uuid_recognizer.py:27

  • This UUID sample is labeled under the "Version 4" section, but the UUID version nibble here is 3 (third group starts with 3ca4), so the test data/comment are inconsistent; either update the comment or change this UUID to a v4 example.
        ("User UUID: 6fa459ea-ee8a-3ca4-894e-db77e160355e",
         1, ((11, 47),), ((0.5, 0.5),)),

presidio-analyzer/presidio_analyzer/predefined_recognizers/generic/uuid_recognizer.py:15

  • The class docstring says UUID v1-5 support includes the "nil UUID special case", but this recognizer intentionally filters the nil UUID out as non-identifying; clarify the docstring so it doesn’t read like the nil UUID is returned as a detected entity.
    RFC 4122 UUID versions 1-5 and RFC 9562 versions 6-8.

    Note: the nil UUID (00000000-0000-0000-0000-000000000000) is explicitly
    excluded as a non-identifying sentinel value.

CHANGELOG.md:9

  • The PR title/description states support for UUID v1–v5 and v7 only, but the code/tests/docs/changelog indicate support for RFC 9562 v6–v8 as well. Please align the PR description/title (or, if v6/v8 aren’t intended, remove that support consistently across code/tests/docs).
- Added `UuidRecognizer` (generic, entity type `UUID`) to detect UUIDs in the standard 8-4-4-4-12 hyphenated hexadecimal format, covering RFC 4122 versions 1-5 and RFC 9562 versions 6-8. Validates version and variant nibbles and filters the nil UUID to reduce false positives.

Comment on lines +99 to +102
assert len(results) == expected_len
for res, (st_pos, fn_pos), (st_score, fn_score) in zip(
results, expected_positions, expected_score_ranges
):

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — added explicit length assertions for expected_positions and expected_score_ranges before the zip loop. Pushed in edf3067.

Copilot AI review requested due to automatic review settings July 23, 2026 14:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comment on lines +57 to +58
# 1 custom recognizer in english + 29 predefined - 11 disabled
assert len(recognizers) == 1 + 29 - 11
Copilot AI review requested due to automatic review settings July 23, 2026 14:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

presidio-analyzer/tests/test_recognizer_registry.py:58

  • This assertion hard-codes the total number of predefined/disabled recognizers, so it will keep needing manual updates whenever a recognizer is added/removed; assert on specific expected inclusions/exclusions (e.g., the custom recognizer is present, a known disabled recognizer is absent, and the new UuidRecognizer is loaded) to make the test stable.
    # 1 custom recognizer in english + 29 predefined - 11 disabled
    assert len(recognizers) == 1 + 29 - 11

Comment on lines +33 to +36
# Version 2 (DCE Security, RFC 4122)
("DCE UUID: 550e8400-e29b-21d4-a716-446655440000",
1, ((10, 46),), ((0.5, 0.5),)),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants