Skip to content

fix: added squelch and no-pii annotation check - #551

Open
Akanshu-2u wants to merge 16 commits into
openedx:masterfrom
Akanshu-2u:aaich/pii-squelch-annotation
Open

fix: added squelch and no-pii annotation check#551
Akanshu-2u wants to merge 16 commits into
openedx:masterfrom
Akanshu-2u:aaich/pii-squelch-annotation

Conversation

@Akanshu-2u

@Akanshu-2u Akanshu-2u commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Description:

PII variables (e.g. email, username, full_name) could silently leak into logs, print statements, or exceptions with no automated guardrail. Stale .. no_pii: annotations on Django models also went undetected.

Solution:

  • Replaced vague words (name, ip, image) with specific ones (full_name, ip_address, profile_image) so common variable names don't trigger false alerts.
  • Added 21 known-safe field names (e.g., service_username, email_enabled, attr_full_name, location) to an ignore list so they are always skipped.
  • Updated the same lists in 3 places: the plugin code, the runtime defaults, and the pylintrc template — so nothing goes out of date.
  • New test cases lock in this behavior so these false positives can never come back.
  • A field literally named email (but it's actually a BooleanField) still flags. Developers just need to add one inline comment to silence it:
python
# pylint: disable=pii-invalid-no-pii-annotation

Private JIRA Ticket:

BOMS-587

Comment thread edx_lint/files/pylintrc Outdated

# Comma-separated list of identifier substrings treated as likely PII.
# Substring matching is used, so 'email' will match 'user_email_address'.
pii-terms=email,secondary_email,username,retired_username,password,full_name,first_name,last_name,phone,phone_number,birth_date,ip_address,location,address,mailing_address,gender,profile_image,job_title,social_link

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Format it for better readability.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

addressed.

Comment thread edx_lint/files/pylintrc Outdated

# Comma-separated list of identifier substrings treated as likely PII.
# Substring matching is used, so 'email' will match 'user_email_address'.
pii-terms=email,secondary_email,username,retired_username,password,full_name,first_name,last_name,phone,phone_number,birth_date,ip_address,location,address,mailing_address,gender,profile_image,job_title,social_link

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

can you recheck if retired_username is considered as PII?

Comment thread edx_lint/pylint/pii_annotation_check.py Outdated
class PiiAnnotationChecker(PiiConfigMixin, BaseChecker):
"""
Fires ``pii-invalid-no-pii-annotation`` (W7633) when a concrete Django model

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: Remove this black line

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

removed.

Comment thread edx_lint/pylint/pii_squelch_check.py Outdated
Comment on lines +71 to +72


Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Nit: Two blank lines here, Remove it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

removed.

Comment thread CHANGELOG.rst
Unreleased
~~~~~~~~~~

6.2.0 - 2026-06-26

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Just double checking, This jumps straight from 5.7.0 to 6.2.0, with no 6.0.0 or 6.1.0, Is this normal?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

6.0.0 and 6.1.0 were previous releases that simply weren't documented in the CHANGELOG. So 6.2.0 here is correct, the jump in the CHANGELOG is just a documentation gap from earlier releases, not a versioning error.

"job_title",
"social_link",
])
self._pii_terms_cache = [t.strip().lower() for t in raw_terms if t.strip()]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

use identifiable name instead of t

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed this and related ones also.

"attr_email", "default_email", "skip_email_verification",
"location", "_location", "example_full_name"
])
self._safe_keys_cache = {k.strip().lower() for k in raw_keys if k.strip()}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

same here. Rename K to identifiable name and other places also

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed this and related ones also.

Comment thread edx_lint/files/pylintrc Outdated
default_email,
skip_email_verification,
location,
_location,

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.

We should remove location/_location from this list.

Comment thread edx_lint/files/pylintrc Outdated
email,
secondary_email,
username,
retired_username,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Remove retired_username, as it is non-traceable and does not follow the OEP-30 validation.

Comment thread edx_lint/files/pylintrc Outdated
attr_email,
default_email,
skip_email_verification,
location,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Check whether it has to be part of PII-terms as its flagged as PII in OEP-30 doc.

Comment thread edx_lint/pylint/_pii_common.py Outdated
_NO_PII_COMMENT_RE = re.compile(r"[\s]*#[\s]*\.\.\s*no_pii", re.IGNORECASE)

# Lines above ``class`` to scan for a comment-style annotation.
_ANNOTATION_LOOKAHEAD = 5

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Increase it to 10, so that detection of pii and no_pii terms doesn't get missed out if description length increases.

Comment thread edx_lint/pylint/_pii_common.py Outdated
# OEP-0030 PII identifier substrings — substring-matched against variable names.
_DEFAULT_PII_TERMS = [
"email", "secondary_email",
"username", "retired_username",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Remove retired_username from this place. And consider looking at other places also if exists.

Comment thread edx_lint/pylint/_pii_common.py Outdated
},
),
(
"pii-django-model-bases",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For reviewers: Historical models are not considered in this PR. This will be an incremental/next phase change.

Comment thread edx_lint/pylint/_pii_common.py Outdated

def _test_references_flag(self, test, flag):
"""
Return True if AST node *test* references the squelch *flag*.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

reorganize the pattern number to reduce traversal . The most frequestly used patterns must be placed on top.

Comment thread edx_lint/pylint/_pii_common.py Outdated
"""
Recursively inspect *node*; return the first PII term found, or None.
Checks Name, Attribute, f-strings, binary ops, dicts, and nested calls.
String literals are NOT checked.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

There are a lot of ifs and elifs here, so try using switch case instead.

Comment thread edx_lint/pylint/_pii_common.py Outdated
if ancestor.name in model_bases:
is_model_subclass = True
break
except Exception: # pylint: disable=broad-except

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Check if pylint inline comment is required, if not please remove.
Check if we can log the exception raised.

Comment thread edx_lint/files/pylintrc

# Exact identifiers that superficially match PII terms but are approved
# as non-sensitive (surrogate keys, flag fields, system fields).
pii-safe-key-patterns =

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Remove the pii terms and just keep prefix or suffix. Ex: user_id, remove user and safe key will be _id .

Comment thread edx_lint/files/pylintrc Outdated
Comment on lines +523 to +541
pii-terms =
email,
secondary_email,
username,
retired_username,
password,
full_name,
first_name,
last_name,
phone,
phone_number,
birth_date,
ip_address,
address,
mailing_address,
gender,
profile_image,
job_title,
social_link

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.

Suggested change
pii-terms =
email,
secondary_email,
username,
retired_username,
password,
full_name,
first_name,
last_name,
phone,
phone_number,
birth_date,
ip_address,
address,
mailing_address,
gender,
profile_image,
job_title,
social_link
```suggestion : Because matching uses substring containment, several terms are redundant.
_DEFAULT_PII_TERMS = (
"email",
"username",
"password",
"full_name",
"first_name",
"last_name",
"phone",
"birth_date",
"ip_address",
"address",
"gender",
"profile_image",
"job_title",
"social_link",
)

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.

4 participants