From 3a706542a2a9f73d585a436f0664d7edf73e519b Mon Sep 17 00:00:00 2001 From: Dominic Ayre Date: Mon, 22 Sep 2025 14:12:22 +0000 Subject: [PATCH 1/6] Add a warning and path for default change for stdio --- src/confcom/azext_confcom/_params.py | 21 +++++++++-- src/confcom/azext_confcom/_validators.py | 4 ++ src/confcom/azext_confcom/custom.py | 48 ++++++++++++++++++++---- 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/confcom/azext_confcom/_params.py b/src/confcom/azext_confcom/_params.py index 855973176ac..78a107972e7 100644 --- a/src/confcom/azext_confcom/_params.py +++ b/src/confcom/azext_confcom/_params.py @@ -23,6 +23,7 @@ validate_fragment_json, validate_fragment_json_policy, validate_image_target, + validate_stdio, validate_upload_fragment, validate_infrastructure_svn, ) @@ -105,9 +106,15 @@ def load_arguments(self, _): ) c.argument( "disable_stdio", - options_list=("--disable-stdio",), - required=False, + action="store_true", + help="Disabling container stdio will disable the ability to see the output of the container in the terminal for Confidential ACI", + validator=validate_stdio, + ) + c.argument( + "enable_stdio", + action="store_true", help="Disabling container stdio will disable the ability to see the output of the container in the terminal for Confidential ACI", + validator=validate_stdio, ) c.argument( "diff", @@ -290,9 +297,15 @@ def load_arguments(self, _): ) c.argument( "disable_stdio", - options_list=("--disable-stdio",), - required=False, + action="store_true", + help="Disabling container stdio will disable the ability to see the output of the container in the terminal for Confidential ACI", + validator=validate_stdio, + ) + c.argument( + "enable_stdio", + action="store_true", help="Disabling container stdio will disable the ability to see the output of the container in the terminal for Confidential ACI", + validator=validate_stdio, ) c.argument( "debug_mode", diff --git a/src/confcom/azext_confcom/_validators.py b/src/confcom/azext_confcom/_validators.py index d79a630bb6b..8b4d90ebad4 100644 --- a/src/confcom/azext_confcom/_validators.py +++ b/src/confcom/azext_confcom/_validators.py @@ -131,3 +131,7 @@ def validate_fragment_path(namespace): def validate_fragment_json(namespace): if namespace.fragments_json and not namespace.generate_import: raise CLIError("Must provide --fragment-path to place a fragment import into a file") + +def validate_stdio(namespace): + if namespace.enable_stdio and namespace.disable_stdio: + raise CLIError('Use only one of --enable-stdio or --disable-stdio.') diff --git a/src/confcom/azext_confcom/custom.py b/src/confcom/azext_confcom/custom.py index 4405fefcc14..53011b17858 100644 --- a/src/confcom/azext_confcom/custom.py +++ b/src/confcom/azext_confcom/custom.py @@ -5,6 +5,7 @@ import os import sys +from typing import Optional from azext_confcom import oras_proxy, os_util, security_policy from azext_confcom.config import ( @@ -43,7 +44,8 @@ def acipolicygen_confcom( save_to_file: str = None, debug_mode: bool = False, print_policy_to_terminal: bool = False, - disable_stdio: bool = False, + disable_stdio: Optional[bool] = None, + enable_stdio: Optional[bool] = None, print_existing_policy: bool = False, faster_hashing: bool = False, omit_id: bool = False, @@ -61,6 +63,20 @@ def acipolicygen_confcom( "For additional information, see http://aka.ms/clisecrets. \n", ) + stdio_enabled = True # Default value + if enable_stdio is None and disable_stdio is None: + logger.warning( + "WARNING: Using default stdio setting (Enabled)\n" + "For the most secure deployments, ensure stdio is disabled. " + "Default behaviour may change in the future, you can set stdio with:\n" + " --disable-stdio\n" + " --enable-stdio\n" + ) + elif enable_stdio is not None: + stdio_enabled = enable_stdio + elif disable_stdio is not None: + stdio_enabled = not disable_stdio + if print_existing_policy and arm_template: print_existing_policy_from_arm_template(arm_template, arm_template_parameters) return @@ -112,7 +128,7 @@ def acipolicygen_confcom( input_path, debug_mode=debug_mode, infrastructure_svn=infrastructure_svn, - disable_stdio=disable_stdio, + disable_stdio=(not stdio_enabled), exclude_default_fragments=exclude_default_fragments, ) elif arm_template: @@ -121,7 +137,7 @@ def acipolicygen_confcom( arm_template, arm_template_parameters, debug_mode=debug_mode, - disable_stdio=disable_stdio, + disable_stdio=(not stdio_enabled), approve_wildcards=approve_wildcards, diff_mode=diff, rego_imports=fragments_list, @@ -129,13 +145,13 @@ def acipolicygen_confcom( ) elif image_name: container_group_policies = security_policy.load_policy_from_image_name( - image_name, debug_mode=debug_mode, disable_stdio=disable_stdio + image_name, debug_mode=debug_mode, disable_stdio=(not stdio_enabled) ) elif virtual_node_yaml_path: container_group_policies = security_policy.load_policy_from_virtual_node_yaml_file( virtual_node_yaml_path=virtual_node_yaml_path, debug_mode=debug_mode, - disable_stdio=disable_stdio, + disable_stdio=(not stdio_enabled), approve_wildcards=approve_wildcards, diff_mode=diff, rego_imports=fragments_list, @@ -227,7 +243,8 @@ def acifragmentgen_confcom( fragment_path: str = None, omit_id: bool = False, generate_import: bool = False, - disable_stdio: bool = False, + disable_stdio: Optional[bool] = None, + enable_stdio: Optional[bool] = None, debug_mode: bool = False, output_filename: str = "", outraw: bool = False, @@ -235,6 +252,21 @@ def acifragmentgen_confcom( no_print: bool = False, fragments_json: str = "", ): + + stdio_enabled = True # Default value + if enable_stdio is None and disable_stdio is None: + logger.warning( + "WARNING: Using default stdio setting (Enabled)\n" + "For the most secure deployments, ensure stdio is disabled. " + "Default behaviour may change in the future, you can set stdio with:\n" + " --disable-stdio\n" + " --enable-stdio\n" + ) + elif enable_stdio is not None: + stdio_enabled = enable_stdio + elif disable_stdio is not None: + stdio_enabled = not disable_stdio + output_type = get_fragment_output_type(outraw) if generate_import: @@ -288,14 +320,14 @@ def acifragmentgen_confcom( if image_name: policy = security_policy.load_policy_from_image_name( - image_name, debug_mode=debug_mode, disable_stdio=disable_stdio + image_name, debug_mode=debug_mode, disable_stdio=(not stdio_enabled) ) else: # this is using --input if not tar_mapping: tar_mapping = os_util.load_tar_mapping_from_config_file(input_path) policy = security_policy.load_policy_from_json_file( - input_path, debug_mode=debug_mode, disable_stdio=disable_stdio + input_path, debug_mode=debug_mode, disable_stdio=(not stdio_enabled) ) # get all of the fragments that are being used in the policy # and associate them with each container group From b67559a9a059df462b0f000385dcf1af1c939a65 Mon Sep 17 00:00:00 2001 From: Dominic Ayre Date: Mon, 22 Sep 2025 14:27:34 +0000 Subject: [PATCH 2/6] Satisfy azdev style --- src/confcom/azext_confcom/_validators.py | 1 + src/confcom/azext_confcom/custom.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/confcom/azext_confcom/_validators.py b/src/confcom/azext_confcom/_validators.py index 8b4d90ebad4..519369cfb66 100644 --- a/src/confcom/azext_confcom/_validators.py +++ b/src/confcom/azext_confcom/_validators.py @@ -132,6 +132,7 @@ def validate_fragment_json(namespace): if namespace.fragments_json and not namespace.generate_import: raise CLIError("Must provide --fragment-path to place a fragment import into a file") + def validate_stdio(namespace): if namespace.enable_stdio and namespace.disable_stdio: raise CLIError('Use only one of --enable-stdio or --disable-stdio.') diff --git a/src/confcom/azext_confcom/custom.py b/src/confcom/azext_confcom/custom.py index 53011b17858..8fe03d1b4a7 100644 --- a/src/confcom/azext_confcom/custom.py +++ b/src/confcom/azext_confcom/custom.py @@ -63,7 +63,7 @@ def acipolicygen_confcom( "For additional information, see http://aka.ms/clisecrets. \n", ) - stdio_enabled = True # Default value + stdio_enabled = True # Default value if enable_stdio is None and disable_stdio is None: logger.warning( "WARNING: Using default stdio setting (Enabled)\n" @@ -253,7 +253,7 @@ def acifragmentgen_confcom( fragments_json: str = "", ): - stdio_enabled = True # Default value + stdio_enabled = True # Default value if enable_stdio is None and disable_stdio is None: logger.warning( "WARNING: Using default stdio setting (Enabled)\n" From ea039e86caedcd1ae5190f955542ec1997041e9b Mon Sep 17 00:00:00 2001 From: Dominic Ayre Date: Tue, 23 Sep 2025 08:18:24 +0000 Subject: [PATCH 3/6] Fix help string for --enable-stdio --- src/confcom/azext_confcom/_params.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/confcom/azext_confcom/_params.py b/src/confcom/azext_confcom/_params.py index 78a107972e7..08bf87e28fc 100644 --- a/src/confcom/azext_confcom/_params.py +++ b/src/confcom/azext_confcom/_params.py @@ -113,7 +113,7 @@ def load_arguments(self, _): c.argument( "enable_stdio", action="store_true", - help="Disabling container stdio will disable the ability to see the output of the container in the terminal for Confidential ACI", + help="Enable the standard io streams to leave the container", validator=validate_stdio, ) c.argument( @@ -304,7 +304,7 @@ def load_arguments(self, _): c.argument( "enable_stdio", action="store_true", - help="Disabling container stdio will disable the ability to see the output of the container in the terminal for Confidential ACI", + help="Enable the standard io streams to leave the container", validator=validate_stdio, ) c.argument( From bdcec05504208b9786877ac54425b7d5ee849c7d Mon Sep 17 00:00:00 2001 From: Dominic Ayre Date: Tue, 23 Sep 2025 08:19:03 +0000 Subject: [PATCH 4/6] Refactor resolving stdio into it's own function --- src/confcom/azext_confcom/_validators.py | 23 +++++++++++++++++++ src/confcom/azext_confcom/custom.py | 29 +++--------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/confcom/azext_confcom/_validators.py b/src/confcom/azext_confcom/_validators.py index 519369cfb66..be669f70d8d 100644 --- a/src/confcom/azext_confcom/_validators.py +++ b/src/confcom/azext_confcom/_validators.py @@ -4,9 +4,13 @@ # -------------------------------------------------------------------------------------------- from knack.util import CLIError +from knack.log import get_logger from azext_confcom.config import RESERVED_FRAGMENT_NAMES, SUPPORTED_ALGOS +logger = get_logger(__name__) + + def validate_params_file(namespace): if namespace.arm_template_parameters and not namespace.arm_template: raise CLIError( @@ -136,3 +140,22 @@ def validate_fragment_json(namespace): def validate_stdio(namespace): if namespace.enable_stdio and namespace.disable_stdio: raise CLIError('Use only one of --enable-stdio or --disable-stdio.') + + +def resolve_stdio(enable_stdio_flag, disable_stdio_flag, default=True): + + stdio_enabled = default + if enable_stdio_flag is None and disable_stdio_flag is None: + logger.warning( + "WARNING: Using default stdio setting (Enabled)\n" + "For the most secure deployments, ensure stdio is disabled. " + "Default behaviour may change in the future, you can set stdio with:\n" + " --disable-stdio\n" + " --enable-stdio\n" + ) + elif enable_stdio_flag is not None: + stdio_enabled = enable_stdio_flag + elif disable_stdio_flag is not None: + stdio_enabled = not disable_stdio_flag + + return stdio_enabled diff --git a/src/confcom/azext_confcom/custom.py b/src/confcom/azext_confcom/custom.py index 8fe03d1b4a7..acd513f2038 100644 --- a/src/confcom/azext_confcom/custom.py +++ b/src/confcom/azext_confcom/custom.py @@ -8,6 +8,7 @@ from typing import Optional from azext_confcom import oras_proxy, os_util, security_policy +from azext_confcom._validators import resolve_stdio from azext_confcom.config import ( DEFAULT_REGO_FRAGMENTS, POLICY_FIELD_CONTAINERS_ELEMENTS_REGO_FRAGMENTS, REGO_IMPORT_FILE_STRUCTURE) @@ -63,19 +64,7 @@ def acipolicygen_confcom( "For additional information, see http://aka.ms/clisecrets. \n", ) - stdio_enabled = True # Default value - if enable_stdio is None and disable_stdio is None: - logger.warning( - "WARNING: Using default stdio setting (Enabled)\n" - "For the most secure deployments, ensure stdio is disabled. " - "Default behaviour may change in the future, you can set stdio with:\n" - " --disable-stdio\n" - " --enable-stdio\n" - ) - elif enable_stdio is not None: - stdio_enabled = enable_stdio - elif disable_stdio is not None: - stdio_enabled = not disable_stdio + stdio_enabled = resolve_stdio(enable_stdio, disable_stdio) if print_existing_policy and arm_template: print_existing_policy_from_arm_template(arm_template, arm_template_parameters) @@ -253,19 +242,7 @@ def acifragmentgen_confcom( fragments_json: str = "", ): - stdio_enabled = True # Default value - if enable_stdio is None and disable_stdio is None: - logger.warning( - "WARNING: Using default stdio setting (Enabled)\n" - "For the most secure deployments, ensure stdio is disabled. " - "Default behaviour may change in the future, you can set stdio with:\n" - " --disable-stdio\n" - " --enable-stdio\n" - ) - elif enable_stdio is not None: - stdio_enabled = enable_stdio - elif disable_stdio is not None: - stdio_enabled = not disable_stdio + stdio_enabled = resolve_stdio(enable_stdio, disable_stdio) output_type = get_fragment_output_type(outraw) From 4d1a2d5703350558ea415d0942d498cfbd48e911 Mon Sep 17 00:00:00 2001 From: Dominic Ayre Date: Tue, 23 Sep 2025 10:53:45 +0000 Subject: [PATCH 5/6] Bump version --- src/confcom/HISTORY.rst | 4 ++++ src/confcom/setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/confcom/HISTORY.rst b/src/confcom/HISTORY.rst index 3006fd18e73..b192f72bb8f 100644 --- a/src/confcom/HISTORY.rst +++ b/src/confcom/HISTORY.rst @@ -3,6 +3,10 @@ Release History =============== +1.2.8 +++++++ +* Add a new --enable-stdio flag, with a warning if neither this or --disable-stdio is set + 1.2.7 ++++++ * bugfix making it so that oras discover function doesn't error when no fragments are found in the remote repository diff --git a/src/confcom/setup.py b/src/confcom/setup.py index 3ce7907b25a..954d44b1874 100644 --- a/src/confcom/setup.py +++ b/src/confcom/setup.py @@ -19,7 +19,7 @@ logger.warn("Wheel is not available, disabling bdist_wheel hook") -VERSION = "1.2.7" +VERSION = "1.2.8" # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers From d412885a177f93983db932edbff2e7300a1f207d Mon Sep 17 00:00:00 2001 From: Dominic Ayre Date: Wed, 24 Sep 2025 18:04:18 +0000 Subject: [PATCH 6/6] Bump minor version --- src/confcom/HISTORY.rst | 2 +- src/confcom/setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/confcom/HISTORY.rst b/src/confcom/HISTORY.rst index b192f72bb8f..f45806e4666 100644 --- a/src/confcom/HISTORY.rst +++ b/src/confcom/HISTORY.rst @@ -3,7 +3,7 @@ Release History =============== -1.2.8 +1.3.0 ++++++ * Add a new --enable-stdio flag, with a warning if neither this or --disable-stdio is set diff --git a/src/confcom/setup.py b/src/confcom/setup.py index 954d44b1874..df6c58e0180 100644 --- a/src/confcom/setup.py +++ b/src/confcom/setup.py @@ -19,7 +19,7 @@ logger.warn("Wheel is not available, disabling bdist_wheel hook") -VERSION = "1.2.8" +VERSION = "1.3.0" # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers