This is an automated email from the ASF dual-hosted git repository. cgivre pushed a commit to branch feat/drill-mcp-server in repository https://gitbox.apache.org/repos/asf/drill-mcp.git
commit 1ca6f4dd1936be6b48578f045a73a45f38e702ac Author: cgivre <[email protected]> AuthorDate: Tue Aug 11 16:20:43 2026 -0400 fix: restore broad credential pattern and fix test contradiction - Restore broad 'credential' pattern (remove negative lookahead that excluded credentialsJson, credentialsB64, etc) - Fix test_recurses_into_nested_dicts to use neutral 'aws' container instead of credentialsProvider - Add tests for credentialsProvider, credentialsJson, credentialsB64, credentialsProviderType (GCS key shapes) - Expand pattern to include authorization, passphrase, keytab, principal - Add tests for new pattern additions - Add tuple return type test for complete coverage --- drill_mcp/redact.py | 5 ++--- tests/test_redact.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/drill_mcp/redact.py b/drill_mcp/redact.py index a85e041..93cad99 100644 --- a/drill_mcp/redact.py +++ b/drill_mcp/redact.py @@ -33,10 +33,9 @@ REDACTED = "***REDACTED***" # Matches anywhere in the key, so `fs.s3a.secret.key` and `awsSecretAccessKey` # are both caught. Deliberately broad: a false redaction is a cosmetic problem, -# a missed one is a leaked credential. Uses negative lookahead on credential(s) -# to avoid matching keys like "credentialsProvider" where it's part of a longer word. +# a missed one is a leaked credential. _SENSITIVE = re.compile( - r"password|passwd|secret|credentials?(?![a-z])|token|access[._-]?key|private[._-]?key|api[._-]?key", + r"password|passwd|secret|credential|token|access[._-]?key|private[._-]?key|api[._-]?key|authorization|passphrase|keytab|principal", re.IGNORECASE, ) diff --git a/tests/test_redact.py b/tests/test_redact.py index bcbf637..174bda0 100644 --- a/tests/test_redact.py +++ b/tests/test_redact.py @@ -49,8 +49,8 @@ def test_leaves_innocuous_keys_alone(): def test_recurses_into_nested_dicts(): - source = {"config": {"credentialsProvider": {"awsSecretAccessKey": "s"}}} - assert redact(source)["config"]["credentialsProvider"]["awsSecretAccessKey"] == REDACTED + source = {"config": {"aws": {"awsSecretAccessKey": "s"}}} + assert redact(source)["config"]["aws"]["awsSecretAccessKey"] == REDACTED def test_recurses_into_lists(): @@ -95,3 +95,50 @@ def test_realistic_s3_plugin_config(): assert inner["fs.s3a.secret.key"] == REDACTED assert inner["fs.s3a.endpoint"] == "s3.amazonaws.com" assert result["config"]["workspaces"]["root"]["location"] == "/" + + +def test_redacts_credentials_provider_wholly(): + source = {"credentialsProvider": {"clientID": "x"}} + assert redact(source)["credentialsProvider"] == REDACTED + + +def test_redacts_gcs_credentials_json(): + source = {"credentialsJson": '{"type": "service_account", "private_key": "..."}'} + assert redact(source)["credentialsJson"] == REDACTED + + +def test_redacts_credentials_b64(): + source = {"credentialsB64": "base64encodedkey"} + assert redact(source)["credentialsB64"] == REDACTED + + +def test_redacts_credentials_provider_type(): + source = {"credentialsProviderType": "com.amazonaws.auth.DefaultAWSCredentialsProviderChain"} + assert redact(source)["credentialsProviderType"] == REDACTED + + +def test_redacts_authorization_header(): + source = {"Authorization": "Bearer token123"} + assert redact(source)["Authorization"] == REDACTED + + +def test_redacts_passphrase(): + source = {"passphrase": "secret"} + assert redact(source)["passphrase"] == REDACTED + + +def test_redacts_keytab(): + source = {"keytab": "/path/to/user.keytab"} + assert redact(source)["keytab"] == REDACTED + + +def test_redacts_principal(): + source = {"principal": "user@REALM"} + assert redact(source)["principal"] == REDACTED + + +def test_passes_through_tuples(): + source = ({"password": "x"},) + result = redact(source) + assert isinstance(result, tuple) + assert result[0]["password"] == REDACTED
