Skip to content

Commit 3809157

Browse files
fixed logging of sensitive data
1 parent 60d2ab1 commit 3809157

File tree

2 files changed

+94
-16
lines changed

2 files changed

+94
-16
lines changed

src/sagemaker/config/config_utils.py

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -69,29 +69,19 @@ def _log_sagemaker_config_single_substitution(source_value, config_value, config
6969
"""
7070
logger = get_sagemaker_config_logger()
7171

72-
# sensitive_keywords = re.compile(r'(secret|password|key)', re.IGNORECASE)
73-
7472
source_value_log_copy = deepcopy(source_value)
7573
config_value_log_copy = deepcopy(config_value)
7674

7775

78-
# if isinstance(source_value_log_copy, dict):
79-
# for key in source_value_log_copy.keys():
80-
# if re.search(r'(secret|password|key)', key, re.IGNORECASE):
81-
# source_value_log_copy[key] = '***'
82-
#
83-
# if isinstance(config_value_log_copy, dict):
84-
# for key in config_value_log_copy.keys():
85-
# if re.search(r'(secret|password|key)', key, re.IGNORECASE):
86-
# config_value_log_copy[key] = '***'
87-
8876
if isinstance(source_value_log_copy, dict):
8977
for key in source_value_log_copy.keys():
90-
source_value_log_copy[key] = '***'
78+
if re.search(r'(secret|password|key)', key, re.IGNORECASE):
79+
source_value_log_copy[key] = '***'
9180

9281
if isinstance(config_value_log_copy, dict):
93-
for key in config_value_log_copy.keys():
94-
config_value_log_copy[key] = '***'
82+
for k in config_value_log_copy.keys():
83+
if re.search(r'(secret|password|key)', k, re.IGNORECASE):
84+
config_value_log_copy[k] = '***'
9585

9686
if config_value is not None:
9787

@@ -105,7 +95,7 @@ def _log_sagemaker_config_single_substitution(source_value, config_value, config
10595
logger.debug(
10696
"Applied value\n config key = %s\n config value that will be used = %s",
10797
config_key_path,
108-
config_value,
98+
config_value_log_copy,
10999
)
110100
else:
111101
logger.info(

tests/unit/test_utils.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from __future__ import absolute_import
1616

1717
import copy
18+
import logging
1819
import shutil
1920
import tarfile
2021
from datetime import datetime
@@ -59,6 +60,8 @@
5960
_validate_new_tags,
6061
remove_tag_with_key,
6162
)
63+
64+
from src.sagemaker.config.config_utils import _log_sagemaker_config_single_substitution
6265
from tests.unit.sagemaker.workflow.helpers import CustomStep
6366
from sagemaker.workflow.parameters import ParameterString, ParameterInteger
6467

@@ -1279,6 +1282,91 @@ def test_resolve_value_from_config():
12791282
mock_info_logger.reset_mock()
12801283

12811284

1285+
class TestLogSagemakerConfig(TestCase):
1286+
1287+
def test_sensitive_info_masking(self):
1288+
logger = logging.getLogger('sagemaker.config')
1289+
logger.setLevel(logging.DEBUG)
1290+
1291+
stream_handler = logging.StreamHandler()
1292+
logger.addHandler(stream_handler)
1293+
1294+
# source value is None
1295+
with self.assertLogs(logger, level='DEBUG') as log:
1296+
_log_sagemaker_config_single_substitution(
1297+
None,
1298+
{"apiKey": "topsecretkey"},
1299+
"config/path"
1300+
)
1301+
1302+
self.assertIn("config value that will be used = {'apiKey': '***'}", log.output[0])
1303+
1304+
# source value is None and config_value == source_value
1305+
with self.assertLogs(logger, level='DEBUG') as log:
1306+
_log_sagemaker_config_single_substitution(
1307+
{"secretword": "topsecretword"},
1308+
{"secretword": "topsecretword"},
1309+
"config/path"
1310+
)
1311+
1312+
self.assertIn("Skipped value", log.output[0])
1313+
self.assertIn("source value that will be used = {'secretword': '***'}", log.output[0])
1314+
self.assertIn("config value = {'secretword': '***'}", log.output[0])
1315+
1316+
# source value is not None and config_value != source_value
1317+
with self.assertLogs(logger, level='DEBUG') as log:
1318+
_log_sagemaker_config_single_substitution(
1319+
{"password": "supersecretpassword"},
1320+
{"apiKey": "topsecretkey"},
1321+
"config/path"
1322+
)
1323+
1324+
self.assertIn("Skipped value", log.output[0])
1325+
self.assertIn("source value that will be used = {'password': '***'}", log.output[0])
1326+
self.assertIn("config value = {'apiKey': '***'}", log.output[0])
1327+
1328+
def test_non_sensitive_info_masking(self):
1329+
logger = logging.getLogger('sagemaker.config')
1330+
logger.setLevel(logging.DEBUG)
1331+
1332+
stream_handler = logging.StreamHandler()
1333+
logger.addHandler(stream_handler)
1334+
1335+
# source value is None
1336+
with self.assertLogs(logger, level='DEBUG') as log:
1337+
_log_sagemaker_config_single_substitution(
1338+
None,
1339+
{"username": "randomvalue"},
1340+
"config/path"
1341+
)
1342+
1343+
self.assertIn("config value that will be used = {'username': 'randomvalue'}", log.output[0])
1344+
1345+
# source value is not None and config_value == source_value
1346+
with self.assertLogs(logger, level='DEBUG') as log:
1347+
_log_sagemaker_config_single_substitution(
1348+
{"nonsensitivevalue": "randomvalue"},
1349+
{"nonsensitivevalue": "randomvalue"},
1350+
"config/path"
1351+
)
1352+
1353+
self.assertIn("Skipped value", log.output[0])
1354+
self.assertIn("source value that will be used = {'nonsensitivevalue': 'randomvalue'}", log.output[0])
1355+
self.assertIn("config value = {'nonsensitivevalue': 'randomvalue'}", log.output[0])
1356+
1357+
# source value is not None and config_value != source_value
1358+
with self.assertLogs(logger, level='DEBUG') as log:
1359+
_log_sagemaker_config_single_substitution(
1360+
{"username": "nonsensitiveinfo"},
1361+
{"configvalue": "nonsensitivevalue"},
1362+
"config/path/non_sensitive"
1363+
)
1364+
1365+
self.assertIn("Skipped value", log.output[0])
1366+
self.assertIn("source value that will be used = {'username': 'nonsensitiveinfo'}", log.output[0])
1367+
self.assertIn("config value = {'configvalue': 'nonsensitivevalue'}", log.output[0])
1368+
1369+
12821370
def test_get_sagemaker_config_value():
12831371
mock_config_logger = Mock()
12841372

0 commit comments

Comments
 (0)