Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Keyvault] az keyvault security-domain upload/restore-blob: Make --passwords required to protect private key files #29432

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from

Conversation

evelyn-ys
Copy link
Member

Related command

az keyvault security-domain upload/restore-blob

Description

Fix #29278
It's unsafe to ask customers to store plain text private key files on their local disk for --sd-wrapping-keys parameter for az keyvault security-domain upload/restore-blob. So we require --sd-wrapping-keys together with --passwords

Testing Guide

History Notes

[Component Name 1] BREAKING CHANGE: az command a: Make some customer-facing breaking change
[Component Name 2] az command b: Add some customer-facing feature


This checklist is used to make sure that common guidelines for a pull request are followed.

Copy link

azure-client-tools-bot-prd bot commented Jul 22, 2024

❌AzureCLI-FullTest
️✔️acr
️✔️2020-09-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9
️✔️acs
️✔️2020-09-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9
️✔️advisor
️✔️latest
️✔️3.11
️✔️3.9
️✔️ams
️✔️latest
️✔️3.11
️✔️3.9
️✔️apim
️✔️latest
️✔️3.11
️✔️3.9
️✔️appconfig
️✔️latest
️✔️3.11
️✔️3.9
️✔️appservice
️✔️latest
️✔️3.11
️✔️3.9
️✔️aro
️✔️latest
️✔️3.11
️✔️3.9
️✔️backup
️✔️latest
️✔️3.11
️✔️3.9
️✔️batch
️✔️latest
️✔️3.11
️✔️3.9
️✔️batchai
️✔️latest
️✔️3.11
️✔️3.9
️✔️billing
️✔️latest
️✔️3.11
️✔️3.9
️✔️botservice
️✔️latest
️✔️3.11
️✔️3.9
️✔️cdn
️✔️latest
️✔️3.11
️✔️3.9
️✔️cloud
️✔️latest
️✔️3.11
️✔️3.9
️✔️cognitiveservices
️✔️latest
️✔️3.11
️✔️3.9
️✔️compute_recommender
️✔️latest
️✔️3.11
️✔️3.9
️✔️config
️✔️latest
️✔️3.11
️✔️3.9
️✔️configure
️✔️latest
️✔️3.11
️✔️3.9
️✔️consumption
️✔️latest
️✔️3.11
️✔️3.9
️✔️container
️✔️latest
️✔️3.11
️✔️3.9
️✔️containerapp
️✔️latest
️✔️3.11
️✔️3.9
️✔️core
️✔️2018-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2019-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9
️✔️cosmosdb
️✔️latest
️✔️3.11
️✔️3.9
️✔️databoxedge
️✔️2019-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9
️✔️dla
️✔️latest
️✔️3.11
️✔️3.9
️✔️dls
️✔️latest
️✔️3.11
️✔️3.9
️✔️dms
️✔️latest
️✔️3.11
️✔️3.9
️✔️eventgrid
️✔️latest
️✔️3.11
️✔️3.9
️✔️eventhubs
️✔️latest
️✔️3.11
️✔️3.9
️✔️feedback
️✔️latest
️✔️3.11
️✔️3.9
️✔️find
️✔️latest
️✔️3.11
️✔️3.9
️✔️hdinsight
️✔️latest
️✔️3.11
️✔️3.9
️✔️identity
️✔️latest
️✔️3.11
️✔️3.9
️✔️iot
️✔️2019-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9
❌keyvault
️✔️2018-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.11
️✔️3.9
❌latest
❌3.11
Type Test Case Error Message Line
Failed test_keyvault_hsm_security_domain self = <azure.cli.testsdk.base.ExecutionResult object at 0x7fa0f2e9ba90>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7fa0f518da50>
command = 'keyvault security-domain upload --hsm-name test-mhsm-sd2000003 --sd-file "/tmp/tmpzib6nhpm/sdfile.json" --sd-exchange...s/latest/keys/sd1.pem" "/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/keys/sd2.pem"'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0

src/azure-cli-testsdk/azure/cli/testsdk/base.py:302: 
 
                                       
env/lib/python3.11/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
src/azure-cli-core/azure/cli/core/init.py:127: in exception_handler
    return handle_exception(ex)
                                        

ex = CLIError(CLIError("--passwords can't be None. Please don't save key files without password protection on local disk."))
args = (), kwargs = {}

    def handle_main_exception(ex, *args, **kwargs):  # pylint: disable=unused-argument
        if isinstance(ex, CannotOverwriteExistingCassetteException):
            # This exception usually caused by a no match HTTP request. This is a product error
            # that is caused by change of SDK invocation.
            raise ex
    
