fix(vector-store): stop writing service account private key to DEBUG logs in GoogleMatchingEngine (#7506)

Co-authored-by: rupak-eng <rupak-eng@users.noreply.github.com>
This commit is contained in:
rupak
2026-10-07 16:20:38 +05:30
committed by GitHub
parent 0516f19f72
commit d62ce07fac
2 changed files with 35 additions and 2 deletions
@@ -34,7 +34,7 @@ class OutputData(BaseModel):
class GoogleMatchingEngine(VectorStoreBase): class GoogleMatchingEngine(VectorStoreBase):
def __init__(self, **kwargs): def __init__(self, **kwargs):
"""Initialize Google Matching Engine client.""" """Initialize Google Matching Engine client."""
logger.debug("Initializing Google Matching Engine with kwargs: %s", kwargs) logger.debug("Initializing Google Matching Engine with config keys: %s", sorted(kwargs))
# If collection_name is passed, use it as deployment_index_id if deployment_index_id is not provided # If collection_name is passed, use it as deployment_index_id if deployment_index_id is not provided
if "collection_name" in kwargs and "deployment_index_id" not in kwargs: if "collection_name" in kwargs and "deployment_index_id" not in kwargs:
@@ -46,7 +46,7 @@ class GoogleMatchingEngine(VectorStoreBase):
try: try:
config = GoogleMatchingEngineConfig(**kwargs) config = GoogleMatchingEngineConfig(**kwargs)
logger.debug("Config created: %s", config.model_dump()) logger.debug("Config created with fields: %s", sorted(config.model_dump()))
logger.debug("Config collection_name: %s", getattr(config, "collection_name", None)) logger.debug("Config collection_name: %s", getattr(config, "collection_name", None))
except Exception as e: except Exception as e:
logger.error("Failed to validate config: %s", str(e)) logger.error("Failed to validate config: %s", str(e))
@@ -1,3 +1,4 @@
import logging
from unittest.mock import Mock, patch from unittest.mock import Mock, patch
import pytest import pytest
@@ -165,3 +166,35 @@ def test_error_handling(vector_store, mock_vertex_ai):
assert isinstance(exc_info.value, exceptions.InvalidArgument) assert isinstance(exc_info.value, exceptions.InvalidArgument)
assert "Invalid request" in str(exc_info.value) assert "Invalid request" in str(exc_info.value)
def test_debug_logs_never_carry_service_account_key(caplog):
"""Regression for #7503: constructor DEBUG lines must not log the inline credential.
The constructor emits the whole kwargs dict and the validated config dump at
DEBUG; when ``service_account_json`` is passed inline that writes the PEM
private key to the log sink. Constructor diagnostics should name the fields,
never their values.
"""
private_key = "-----BEGIN PRIVATE KEY-----\nFAKE-KEY-MATERIAL-FOR-TEST\n-----END PRIVATE KEY-----\n"
kwargs = {
"project_id": "test-project",
"project_number": "123456789",
"region": "us-central1",
"endpoint_id": "test-endpoint",
"index_id": "test-index",
"deployment_index_id": "test-deployment",
"service_account_json": {"type": "service_account", "private_key": private_key},
}
with caplog.at_level(logging.DEBUG, logger="mem0.vector_stores.vertex_ai_vector_search"):
# Fails later at credential load (no network, no valid key); the two
# DEBUG statements under test run before that.
with pytest.raises(Exception):
GoogleMatchingEngine(**kwargs)
logged = caplog.text
assert private_key not in logged
assert "FAKE-KEY-MATERIAL-FOR-TEST" not in logged
# The diagnostics must stay useful: field names are still logged.
assert "service_account_json" in logged