def test_policy_expected_errors_for_create_cert(): """Either a subject or subject alternative name property are required for creating a certificate""" client = CertificateClient("...", object()) with pytest.raises(ValueError, match=NO_SAN_OR_SUBJECT): policy = CertificatePolicy() client.begin_create_certificate("...", policy=policy) with pytest.raises(ValueError, match=NO_SAN_OR_SUBJECT): policy = CertificatePolicy(issuer_name=WellKnownIssuerNames.self) client.begin_create_certificate("...", policy=policy)
class KeyVaultCertificates: def __init__(self): # DefaultAzureCredential() expects the following environment variables: # * AZURE_CLIENT_ID # * AZURE_CLIENT_SECRET # * AZURE_TENANT_ID credential = DefaultAzureCredential() self.certificate_client = CertificateClient( vault_url=os.environ["AZURE_PROJECT_URL"], credential=credential) self.certificate_name = "cert-name-" + uuid.uuid1().hex def create_certificate(self): self.certificate_client.begin_create_certificate( name=self.certificate_name, policy=CertificatePolicy.get_default()).wait() print("\tdone") def get_certificate(self): print("Getting a certificate...") certificate = self.certificate_client.get_certificate( name=self.certificate_name) print(f"\tdone, certificate: {certificate.name}.") def delete_certificate(self): print("Deleting a certificate...") deleted_certificate = self.certificate_client.delete_certificate( name=self.certificate_name) print("\tdone: " + deleted_certificate.name) def run(self): print("") print("------------------------") print("Key Vault - Certificates\nIdentity - Credential") print("------------------------") print("1) Create a certificate") print("2) Get that certificate") print("3) Delete that certificate (Clean up the resource)") print("") try: self.create_certificate() self.get_certificate() finally: self.delete_certificate()
class KeyVaultCertificates: def __init__(self): # DefaultAzureCredential() expects the following environment variables: # * AZURE_CLIENT_ID # * AZURE_CLIENT_SECRET # * AZURE_TENANT_ID authority_host = os.environ.get('AZURE_AUTHORITY_HOST') or KnownAuthorities.AZURE_PUBLIC_CLOUD credential = DefaultAzureCredential(authority=authority_host) self.certificate_client = CertificateClient( vault_url=os.environ["AZURE_PROJECT_URL"], credential=credential ) self.certificate_name = "cert-name-" + uuid.uuid1().hex def create_certificate(self): print("Creating certificate (name: {})".format(self.certificate_name)) create_poller = self.certificate_client.begin_create_certificate( certificate_name=self.certificate_name, policy=CertificatePolicy.get_default()) print("\twaiting...") create_poller.result() print("\tdone") def get_certificate(self): print("Getting a certificate...") certificate = self.certificate_client.get_certificate(certificate_name=self.certificate_name) print("\tdone, certificate: {}.".format(certificate.name)) def delete_certificate(self): print("Deleting a certificate...") poller = self.certificate_client.begin_delete_certificate(certificate_name=self.certificate_name) deleted_certificate = poller.result() print("\tdone: " + deleted_certificate.name) def run(self): print("") print("------------------------") print("Key Vault - Certificates\nIdentity - Credential") print("------------------------") print("1) Create a certificate") print("2) Get that certificate") print("3) Delete that certificate (Clean up the resource)") print("") try: self.create_certificate() self.get_certificate() finally: self.delete_certificate()
def backup_restore_certificate(self): """ backs up a key vault certificate and restores it to another key vault """ # create a key vault first_vault = self.create_vault() # create a certificate client credential = DefaultAzureCredential() first_certificate_client = CertificateClient( vault_url=first_vault.properties.vault_uri, credential=credential) # add a certificate to the vault certificate_name = get_name('certificate') certificate = first_certificate_client.begin_create_certificate( certificate_name, CertificatePolicy.get_default()).result() print('created certificate {}'.format(certificate.name)) # list the certificates in the vault certificate_properties = first_certificate_client.list_properties_of_certificates( ) print("all of the certificates in the client's vault:") for certificate_property in certificate_properties: print(certificate_property.name) # backup the certificate backup = first_certificate_client.backup_certificate(certificate_name) print('backed up certificate {}'.format(certificate_name)) # create a second vault second_vault = self.create_vault() # create a certificate client second_certificate_client = CertificateClient( vault_url=second_vault.properties.vault_uri, credential=credential) # restore the certificate to the new vault restored = second_certificate_client.restore_certificate_backup(backup) print('restored certificate {}'.format(restored.name)) # list the certificates in the new vault certificate_properties = second_certificate_client.list_properties_of_certificates( ) print("all of the certificates in the new vault:") for certificate_property in certificate_properties: print(certificate_property.name)
class KeyVaultCertificates(KeyVaultBase): def __init__(self): credential = self.get_default_credential() self.certificate_client = CertificateClient( vault_url=os.environ["AZURE_PROJECT_URL"], credential=credential) self.certificate_name = "cert-name-" + uuid.uuid1().hex def create_certificate(self): print("Creating certificate (name: {})".format(self.certificate_name)) create_poller = self.certificate_client.begin_create_certificate( certificate_name=self.certificate_name, policy=CertificatePolicy.get_default()) print("\twaiting...") create_poller.result() print("\tdone") def get_certificate(self): print("Getting a certificate...") certificate = self.certificate_client.get_certificate( certificate_name=self.certificate_name) print("\tdone, certificate: {}.".format(certificate.name)) def delete_certificate(self): print("Deleting a certificate...") poller = self.certificate_client.begin_delete_certificate( certificate_name=self.certificate_name) deleted_certificate = poller.result() print("\tdone: " + deleted_certificate.name) def run(self): print("") print("------------------------") print("Key Vault - Certificates\nIdentity - Credential") print("------------------------") print("1) Create a certificate") print("2) Get that certificate") print("3) Delete that certificate (Clean up the resource)") print("") try: self.create_certificate() self.get_certificate() finally: self.delete_certificate()
# Instantiate a certificate client that will be used to call the service. # Notice that the client is using default Azure credentials. # To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID', # 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials. VAULT_ENDPOINT = os.environ["VAULT_ENDPOINT"] credential = DefaultAzureCredential() client = CertificateClient(vault_endpoint=VAULT_ENDPOINT, credential=credential) try: print("\n.. Create Certificate") cert_name = "BackupRestoreCertificate" # Let's create a certificate for your key vault. # if the certificate already exists in the Key Vault, then a new version of the certificate is created. # A long running poller is returned for the create certificate operation. create_certificate_poller = client.begin_create_certificate( name=cert_name, policy=CertificatePolicy.get_default()) # The result call awaits the completion of the create certificate operation and returns the final result. # It will return a certificate if creation is successful, and will return the CertificateOperation if not. certificate = create_certificate_poller.result() print("Certificate with name '{0}' created.".format(cert_name)) # Backups are good to have, if in case certificates gets deleted accidentally. # For long term storage, it is ideal to write the backup to a file. print("\n.. Create a backup for an existing certificate") certificate_backup = client.backup_certificate(name=cert_name) print("Backup created for certificate with name '{0}'.".format(cert_name)) # The storage account certificate is no longer in use, so you can delete it. print("\n.. Delete the certificate") client.delete_certificate(name=cert_name)
issuer_name=WellKnownIssuerNames.self, subject="CN=*.microsoft.com", san_dns_names=["sdk.azure-int.net"], exportable=True, key_type="RSA", key_size=2048, reuse_key=False, content_type=CertificateContentType.pkcs12, validity_in_months=24, ) cert_name = "HelloWorldCertificate" # begin_create_certificate returns a poller. Calling result() on the poller will return the certificate # as a KeyVaultCertificate if creation is successful, and the CertificateOperation if not. The wait() # call on the poller will wait until the long running operation is complete. certificate = client.begin_create_certificate(certificate_name=cert_name, policy=cert_policy).result() print("Certificate with name '{0}' created".format(certificate.name)) # Let's get the bank certificate using its name print("\n.. Get a certificate by name") bank_certificate = client.get_certificate(cert_name) print("Certificate with name '{0}' was found'.".format( bank_certificate.name)) # After one year, the bank account is still active, and we have decided to update the tags. print("\n.. Update a certificate by name") tags = {"a": "b"} updated_certificate = client.update_certificate_properties( certificate_name=bank_certificate.name, tags=tags) print("Certificate with name '{0}' was updated on date '{1}'".format( bank_certificate.name, updated_certificate.properties.updated_on))
def run_example(): """Resource Group management example.""" # # Create the Resource Manager Client with an Application (service principal) token provider # subscription_id = os.environ.get( 'AZURE_SUBSCRIPTION_ID', '11111111-1111-1111-1111-111111111111') # your Azure Subscription Id credential = ClientSecretCredential( client_id=os.environ['AZURE_CLIENT_ID'], client_secret=os.environ['AZURE_CLIENT_SECRET'], tenant_id=os.environ['AZURE_TENANT_ID']) resource_client = ResourceManagementClient(credential, subscription_id) compute_client = ComputeManagementClient(credential, subscription_id) network_client = NetworkManagementClient(credential, subscription_id) kv_mgmt_client = KeyVaultManagementClient(credential, subscription_id) cert_client = CertificateClient( "https://{}.vault.azure.net".format(KV_NAME), credential) # Create Resource group print('\nCreate Resource Group') resource_group = resource_client.resource_groups.create_or_update( GROUP_NAME, {'location': LOCATION}) print_item(resource_group) # Resolve the client_id as object_id for KeyVault access policy. # If you already know your object_id, you can skip this part sp_object_id = os.environ.get('AZURE_CLIENT_OBJECT_ID', '11111111-1111-1111-1111-111111111111' ) # your service principal's object id # Create Key Vault account print('\nCreate Key Vault account') async_vault_poller = kv_mgmt_client.vaults.begin_create_or_update( GROUP_NAME, KV_NAME, { 'location': LOCATION, 'properties': { 'sku': { 'name': 'standard' }, 'tenant_id': os.environ['AZURE_TENANT_ID'], 'access_policies': [{ 'tenant_id': os.environ['AZURE_TENANT_ID'], 'object_id': sp_object_id, 'permissions': { # Only "certificates" and "secrets" are needed for this sample 'certificates': ['all'], 'secrets': ['all'] } }], # Critical to allow the VM to download certificates later 'enabled_for_deployment': True } }) vault = async_vault_poller.result() print_item(vault) # # KeyVault recommentation is to wait 20 seconds after account creation for DNS update time.sleep(20) # Ask KeyVault to create a Certificate certificate_name = "cert1" print('\nCreate Key Vault Certificate') certificate_poller = cert_client.begin_create_certificate( certificate_name, policy=DEFAULT_POLICY) certificate_poller.wait() while True: check = cert_client.get_certificate_operation(certificate_name) if check.status != 'inProgress': break try: print("Waiting for certificate creation to finish") time.sleep(10) except KeyboardInterrupt: print("Certificate creation wait cancelled.") raise print_item(check) print('\nGet Key Vault created certificate as a secret') secret_client = SecretClient("https://{}.vault.azure.net".format(KV_NAME), credential) certificate_as_secret = secret_client.get_secret( certificate_name, "" # Latest version ) print_item(certificate_as_secret) print("\nCreate Network") # Create Network components of the VM # This is not related to the main topic of this sample and is just required to create the VM subnet = create_virtual_network(network_client) public_ip = create_public_ip(network_client) nic = create_network_interface(network_client, subnet, public_ip) print_item(nic) # Create a VM with some Key Vault certificates params_create = { 'location': LOCATION, 'hardware_profile': get_hardware_profile(), 'network_profile': get_network_profile(nic.id), 'storage_profile': get_storage_profile(), 'os_profile': { 'admin_username': ADMIN_LOGIN, 'admin_password': ADMIN_PASSWORD, 'computer_name': 'testkvcertificates', # This is the Key Vault critical part 'secrets': [{ 'source_vault': { 'id': vault.id, }, 'vault_certificates': [{ 'certificate_url': certificate_as_secret.id }] }] } } print("\nCreate VM") vm_poller = compute_client.virtual_machines.begin_create_or_update( GROUP_NAME, VM_NAME, params_create, ) vm_result = vm_poller.result() print_item(vm_result) # Get the PublicIP after VM creation, since assignment is dynamic public_ip = network_client.public_ip_addresses.get(GROUP_NAME, PUBLIC_IP_NAME) print("You can connect to the VM using:") print("ssh {}@{}".format( ADMIN_LOGIN, public_ip.ip_address, )) print("And password: {}\n".format(ADMIN_PASSWORD)) print("Your certificate is available in this folder: /var/lib/waagent") print("You must be root to see it (sudo su)\n") input("Press enter to delete this Resource Group.") # Delete Resource group and everything in it print('Delete Resource Group') delete_async_operation = resource_client.resource_groups.begin_delete( GROUP_NAME) delete_async_operation.wait() print("\nDeleted: {}".format(GROUP_NAME))
# Notice that the client is using default Azure credentials. # To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID', # 'AZURE_CLIENT_SECRET' and 'AZURE_TENANT_ID' are set with the service principal credentials. VAULT_URL = os.environ["VAULT_URL"] credential = DefaultAzureCredential() client = CertificateClient(vault_url=VAULT_URL, credential=credential) # Let's create certificates holding storage and bank accounts credentials. If the certificate # already exists in the Key Vault, then a new version of the certificate is created. print("\n.. Create Certificates") bank_cert_name = "BankRecoverCertificate" storage_cert_name = "ServerRecoverCertificate" bank_certificate_poller = client.begin_create_certificate( certificate_name=bank_cert_name, policy=CertificatePolicy.get_default() ) storage_certificate_poller = client.begin_create_certificate( certificate_name=storage_cert_name, policy=CertificatePolicy.get_default() ) bank_certificate = bank_certificate_poller.result() storage_certificate = storage_certificate_poller.result() print("Certificate with name '{0}' was created.".format(bank_certificate.name)) print("Certificate with name '{0}' was created.".format(storage_certificate.name)) # The storage account was closed, need to delete its credentials from the Key Vault. print("\n.. Delete a Certificate") deleted_bank_poller = client.begin_delete_certificate(bank_cert_name) deleted_bank_certificate = deleted_bank_poller.result() # To ensure certificate is deleted on the server side.
class Acme2KeyVault: """ Provisions ACME/Let's Encrypt TLS certificates """ def __init__(self, credential: ChainedTokenCredential, options: Options): self.options = options self._cert_client = CertificateClient(options.azure_keyvault_uri, credential) self._dns_client = DnsManagementClient(credential, options.azure_subscription_id) blob_svc_client = BlobServiceClient.from_connection_string( options.cert_request_connection_str, ) self._container_client = blob_svc_client.get_container_client( options.cert_request_container) def _cert_policy_from_request( self, cert_request: CertRequest) -> CertificatePolicy: subject = f"CN={cert_request.common_name}" if self.options.cert_subject: subject += " " + self.options.cert_subject return CertificatePolicy( issuer_name="Unknown", key_size=self.options.cert_key_size, subject=subject, san_dns_names=cert_request.alternative_names, validity_in_months=CERT_VALIDITY_MONTHS, exportable=True, ) def _generate_new_cert_key(self, cert_request: CertRequest) -> str: """ Generates a new certificate key and returns it in the PEM format (as required by Azure keyvault) Note: Deletes any previous certificate operation with the same id """ # Delete the previous certificate operation if it exists try: self._cert_client.delete_certificate_operation(cert_request.id) except HttpResponseError as e: if e.status_code != 404: raise # Generate a new certificate key self._cert_client.begin_create_certificate( certificate_name=cert_request.id, policy=self._cert_policy_from_request(cert_request), ) # Get the CSR for the new certificate key cert_op = self._cert_client.get_certificate_operation(cert_request.id) return _csr_bytes_to_pem(cert_op.csr) def _create_acme_client(self) -> acme_client.ClientV2: net = acme_client.ClientNetwork(key=josepy.JWKRSA( key=rsa.generate_private_key( public_exponent=ACME_RSA_PUBLIC_EXPONENT, key_size=ACME_RSA_KEY_SIZE, backend=default_backend(), ))) directory = acme_messages.Directory.from_json( net.get(self.options.acme_directory_url).json()) return acme_client.ClientV2(directory=directory, net=net) def _authorization_to_relative_domain( self, authorization: acme_messages.Authorization, ): relative_domain = authorization.identifier.value.replace( f".{self.options.azure_dns_zone}", "") return f"_acme-challenge.{relative_domain}" def _setup_dns_challenge( self, record_set_name: str, value: str, ): self._dns_client.record_sets.create_or_update( resource_group_name=self.options.azure_dns_zone_resource_group, zone_name=self.options.azure_dns_zone, relative_record_set_name=record_set_name, record_type=RecordType.TXT, parameters=RecordSet( ttl=ACME_CHALLENGE_TXT_RECORD_TTL, txt_records=[TxtRecord(value=[value])], ), ) def _teardown_dns_challenge( self, record_set_name: str, ): self._dns_client.record_sets.delete( resource_group_name=self.options.azure_dns_zone_resource_group, zone_name=self.options.azure_dns_zone, relative_record_set_name=record_set_name, record_type=RecordType.TXT, ) def _verify_challenge( self, client: acme_client.ClientV2, authz: acme_messages.Authorization, ): challenge_body, dns_challenge = _find_dns_challenge(authz) validation_domain = self._authorization_to_relative_domain(authz) response, validation_value = dns_challenge.response_and_validation( client.net.key) try: logging.debug( "Creating DNS challenge: '%s' = '%s'", validation_domain, validation_value, ) self._setup_dns_challenge( record_set_name=validation_domain, value=validation_value, ) logging.debug("Answering DNS challenge") client.answer_challenge(challenge_body, response) finally: logging.debug("Tearing down DNS challenge: '%s'", validation_domain) self._teardown_dns_challenge(record_set_name=validation_domain, ) def _order_certificate(self, csr: str) -> str: logging.debug("Registering an account") client = self._create_acme_client() client.new_account( acme_messages.NewRegistration.from_data( email=self.options.acme_contact_email, terms_of_service_agreed=True, )) logging.debug("Placing a new order") order = client.new_order(csr) logging.debug("Verifying challenges") authz_resource: acme_messages.AuthorizationResource for authz_resource in order.authorizations: # pylint: disable=not-an-iterable authz: acme_messages.Authorization = authz_resource.body self._verify_challenge(client, authz) logging.debug("Finalizing order") finalized_order = client.poll_and_finalize(order) return finalized_order.fullchain_pem def _store_certificate(self, cert_request: CertRequest, certificate: str): self._cert_client.merge_certificate( cert_request.id, [certificate.encode("ascii")], ) def provision(self, cert_request: CertRequest): """ Provision a TLS certificate based on the given certificate request. This can be used for both provisioning new certificates as well as renewing existing ones. """ logging.info("Generating a certificate key %s", cert_request.id) csr = self._generate_new_cert_key(cert_request) logging.info("Ordering a certificate for %s", cert_request.common_name) certificate = self._order_certificate(csr) logging.info("Storing certificate %s", cert_request.id) self._store_certificate(cert_request, certificate) def save(self, cert_request: CertRequest): """ Saves the certificate request details for certificate renewal purposes """ blob_client = self._container_client.get_blob_client( cert_request.blob_name) blob_client.upload_blob(data=cert_request.json(), overwrite=True) def _cert_needs_renewal(self, certificate: CertificateProperties) -> bool: # Disabled certificates are not renewed if not certificate.enabled: return False now = datetime.now(tz=timezone.utc) time_until_expiration = certificate.expires_on.replace() - now return time_until_expiration.days <= self.options.cert_expiry_threshold_days def find_cert_names_needing_renewal(self) -> typing.List[str]: """ Find all the names of the certificates from Key Vault that need to be renewed """ certificates = self._cert_client.list_properties_of_certificates() return [ certificate.name for certificate in certificates if self._cert_needs_renewal(certificate) ] def find_certs_needing_renewal(self) -> typing.List[CertRequest]: """ Find all the certificates from Key Vault that need to be renewed """ cert_requests: typing.List[CertRequest] = [] for cert_name in self.find_cert_names_needing_renewal(): blob_client = self._container_client.get_blob_client( _cert_name_to_blob_name(cert_name)) try: bytes = blob_client.download_blob().readall() cert_request = CertRequest.parse_raw(bytes) cert_requests.append(cert_request) except HttpResponseError as e: if e.status_code == 404: logging.error( "Could not find cert request document for certificate %s", cert_name, ) else: raise return cert_requests
def create_or_update_cert( kv_cert_name, *domains, use_prod=False, keyvault_url='https://ponti-certs-kvjwxwal2p6n.vault.azure.net/', dns_zone_resource_group='damienpontifex.com-rg', dns_zone_name='damienpontifex.com', registration_email='*****@*****.**', dns_subscription_id="fa2cbf67-1293-4f9c-8884-a0379a9e0c64"): # Get directory if use_prod: directory_url = 'https://acme-v02.api.letsencrypt.org/directory' user_key_name = 'acme' issuance_period_months = 3 else: directory_url = 'https://acme-staging-v02.api.letsencrypt.org/directory' user_key_name = 'acme-staging' issuance_period_months = 1 credential = DefaultAzureCredential() challenge_handler = functools.partial( dns_challenge_handler, credential=credential, subscription_id=dns_subscription_id, dns_zone_resource_group=dns_zone_resource_group, dns_zone_name=dns_zone_name) cert_client = CertificateClient(vault_url=keyvault_url, credential=credential) #%% key = KeyVaultRSAKey(credential, keyvault_url, user_key_name) account_key = josepy.JWKRSA(key=key) client_network = acme.client.ClientNetwork(account_key) directory = messages.Directory.from_json( client_network.get(directory_url).json()) client = acme.client.ClientV2(directory, client_network) new_regr = acme.messages.Registration.from_data( key=account_key, email=registration_email, terms_of_service_agreed=True) # Register or fetch account try: regr = client.new_account(new_regr) logger.info('Created new account') except acme.errors.ConflictError as e: regr = acme.messages.RegistrationResource(uri=e.location, body=new_regr) regr = client.query_registration(regr) logger.info('Got existing account') cert_policy = CertificatePolicy( issuer_name='Unknown', subject_name=f'CN={domains[0]}', exportable=True, key_type=KeyType.rsa, key_size=2048, content_type=CertificateContentType.pkcs12, san_dns_names=domains[1:] if len(domains) > 1 else [], validity_in_months=issuance_period_months) try: # Check an existing certificate operation isn't in progress cert_op = cert_client.get_certificate_operation( certificate_name=kv_cert_name) logger.info('Existing cert operation in progress') except ResourceNotFoundError: cert_op = cert_client.begin_create_certificate( certificate_name=kv_cert_name, policy=cert_policy) logger.info('New cert operation') # cert_op = kvclient.create_certificate(KEYVAULT_URL, certificate_name=kv_cert_name, certificate_policy=cert_policy) cert_op_res = cert_op.result() cert_op_r = cert_client.get_certificate_operation(kv_cert_name) logger.info('Created certificate request in key vault') # Wrap with header and footer for pem to show certificate request csr_pem = "-----BEGIN CERTIFICATE REQUEST-----\n" + base64.b64encode( cert_op_r.csr).decode() + "\n-----END CERTIFICATE REQUEST-----\n" # Submit order order_resource = client.new_order(csr_pem) logger.info('Submitted order') # Challenges from order # Respond to challenges challenges_to_respond_to = list( challenge_handler(authorizations=order_resource.authorizations, account_key=account_key)) for dns_challenge in challenges_to_respond_to: # Perform challenge auth_response = client.answer_challenge( dns_challenge, dns_challenge.chall.response(account_key)) logger.info('Answered challenges') # Poll for status # Finalize order # Download certificate final_order = client.poll_and_finalize(order_resource) logger.info('Finalised order') # Strip header and footer of BEGIN/END CERTIFICATE # with open('cert.pem', 'w') as f: # f.write(final_order.fullchain_pem) certificate_vals = [ val.replace('\n', '').encode() for val in final_order.fullchain_pem.split('-----') if 'CERTIFICATE' not in val and len(val.replace('\n', '')) != 0 ] cert_client.merge_certificate(name=kv_cert_name, x509_certificates=certificate_vals) logger.info('Merged certificate back to key vault')
def deleted_certificate_recovery(self): """ a sample of enumerating, retrieving, recovering and purging deleted certificates from a key vault """ # create a vault enabling the soft delete feature vault = self.create_vault() # create a certificate client credential = DefaultAzureCredential() certificate_client = CertificateClient( vault_url=vault.properties.vault_uri, credential=credential) # create certificates in the vault cert_to_recover = get_name('cert') cert_to_purge = get_name('cert') create_certificate_poller = certificate_client.begin_create_certificate( cert_to_recover, policy=CertificatePolicy.get_default()) created_certificate = create_certificate_poller.result() print('created certificate {}'.format(created_certificate.name)) create_certificate_poller = certificate_client.begin_create_certificate( cert_to_purge, policy=CertificatePolicy.get_default()) created_certificate = create_certificate_poller.result() print('created certificate {}'.format(created_certificate.name)) # list the vault certificates certificates = certificate_client.list_properties_of_certificates() print('list the vault certificates') for certificate in certificates: print(certificate.name) # delete the certificates deleted_certificate_poller = certificate_client.begin_delete_certificate( cert_to_recover) deleted_certificate = deleted_certificate_poller.result() deleted_certificate_poller.wait() print('deleted certificate {}'.format(deleted_certificate.name)) deleted_certificate_poller = certificate_client.begin_delete_certificate( cert_to_purge) deleted_certificate = deleted_certificate_poller.result() deleted_certificate_poller.wait() print('deleted certificate {}'.format(deleted_certificate.name)) # list the deleted certificates deleted_certs = certificate_client.list_deleted_certificates() print('deleted certificates:') for deleted_cert in deleted_certs: print(deleted_cert.name) # recover a deleted certificate recovered_certificate_poller = certificate_client.begin_recover_deleted_certificate( cert_to_recover) recovered_certificate_certificate = recovered_certificate_poller.result( ) print('recovered certificate {}'.format( recovered_certificate_certificate.name)) # purge a deleted certificate certificate_client.purge_deleted_certificate(cert_to_purge) time.sleep(50) print('purged certificate {}'.format(cert_to_purge)) # list the vault certificates certificates = certificate_client.list_properties_of_certificates() print("all of the certificates in the client's vault:") for certificate in certificates: print(certificate.name)
from azure.identity import CertificateCredential, DefaultAzureCredential from azure.keyvault.certificates import CertificateClient, CertificateContentType, CertificatePolicy from azure.keyvault.secrets import SecretClient VAULT_URL = os.environ["VAULT_URL"] credential = DefaultAzureCredential() # a CertificateClient to create self-signed certs to work with CERT_CLIENT = CertificateClient(VAULT_URL, credential) # Key Vault stores certificate private keys as secrets, so we use a SecretClient to retrieve them SECRET_CLIENT = SecretClient(VAULT_URL, credential) # Creating a self-signed cert to work with create_cert_poller = CERT_CLIENT.begin_create_certificate("azure-identity-sample", CertificatePolicy.get_default()) cert = create_cert_poller.result() # The certificate as returned by begin_create_certificate() or get_certificate() contains # only the public portion of the certificate. Key Vault will release the private key only # if the certificate's policy indicates it's exportable (certs are exportable by default). policy = CERT_CLIENT.get_certificate_policy(cert.name) assert policy.exportable, "Expected an exportable certificate because that's Key Vault's default" # The policy's content_type indicates whether the certificate is stored in PEM or PKCS12 format assert policy.content_type == CertificateContentType.pkcs12, "Expected PKCS12 because that's Key Vault's default" # Key Vault stores the complete certificate, with its private key, as a secret sharing the certificate's name # Because this certificate is stored in PKCS12 format, the secret's value is base64 encoded bytes encoded_cert = SECRET_CLIENT.get_secret(cert.name).value pkcs12_bytes = base64.b64decode(encoded_cert)