>       raise CliExecutionError(ex)
E       azure.cli.testsdk.exceptions.CliExecutionError: The CLI throws exception CLIError during execution and fails the command.

src/azure-cli-testsdk/azure/cli/testsdk/patches.py:35: CliExecutionError

During handling of the above exception, another exception occurred:

self = <azure.cli.command_modules.keyvault.tests.latest.test_keyvault_commands.KeyVaultHSMSecurityDomainScenarioTest testMethod=test_keyvault_hsm_security_domain>

    @serial_test()
    @AllowLargeResponse()
    @ResourceGroupPreparer(name_prefix='cli_test_keyvault_mhsm_sd')
    def test_keyvault_hsm_security_domain(self):
        sdtest_dir = tempfile.mkdtemp()
        logged_in_user = self.cmd('ad signed-in-user show').get_output_in_json()
        logged_in_user = logged_in_user["id"] if logged_in_user is not None else "a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e"
        self.kwargs.update({
            'hsm_name': self.create_random_name('test-mhsm-sd1', 24),
            'next_hsm_name': self.create_random_name('test-mhsm-sd2', 24),
            'loc': 'uksouth',
            'init_admin': logged_in_user,
            'key_name': self.create_random_name('key', 10),
            'sdtest_dir': sdtest_dir
        })
        self.kwargs.update({
            'sdfile': os.path.join(self.kwargs['sdtest_dir'], 'sdfile.json'),
            'exchange_key': os.path.join(self.kwargs['sdtest_dir'], 'sdex.pem'),
            'key_backup': os.path.join(self.kwargs['sdtest_dir'], 'key.bak')
        })
    
        for i in range(1, 4):
            self.kwargs['cer{}path'.format(i)] = os.path.join(KEYS_DIR, 'sd{}.cer'.format(i))
            self.kwargs['key{}path'.format(i)] = os.path.join(KEYS_DIR, 'sd{}.pem'.format(i))
    
        self.cmd('az keyvault create --hsm-name {hsm_name} -l {loc} -g {rg} --administrators {init_admin} '
                 '--retention-days 7')
    
        self.cmd('az keyvault wait-hsm --hsm-name {hsm_name} --created -g {rg}')
    
        # download SD
        self.cmd('az keyvault security-domain download --hsm-name {hsm_name} --security-domain-file "{sdfile}" '
                 '--sd-quorum 2 --sd-wrapping-keys "{cer1_path}" "{cer2_path}" "{cer3_path}"')
        time.sleep(180)
        with mock.patch('azure.cli.command_modules.keyvault.custom.gen_guid', side_effect=self.create_guid):
            self.cmd('az keyvault role assignment create --assignee {init_admin} --hsm-name {hsm_name} '
                     '--role "Managed HSM Crypto User" --scope "/"')
    
        # create a new key and backup it
        self.cmd('az keyvault key create --hsm-name {hsm_name} -n {key_name}')
        self.cmd('az keyvault key backup --hsm-name {hsm_name} -n {key_name} -f "{key_backup}"')
    
        # delete the HSM
        self.cmd('az keyvault delete --hsm-name {hsm_name}')
    
        # create a new HSM
        self.cmd('az keyvault create --hsm-name {next_hsm_name} -l {loc} -g {rg} --administrators {init_admin} '
                 '--retention-days 7 --no-wait')
    
        # wait until the HSM is ready for recovery
        self.cmd('az keyvault wait-hsm --hsm-name {next_hsm_name} --created -g {rg}')
    
        # download the exchange key
        self.cmd('az keyvault security-domain init-recovery --hsm-name {next_hsm_name} '
                 '--sd-exchange-key "{exchange_key}"')
    
        # upload the blob
>       self.cmd('az keyvault security-domain upload --hsm-name {next_hsm_name} --sd-file "{sdfile}" '
                 '--sd-exchange-key "{exchange_key}" '
                 '--sd-wrapping-keys "{key1_path}" "{key2_path}"')

src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_keyvault_commands.py:593: 
 
 
 
                                     
src/azure-cli-testsdk/azure/cli/testsdk/base.py:176: in cmd
    return execute(self.cli_ctx, command, expect_failure=expect_failure).assert_with_checks(checks)
src/azure-cli-testsdk/azure/cli/testsdk/base.py:251: in init
    self.in_process_execute(cli_ctx, command, expect_failure=expect_failure)
src/azure-cli-testsdk/azure/cli/testsdk/base.py:314: in in_process_execute
    raise ex.exception
env/lib/python3.11/site-packages/knack/cli.py:233: in invoke
    cmd_result = self.invocation.execute(args)
src/azure-cli-core/azure/cli/core/commands/init.py:664: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:731: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
src/azure-cli-core/azure/cli/core/commands/init.py:701: in run_job
    result = cmd_copy(params)
src/azure-cli-core/azure/cli/core/commands/init.py:334: in call
    return self.handler(*args, **kwargs)
src/azure-cli/azure/cli/command_modules/keyvault/command_type.py:135: in keyvault_command_handler
    return keyvault_exception_handler(ex)
 
 
 
 
 
                                   

ex = CLIError("--passwords can't be None. Please don't save key files without password protection on local disk.")

    def keyvault_exception_handler(ex):
        from msrest.exceptions import ValidationError, ClientRequestError
        if isinstance(ex, ValidationError):
            try:
                raise CLIError(ex.inner_exception.error.message)
            except AttributeError:
                raise CLIError(ex)
        elif isinstance(ex, ClientRequestError):
            if 'Failed to establish a new connection' in str(ex.inner_exception):
                instance_type = 'Vault'
                if 'managedhsm' in str(ex.inner_exception):
                    instance_type = 'HSM'
                raise CLIError('Max retries exceeded attempting to connect to {instance_type}. '
                               'The {instance_type} may not exist or you may need to flush your DNS cache '
                               'and try again later.'.format(instance_type=instance_type))
            raise CLIError(ex)
        else:
>           raise CLIError(ex)
E           knack.util.CLIError: --passwords can't be None. Please don't save key files without password protection on local disk.

src/azure-cli/azure/cli/command_modules/keyvault/_command_type.py:49: CLIError
azure/cli/command_modules/keyvault/tests/latest/test_keyvault_commands.py:535
❌3.9
Type Test Case Error Message Line
Failed test_keyvault_hsm_security_domain self = <azure.cli.testsdk.base.ExecutionResult object at 0x7fb45209db80>
cli_ctx = <azure.cli.core.mock.DummyCli object at 0x7fb454935a00>
command = 'keyvault security-domain upload --hsm-name test-mhsm-sd2000003 --sd-file "/tmp/tmpbxhcp3i4/sdfile.json" --sd-exchange...s/latest/keys/sd1.pem" "/mnt/vss/work/1/s/src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/keys/sd2.pem"'
expect_failure = False

    def in_process_execute(self, cli_ctx, command, expect_failure=False):
        from io import StringIO
        from vcr.errors import CannotOverwriteExistingCassetteException
    
        if command.startswith('az '):
            command = command[3:]
    
        stdout_buf = StringIO()
        logging_buf = StringIO()
        try:
            # issue: stderr cannot be redirect in this form, as a result some failure information
            # is lost when command fails.
>           self.exit_code = cli_ctx.invoke(shlex.split(command), out_file=stdout_buf) or 0

src/azure-cli-testsdk/azure/cli/testsdk/base.py:302: 
 
                                       
env/lib/python3.9/site-packages/knack/cli.py:245: in invoke
    exit_code = self.exception_handler(ex)
src/azure-cli-core/azure/cli/core/init.py:127: in exception_handler
    return handle_exception(ex)
                                        

ex = CLIError(CLIError("--passwords can't be None. Please don't save key files without password protection on local disk."))
args = (), kwargs = {}

    def handle_main_exception(ex, *args, **kwargs):  # pylint: disable=unused-argument
        if isinstance(ex, CannotOverwriteExistingCassetteException):
            # This exception usually caused by a no match HTTP request. This is a product error
            # that is caused by change of SDK invocation.
            raise ex
    
>       raise CliExecutionError(ex)
E       azure.cli.testsdk.exceptions.CliExecutionError: The CLI throws exception CLIError during execution and fails the command.

src/azure-cli-testsdk/azure/cli/testsdk/patches.py:35: CliExecutionError

During handling of the above exception, another exception occurred:

