Skip to content

Commit 7e6dd5d

Browse files
[uss_qualifier] Add flag to ensure redaction of sensitive information (#853)
1 parent 2d30372 commit 7e6dd5d

File tree

4 files changed

+54
-5
lines changed

4 files changed

+54
-5
lines changed

monitoring/monitorlib/dicts.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import json
2-
from typing import List, Tuple, Any, Union
2+
from typing import List, Tuple, Any, Union, Iterator
33

44
from implicitdict import ImplicitDict
55

@@ -62,6 +62,17 @@ def get_element(obj: dict, element: Union[JSONAddress, List[str]], pop=False) ->
6262
raise ValueError(f"{str(e)} at {element}")
6363

6464

65+
def get_element_or_default(
66+
obj: dict, element: Union[JSONAddress, List[str]], default_value: Any
67+
) -> Any:
68+
try:
69+
return get_element(obj, element)
70+
except KeyError:
71+
return default_value
72+
except TypeError:
73+
return default_value
74+
75+
6576
class RemovedElement(ImplicitDict):
6677
address: JSONAddress
6778
value = None

monitoring/uss_qualifier/main.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from loguru import logger
1111
import yaml
1212

13-
from monitoring.monitorlib.dicts import remove_elements
13+
from monitoring.monitorlib.dicts import remove_elements, get_element_or_default
1414
from monitoring.monitorlib.versioning import get_code_version, get_commit_hash
1515
from monitoring.uss_qualifier.configurations.configuration import (
1616
USSQualifierConfiguration,
@@ -73,6 +73,13 @@ def parseArgs() -> argparse.Namespace:
7373
help="JSON string containing runtime metadata to record in the test run report (if specified).",
7474
)
7575

76+
parser.add_argument(
77+
"--disallow-unredacted",
78+
type=bool,
79+
default=False,
80+
help="When true, do not run a test configuration which would produce unredacted sensitive information in its artifacts",
81+
)
82+
7683
return parser.parse_args()
7784

7885

@@ -140,13 +147,32 @@ def execute_test_run(
140147
)
141148

142149

150+
def raise_for_unredacted_information(config: USSQualifierConfiguration) -> None:
151+
"""Raises a ValueError if the provided configuration would produce or display unredacted information."""
152+
153+
required_values = {
154+
"v1.artifacts.globally_expanded_report.redact_access_tokens": True,
155+
"v1.artifacts.raw_report.redact_access_tokens": True,
156+
"v1.artifacts.report_html.redact_access_tokens": True,
157+
"v1.artifacts.sequence_view.redact_access_tokens": True,
158+
}
159+
160+
for json_address, required_value in required_values.items():
161+
actual_value = get_element_or_default(config, json_address, required_value)
162+
if actual_value != required_value:
163+
raise ValueError(
164+
f"Configuration element {json_address} must be {required_value} to disallow unredacted information, but was instead set to {actual_value}"
165+
)
166+
167+
143168
def run_config(
144169
config_name: str,
145170
config_output: str,
146171
skip_validation: bool,
147172
exit_before_execution: bool,
148173
output_path: Optional[str],
149174
runtime_metadata: Optional[dict],
175+
disallow_unredacted: bool,
150176
):
151177
config_src = load_dict_with_references(config_name)
152178

@@ -192,6 +218,9 @@ def run_config(
192218
logger.info("Exiting because --exit-before-execution specified.")
193219
return
194220

221+
if disallow_unredacted:
222+
raise_for_unredacted_information(whole_config)
223+
195224
config: USSQualifierConfigurationV1 = whole_config.v1
196225

197226
if config.artifacts and not output_path:
@@ -206,7 +235,7 @@ def run_config(
206235
report.runtime_metadata = runtime_metadata
207236

208237
if config.artifacts:
209-
generate_artifacts(report, config.artifacts, output_path)
238+
generate_artifacts(report, config.artifacts, output_path, disallow_unredacted)
210239

211240
if "validation" in config and config.validation:
212241
logger.info(f"Validating test run report for configuration '{config_name}'")
@@ -228,6 +257,8 @@ def main() -> int:
228257
if runtime_metadata is not None and not isinstance(runtime_metadata, dict):
229258
raise ValueError("--runtime-metadata must specify a JSON dictionary")
230259

260+
disallow_unredacted = args.disallow_unredacted
261+
231262
config_names = str(args.config).split(",")
232263

233264
if args.config_output:
@@ -254,6 +285,7 @@ def main() -> int:
254285
args.exit_before_execution,
255286
output_path,
256287
runtime_metadata,
288+
disallow_unredacted,
257289
)
258290
if exit_code != os.EX_OK:
259291
return exit_code

monitoring/uss_qualifier/make_artifacts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def main() -> int:
8888
output_path = default_output_path(report_name)
8989
else:
9090
output_path = default_output_path(config_name)
91-
generate_artifacts(report, config.artifacts, output_path)
91+
generate_artifacts(report, config.artifacts, output_path, False)
9292
else:
9393
output_path = "nowhere"
9494
logger.warning(f"No artifacts to generate for {config_name}")

monitoring/uss_qualifier/reports/artifacts.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,18 @@ def generate_artifacts(
3434
report: TestRunReport,
3535
artifacts: ArtifactsConfiguration,
3636
output_path: str,
37+
disallow_unredacted: bool,
3738
):
3839
logger.debug(f"Writing artifacts to {os.path.abspath(output_path)}")
3940
os.makedirs(output_path, exist_ok=True)
4041

4142
def _should_redact(cfg) -> bool:
42-
return "redact_access_tokens" in cfg and cfg.redact_access_tokens
43+
result = "redact_access_tokens" in cfg and cfg.redact_access_tokens
44+
if disallow_unredacted and not result:
45+
raise RuntimeError(
46+
"The option to disallow unredacted information was set, but the configuration specified unredacted information any way"
47+
)
48+
return result
4349

4450
logger.info(f"Redacting access tokens from report")
4551
redacted_report = ImplicitDict.parse(json.loads(json.dumps(report)), TestRunReport)

0 commit comments

Comments
 (0)