Skip to content

Commit a27ce47

Browse files
haiyuan-eng-googlecopybara-github
authored andcommitted
fix(adk): redact credentials in BigQuery analytics plugin
Fixes an issue where the Agent Analytics plugin could log plain-text OAuth credentials and access tokens to BigQuery. Sensitive keys are now redacted. Co-authored-by: Haiyuan Cao <haiyuan@google.com> PiperOrigin-RevId: 891963630
1 parent add8e86 commit a27ce47

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/google/adk/plugins/bigquery_agent_analytics_plugin.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,24 @@ def _get_tool_origin(tool: "BaseTool") -> str:
208208
return "UNKNOWN"
209209

210210

211+
_SENSITIVE_KEYS = frozenset({
212+
"client_secret",
213+
"access_token",
214+
"refresh_token",
215+
"id_token",
216+
"api_key",
217+
"password",
218+
})
219+
220+
211221
def _recursive_smart_truncate(
212222
obj: Any, max_len: int, seen: Optional[set[int]] = None
213223
) -> tuple[Any, bool]:
214224
"""Recursively truncates string values within a dict or list.
215225
226+
Redacts sensitive keys corresponding to OAuth tokens and secrets
227+
prior to serialization into BigQuery JSON strings.
228+
216229
Args:
217230
obj: The object to truncate.
218231
max_len: Maximum length for string values.
@@ -251,6 +264,12 @@ def _recursive_smart_truncate(
251264
# but explicit loop is fine for clarity given recursive nature.
252265
new_dict = {}
253266
for k, v in obj.items():
267+
if isinstance(k, str):
268+
k_lower = k.lower()
269+
if k_lower in _SENSITIVE_KEYS or k_lower.startswith("temp:"):
270+
new_dict[k] = "[REDACTED]"
271+
continue
272+
254273
val, trunc = _recursive_smart_truncate(v, max_len, seen)
255274
if trunc:
256275
truncated_any = True

tests/unittests/plugins/test_bigquery_agent_analytics_plugin.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,39 @@ class LocalIncident:
384384
assert truncated["result"]["kpi_missed"][0]["kpi"] == "latency"
385385

386386

387+
def test_recursive_smart_truncate_redaction():
388+
"""Test that sensitive keys and temp: state keys are redacted."""
389+
obj = {
390+
"client_secret": "super-secret-123",
391+
"access_token": "ya29.blah",
392+
"refresh_token": "1//0g",
393+
"id_token": "eyJhb",
394+
"api_key": "AIza",
395+
"password": "my-password",
396+
"safe_key": "safe-value",
397+
"temp:auth_state": "some-auth-state",
398+
"nested": {
399+
"CLIENT_SECRET": "nested-secret",
400+
"normal": "value",
401+
},
402+
}
403+
max_len = 1000
404+
truncated, is_truncated = (
405+
bigquery_agent_analytics_plugin._recursive_smart_truncate(obj, max_len)
406+
)
407+
assert not is_truncated
408+
assert truncated["client_secret"] == "[REDACTED]"
409+
assert truncated["access_token"] == "[REDACTED]"
410+
assert truncated["refresh_token"] == "[REDACTED]"
411+
assert truncated["id_token"] == "[REDACTED]"
412+
assert truncated["api_key"] == "[REDACTED]"
413+
assert truncated["password"] == "[REDACTED]"
414+
assert truncated["safe_key"] == "safe-value"
415+
assert truncated["temp:auth_state"] == "[REDACTED]"
416+
assert truncated["nested"]["CLIENT_SECRET"] == "[REDACTED]"
417+
assert truncated["nested"]["normal"] == "value"
418+
419+
387420
class TestBigQueryAgentAnalyticsPlugin:
388421
"""Tests for the BigQueryAgentAnalyticsPlugin."""
389422

0 commit comments

Comments
 (0)