self = <azure.cli.command_modules.keyvault.tests.latest.test_keyvault_commands.KeyVaultHSMSecurityDomainScenarioTest testMethod=test_keyvault_hsm_security_domain>

    @serial_test()
    @AllowLargeResponse()
    @ResourceGroupPreparer(name_prefix='cli_test_keyvault_mhsm_sd')
    def test_keyvault_hsm_security_domain(self):
        sdtest_dir = tempfile.mkdtemp()
        logged_in_user = self.cmd('ad signed-in-user show').get_output_in_json()
        logged_in_user = logged_in_user["id"] if logged_in_user is not None else "a7250e3a-0e5e-48e2-9a34-45f1f5e1a91e"
        self.kwargs.update({
            'hsm_name': self.create_random_name('test-mhsm-sd1', 24),
            'next_hsm_name': self.create_random_name('test-mhsm-sd2', 24),
            'loc': 'uksouth',
            'init_admin': logged_in_user,
            'key_name': self.create_random_name('key', 10),
            'sdtest_dir': sdtest_dir
        })
        self.kwargs.update({
            'sdfile': os.path.join(self.kwargs['sdtest_dir'], 'sdfile.json'),
            'exchange_key': os.path.join(self.kwargs['sdtest_dir'], 'sdex.pem'),
            'key_backup': os.path.join(self.kwargs['sdtest_dir'], 'key.bak')
        })
    
        for i in range(1, 4):
            self.kwargs['cer{}path'.format(i)] = os.path.join(KEYS_DIR, 'sd{}.cer'.format(i))
            self.kwargs['key{}path'.format(i)] = os.path.join(KEYS_DIR, 'sd{}.pem'.format(i))
    
        self.cmd('az keyvault create --hsm-name {hsm_name} -l {loc} -g {rg} --administrators {init_admin} '
                 '--retention-days 7')
    
        self.cmd('az keyvault wait-hsm --hsm-name {hsm_name} --created -g {rg}')
    
        # download SD
        self.cmd('az keyvault security-domain download --hsm-name {hsm_name} --security-domain-file "{sdfile}" '
                 '--sd-quorum 2 --sd-wrapping-keys "{cer1_path}" "{cer2_path}" "{cer3_path}"')
        time.sleep(180)
        with mock.patch('azure.cli.command_modules.keyvault.custom.gen_guid', side_effect=self.create_guid):
            self.cmd('az keyvault role assignment create --assignee {init_admin} --hsm-name {hsm_name} '
                     '--role "Managed HSM Crypto User" --scope "/"')
    
        # create a new key and backup it
        self.cmd('az keyvault key create --hsm-name {hsm_name} -n {key_name}')
        self.cmd('az keyvault key backup --hsm-name {hsm_name} -n {key_name} -f "{key_backup}"')
    
        # delete the HSM
        self.cmd('az keyvault delete --hsm-name {hsm_name}')
    
        # create a new HSM
        self.cmd('az keyvault create --hsm-name {next_hsm_name} -l {loc} -g {rg} --administrators {init_admin} '
                 '--retention-days 7 --no-wait')
    
        # wait until the HSM is ready for recovery
        self.cmd('az keyvault wait-hsm --hsm-name {next_hsm_name} --created -g {rg}')
    
        # download the exchange key
        self.cmd('az keyvault security-domain init-recovery --hsm-name {next_hsm_name} '
                 '--sd-exchange-key "{exchange_key}"')
    
        # upload the blob
>       self.cmd('az keyvault security-domain upload --hsm-name {next_hsm_name} --sd-file "{sdfile}" '
                 '--sd-exchange-key "{exchange_key}" '
                 '--sd-wrapping-keys "{key1_path}" "{key2_path}"')

src/azure-cli/azure/cli/command_modules/keyvault/tests/latest/test_keyvault_commands.py:593: 
 
 
 
                                     
src/azure-cli-testsdk/azure/cli/testsdk/base.py:176: in cmd
    return execute(self.cli_ctx, command, expect_failure=expect_failure).assert_with_checks(checks)
src/azure-cli-testsdk/azure/cli/testsdk/base.py:251: in init
    self.in_process_execute(cli_ctx, command, expect_failure=expect_failure)
src/azure-cli-testsdk/azure/cli/testsdk/base.py:314: in in_process_execute
    raise ex.exception
env/lib/python3.9/site-packages/knack/cli.py:233: in invoke
    cmd_result = self.invocation.execute(args)
src/azure-cli-core/azure/cli/core/commands/init.py:664: in execute
    raise ex
src/azure-cli-core/azure/cli/core/commands/init.py:731: in run_jobs_serially
    results.append(self.run_job(expanded_arg, cmd_copy))
src/azure-cli-core/azure/cli/core/commands/init.py:701: in run_job
    result = cmd_copy(params)
src/azure-cli-core/azure/cli/core/commands/init.py:334: in call
    return self.handler(*args, **kwargs)
src/azure-cli/azure/cli/command_modules/keyvault/command_type.py:135: in keyvault_command_handler
    return keyvault_exception_handler(ex)
 
 
 
 
 
                                   

ex = CLIError("--passwords can't be None. Please don't save key files without password protection on local disk.")

    def keyvault_exception_handler(ex):
        from msrest.exceptions import ValidationError, ClientRequestError
        if isinstance(ex, ValidationError):
            try:
                raise CLIError(ex.inner_exception.error.message)
            except AttributeError:
                raise CLIError(ex)
        elif isinstance(ex, ClientRequestError):
            if 'Failed to establish a new connection' in str(ex.inner_exception):
                instance_type = 'Vault'
                if 'managedhsm' in str(ex.inner_exception):
                    instance_type = 'HSM'
                raise CLIError('Max retries exceeded attempting to connect to {instance_type}. '
                               'The {instance_type} may not exist or you may need to flush your DNS cache '
                               'and try again later.'.format(instance_type=instance_type))
            raise CLIError(ex)
        else:
>           raise CLIError(ex)
E           knack.util.CLIError: --passwords can't be None. Please don't save key files without password protection on local disk.

src/azure-cli/azure/cli/command_modules/keyvault/_command_type.py:49: CLIError
azure/cli/command_modules/keyvault/tests/latest/test_keyvault_commands.py:535
️✔️kusto
️✔️latest
️✔️3.11
️✔️3.9
️✔️lab
️✔️latest
️✔️3.11
️✔️3.9
️✔️managedservices
️✔️latest
️✔️3.11
️✔️3.9
️✔️maps
️✔️latest
️✔️3.11
️✔️3.9
️✔️marketplaceordering
️✔️latest
️✔️3.11
️✔️3.9
️✔️monitor
️✔️latest
️✔️3.11
️✔️3.9
️✔️mysql
️✔️latest
️✔️3.11
️✔️3.9
️✔️netappfiles
️✔️latest
️✔️3.11
️✔️3.9
️✔️network
️✔️2018-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9
️✔️policyinsights
️✔️latest
️✔️3.11
️✔️3.9
️✔️privatedns
️✔️latest
️✔️3.11
️✔️3.9
️✔️profile
️✔️latest
️✔️3.11
️✔️3.9
️✔️rdbms
️✔️latest
️✔️3.11
️✔️3.9
️✔️redis
️✔️latest
️✔️3.11
️✔️3.9
️✔️relay
️✔️latest
️✔️3.11
️✔️3.9
️✔️resource
️✔️2018-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2019-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9
️✔️role
️✔️latest
️✔️3.11
️✔️3.9
️✔️search
️✔️latest
️✔️3.11
️✔️3.9
️✔️security
️✔️latest
️✔️3.11
️✔️3.9
️✔️servicebus
️✔️latest
️✔️3.11
️✔️3.9
️✔️serviceconnector
️✔️latest
️✔️3.11
️✔️3.9
️✔️servicefabric
️✔️latest
️✔️3.11
️✔️3.9
️✔️signalr
️✔️latest
️✔️3.11
️✔️3.9
️✔️sql
️✔️latest
️✔️3.11
️✔️3.9
️✔️sqlvm
️✔️latest
️✔️3.11
️✔️3.9
️✔️storage
️✔️2018-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2019-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9
️✔️synapse
️✔️latest
️✔️3.11
️✔️3.9
️✔️telemetry
️✔️2018-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2019-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9
️✔️util
️✔️latest
️✔️3.11
️✔️3.9
️✔️vm
️✔️2018-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2019-03-01-hybrid
️✔️3.11
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.11
️✔️3.9
️✔️latest
️✔️3.11
️✔️3.9

Copy link

azure-client-tools-bot-prd bot commented Jul 22, 2024

❌AzureCLI-BreakingChangeTest
❌keyvault
rule cmd_name rule_message suggest_message
1008 - ParaPropAdd keyvault security-domain restore-blob cmd keyvault security-domain restore-blob update parameter passwords: added property required=True please remove property required=True for parameter passwords of cmd keyvault security-domain restore-blob

@evelyn-ys evelyn-ys marked this pull request as draft July 22, 2024 06:14
@yonzhan
Copy link
Collaborator

yonzhan commented Jul 22, 2024

Keyvault

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Auto-Assign Auto assign by bot KeyVault az keyvault
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CLI Endpoint Support for Managed HSM (Fix Bug with CLI Plain Text Keys)
2 participants