Skip to content

Conversation

@chl0rum
Copy link
Contributor

@chl0rum chl0rum commented Dec 25, 2025

No description provided.

@github-actions github-actions bot added the type/feat New features label Dec 25, 2025
@ovsds ovsds requested a review from Copilot December 25, 2025 20:06
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new base obfuscator package (dl_obfuscator) that provides functionality for obfuscating sensitive data like secrets and query parameters in various contexts (logs, Sentry, tracing, usage tracking, and inspector).

Key Changes:

  • New dl_obfuscator package with core obfuscation engine and secret keeper registry
  • Support for context-aware obfuscation (different rules for logs vs. inspector)
  • Extensible architecture with base obfuscator class for custom implementations

Reviewed changes

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

Show a summary per file
File Description
metapkg/pyproject.toml Adds dl-obfuscator to the metapackage dependencies
lib/dl_obfuscator/pyproject.toml Package configuration defining dependencies and test settings
lib/dl_obfuscator/dl_obfuscator/secret_keeper.py Registry for storing secrets and query parameters to be obfuscated
lib/dl_obfuscator/dl_obfuscator/engine.py Core obfuscation engine with text and dict processing methods
lib/dl_obfuscator/dl_obfuscator/context.py Enum defining obfuscation contexts (logs, sentry, tracing, etc.)
lib/dl_obfuscator/dl_obfuscator/obfuscators/base.py Abstract base class for custom obfuscators
lib/dl_obfuscator/dl_obfuscator/init.py Package initialization with public API exports
lib/dl_obfuscator/dl_obfuscator_tests/unit/test_secret_keeper.py Unit tests for SecretKeeper functionality
lib/dl_obfuscator/dl_obfuscator_tests/unit/test_engine.py Unit tests for ObfuscationEngine behavior
lib/dl_obfuscator/dl_obfuscator_tests/unit/conftest.py Pytest fixtures for tests
lib/dl_obfuscator/README.md Basic package documentation
lib/dl_obfuscator/LICENSE Apache 2.0 license file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@ovsds ovsds requested a review from Copilot December 30, 2025 12:03
Copy link
Contributor

Copilot AI left a comment

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 13 out of 17 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +17 to +21
_obfuscators: list[BaseObfuscator] = attr.ib(factory=list, init=False)

def __init__(self, secret_keeper: SecretKeeper, obfuscators: list[BaseObfuscator] | None = None):
self.secret_keeper = secret_keeper
self._obfuscators = obfuscators or []
Copy link

Copilot AI Dec 30, 2025

Choose a reason for hiding this comment

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

The class uses @attr.s decorator but defines a custom __init__ method that bypasses attrs' generated initialization. This conflicts with the attr.ib() field definitions on lines 16-17. Either remove the @attr.s decorator and field definitions, or remove the custom __init__ and use attrs' initialization pattern with factory functions.

Suggested change
_obfuscators: list[BaseObfuscator] = attr.ib(factory=list, init=False)
def __init__(self, secret_keeper: SecretKeeper, obfuscators: list[BaseObfuscator] | None = None):
self.secret_keeper = secret_keeper
self._obfuscators = obfuscators or []
obfuscators: list[BaseObfuscator] | None = attr.ib(default=None, repr=False)
_obfuscators: list[BaseObfuscator] = attr.ib(init=False, repr=False)
def __attrs_post_init__(self) -> None:
# Mirror the original __init__ behavior: if obfuscators is None, use an empty list.
self._obfuscators = self.obfuscators or []

Copilot uses AI. Check for mistakes.
Comment on lines +8 to +12
# Core components
"SecretKeeper",
"ObfuscationContext",
"ObfuscationEngine",
# Obfuscators
Copy link
Contributor

Choose a reason for hiding this comment

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

let's not add comments in all block, it will be autosorted later on

@@ -0,0 +1,13 @@
import abc

from ..context import ObfuscationContext
Copy link
Contributor

Choose a reason for hiding this comment

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

relative import ourside __init__.py is a bad idea by default

Comment on lines +27 to +33
def apply_replacement(text: str, secret_items: tuple[str, str]) -> str:
secret, replacement = secret_items
escaped_value = re.escape(secret)
pattern = rf"\b{escaped_value}\b"
replacement = replacement or "hidden"
replacement = f"***{replacement}***"
return re.sub(pattern, replacement, text)
Copy link
Contributor

Choose a reason for hiding this comment

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

why is it enclosed?

if context != ObfuscationContext.INSPECTOR:
secrets.extend(self.secret_keeper.get_params().items())

result = reduce(apply_replacement, secrets, text)
Copy link
Contributor

Choose a reason for hiding this comment

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

let's unwrap, reduce is not the most readable way to define things

Comment on lines +53 to +54
else:
result[key] = value
Copy link
Contributor

@ovsds ovsds Dec 30, 2025

Choose a reason for hiding this comment

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

else not obfuscating? sounds wrong

elif isinstance(data, dict):
return self.obfuscate_dict(data, context)
else:
return data
Copy link
Contributor

Choose a reason for hiding this comment

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

else not obfuscating? sounds wrong

Comment on lines +8 to +9
_secrets: dict[str, str] = attr.ib(factory=dict, init=False, repr=False)
_params: dict[str, str] = attr.ib(factory=dict, init=False, repr=False)
Copy link
Contributor

Choose a reason for hiding this comment

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

why init false?

pattern = rf"\b{escaped_value}\b"
replacement = replacement or "hidden"
replacement = f"***{replacement}***"
return re.sub(pattern, replacement, text)
Copy link
Contributor

Choose a reason for hiding this comment

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

using re.sub for string replacement is overkill, str.replace should be faster

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

Labels

type/feat New features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants