class KeyVaultWrapper(object): def __init__(self, client_id = None, secret = None, tenant_id = None): if client_id != None and secret != None and tenant_id != None: credentials = ServicePrincipalCredentials( client_id = client_id, secret = secret, tenant = tenant_id) else: credentials = MSIAuthentication(resource='https://vault.azure.net') self.kvclient = KeyVaultClient(credentials) def upload_secret(self, vault_uri, secret_name, filename): with open(filename, "rt") as f: self.kvclient.set_secret(vault_uri, secret_name, f.read()) def get_secret(self, vault_uri, secret_name, secret_version): return self.kvclient.get_secret(vault_uri, secret_name, secret_version).value def get_secret_to_file(self, vault_uri, secret_name, secret_version, filename): with open(filename, 'wt+') as file: file.write(self.get_secret(vault_uri, secret_name, secret_version)) def get_certificate_and_key(self, vault_uri, cert_name, cert_version): secret = self.get_secret(vault_uri, cert_name, cert_version) p12 = crypto.load_pkcs12(base64.b64decode(secret), "") return [p12.get_certificate(), p12.get_privatekey()] def get_certificate_and_key_to_file(self, vault_uri, cert_name, cert_version, key_filename, cert_filename): [cert, key] = self.get_certificate_and_key(vault_uri, cert_name, cert_version) with open(cert_filename, 'wb+') as pem_file: pem_file.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert)) with open(key_filename, 'wb+') as key_file: key_file.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key)) def upload_pfx(self, vault_uri, cert_name, pfx_bytes): encoded = base64.b64encode(pfx_bytes) self.kvclient.import_certificate( vault_base_url = vault_uri, certificate_name = cert_name, base64_encoded_certificate = encoded.decode('utf-8')) def generate_pfx(self, certificate, key, passphrase): p12 = crypto.PKCS12() p12.set_certificate(certificate) p12.set_privatekey(key) return p12.export()
def auth_using_adal_callback(self): """ authenticates to the Azure Key Vault by providing a callback to authenticate using adal """ # create a vault to validate authentication with the KeyVaultClient vault = self.create_vault() import adal # create an adal authentication context auth_context = adal.AuthenticationContext('https://login.microsoftonline.com/%s' % self.config.tenant_id) # create a callback to supply the token type and access token on request def adal_callback(server, resource, scope): token = auth_context.acquire_token_with_client_credentials(resource=resource, client_id=self.config.client_id, client_secret=self.config.client_secret) return token['tokenType'], token['accessToken'] # create a KeyVaultAuthentication instance which will callback to the supplied adal_callback auth = KeyVaultAuthentication(adal_callback) # create the KeyVaultClient using the created KeyVaultAuthentication instance client = KeyVaultClient(auth) # set and get a secret from the vault to validate the client is authenticated print('creating secret...') print(client.set_secret(vault.properties.vault_uri, 'auth-sample-secret', 'client is authenticated to the vault')) print('getting secret...') print(client.get_secret(vault.properties.vault_uri, 'auth-sample-secret', secret_version=KeyVaultId.version_none))
def auth_using_service_principle_credentials(self): """ authenticates to the Azure Key Vault service using AAD service principle credentials """ # create a vault to validate authentication with the KeyVaultClient vault = self.create_vault() # create the service principle credentials used to authenticate the client credentials = ServicePrincipalCredentials( client_id=self.config.client_id, secret=self.config.client_secret, tenant=self.config.tenant_id) # create the client using the created credentials client = KeyVaultClient(credentials) # set and get a secret from the vault to validate the client is authenticated print('creating secret...') secret_bundle = client.set_secret( vault.properties.vault_uri, 'auth-sample-secret', 'client is authenticated to the vault') print(secret_bundle) print('getting secret...') secret_bundle = client.get_secret( vault.properties.vault_uri, 'auth-sample-secret', secret_version=KeyVaultId.version_none) print(secret_bundle)
def main(): arg_parser = argparse.ArgumentParser() arg_parser.add_argument( '--name', '-n', action='store', help='secret name to add') arg_parser.add_argument( '--value', '-v', action='store', help='secret value to add') arg_parser.add_argument( '--delete', '-d', action='store', help='secret name to delete') arg_parser.add_argument( '--keyvault', '-k', action='store', help='key vault name') args = arg_parser.parse_args() if args.name is None and args.delete is None: sys.exit('Error: --name (-n) or --delete (-d) argument not provided.') # Load Azure app defaults try: with open('azurermconfig.json') as config_file: config_data = json.load(config_file) except FileNotFoundError: sys.exit("Error: Expecting azurermconfig.json in current folder") tenant_id = config_data['tenantId'] app_id = config_data['appId'] app_secret = config_data['appSecret'] if args.keyvault is None: kv_name = config_data['keyvault'] else: kv_name = args.keyvault key_vault_uri = f'https://{kv_name}.vault.azure.net/' # get credentials credentials = ServicePrincipalCredentials(client_id=app_id, secret=app_secret, tenant=tenant_id) # instantiate a key vault client client = KeyVaultClient(credentials) try: if args.value is not None: # add a secret secret_bundle = client.set_secret(key_vault_uri, args.name, args.value) print('Secret added:', secret_bundle.id) elif args.delete is not None: # delete a secret client.delete_secret(key_vault_uri, args.delete) print('Secret deleted:', args.delete) else: # get a secret secret = client.get_secret(key_vault_uri, args.name, '') print(secret.value) except Exception as ex: print(ex)
def auth_user_with_device_code(self): """ authenticates to the Azure Key Vault by providing a callback to authenticate using adal """ # create a vault to validate authentication with the KeyVaultClient vault = self.create_vault() import adal # create an adal authentication context auth_context = adal.AuthenticationContext( 'https://login.microsoftonline.com/%s' % self.config.tenant_id) # using the XPlat command line client id as it is available across all tenants and subscriptions # this would be replaced by your app id xplat_client_id = '04b07795-8ddb-461a-bbee-02f9e1bf7b46' # create a callback to supply the token type and access token on request def adal_callback(server, resource, scope): user_code_info = auth_context.acquire_user_code( resource, xplat_client_id) print(user_code_info['message']) token = auth_context.acquire_token_with_device_code( resource=resource, client_id=xplat_client_id, user_code_info=user_code_info) return token['tokenType'], token['accessToken'] # create a KeyVaultAuthentication instance which will callback to the supplied adal_callback auth = KeyVaultAuthentication(adal_callback) # create the KeyVaultClient using the created KeyVaultAuthentication instance client = KeyVaultClient(auth) # set and get a secret from the vault to validate the client is authenticated print('creating secret...') secret_bundle = client.set_secret( vault.properties.vault_uri, 'auth-sample-secret', 'client is authenticated to the vault') print(secret_bundle) print('getting secret...') secret_bundle = client.get_secret( vault.properties.vault_uri, 'auth-sample-secret', secret_version=KeyVaultId.version_none) print(secret_bundle)
def GetKeyVaultDBKeys(keyname, genkey, keyversion=""): client = KeyVaultClient(KeyVaultAuthentication(auth_callback)) if genkey == "true": #print "genrate new key" secretvalue = getjsonforuserpwd() secret_bundle1 = client.set_secret( "https://gav-cu-ine-dev-kvrmdemo.vault.azure.net/", keyname, secretvalue) #print secret_bundle1 secret_bundle = client.get_secret( "https://gav-cu-ine-dev-kvrmdemo.vault.azure.net/", keyname, keyversion) #print secret_bundle.value + "getresult" return (secret_bundle.value)
def create_secret_in_key_vault(resource_group_name, key_vault_name, key_vault_secret_name, key_vault_secret_value): "Create an Azure Key Vault Secret" credentials = get_azure_credentials(azure_tenant_id, azure_client_id, azure_secret_id) key_vault_data_plane_client = KeyVaultClient(credentials) key_vault_info = get_key_vault(resource_group_name, key_vault_name) try: key_vault_secret_bundle = key_vault_data_plane_client.set_secret( key_vault_info.properties.vault_uri, key_vault_secret_name, key_vault_secret_value, ) except CloudError as ex: print(ex)
def sp_auth(self): vault = self.create_vault() credentials = ServicePrincipalCredentials( client_id=self.config.client_id, secret=self.config.client_secret, tenant=self.config.tenant_id) client = KeyVaultClient(credentials) #set secret secret_bundle = client.set_secret(vault.properties.vault_uri, 'auth-sample-secret', 'successfully authenticated') print(secret_bundle) #get secret secret_bundle = client.get_secret( vault.properties.vault_uri, 'auth-sample-secret', secret_version=KeyVaultId.version_none) print(secret_bundle)
def createhostentry(): constring = "host=gav-ne-ine-qa-postgresqlarmdemo.postgres.database.azure.com user=geinadmin@gav-ne-ine-qa-postgresqlarmdemo dbname=postgres password= admin@123" client = KeyVaultClient(KeyVaultAuthentication(auth_callback)) secret_bundle1 = client.set_secret( "https://gav-cu-ine-dev-kvrmdemo.vault.azure.net/", "dbhostconstring", constring)
def setkv_secret(keyname, secretvalue): client = KeyVaultClient(KeyVaultAuthentication(auth_callback)) secret_bundle1 = client.set_secret( "https://gav-cu-ine-dev-kvrmdemo.vault.azure.net/", keyname, secretvalue) return (secret_bundle1)
def run_example(): """ARM Template deployment example.""" # # Create the following RP Clients with an Application (service principal) token provider # KnownProfiles.default.use(KnownProfiles.v2019_03_01_hybrid) credentials, subscription_id, mystack_cloud = get_credentials() resource_client = ResourceManagementClient( credentials, subscription_id, base_url=mystack_cloud.endpoints.resource_manager) compute_client = ComputeManagementClient( credentials, subscription_id, base_url=mystack_cloud.endpoints.resource_manager) network_client = NetworkManagementClient( credentials, subscription_id, base_url=mystack_cloud.endpoints.resource_manager) kv_mgmt_client = KeyVaultManagementClient( credentials, subscription_id, base_url=mystack_cloud.endpoints.resource_manager) kv_credentials = ServicePrincipalCredentials( client_id=os.environ['AZURE_CLIENT_ID'], secret=os.environ['AZURE_CLIENT_SECRET'], tenant=os.environ['AZURE_TENANT_ID'], cloud_environment=mystack_cloud) kv_client = KeyVaultClient(kv_credentials) # 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 = resolve_service_principal(os.environ['AZURE_CLIENT_ID']) # Create Key Vault account print('\nCreate Key Vault account') vault = kv_mgmt_client.vaults.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 } }) print_item(vault) # KeyVault recommendation is to wait 20 seconds after account creation for DNS update time.sleep(20) # Create a certificate in the keyvault as a secret certificate_name = "cert1" print('\nCreate Key Vault Certificate as a secret') cert_value = '<Provide your certificate as a base64 encoded string value>' kv_client.set_secret(vault.properties.vault_uri, certificate_name, cert_value) print('\nGet Key Vault created certificate as a secret') certificate_as_secret = kv_client.get_secret( vault.properties.vault_uri, 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.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.delete(GROUP_NAME) delete_async_operation.wait() print("\nDeleted: {}".format(GROUP_NAME))
import redis import sys import os from azure.common.credentials import ServicePrincipalCredentials from azure.mgmt.keyvault import KeyVaultManagementClient from azure.keyvault import KeyVaultClient, KeyVaultId solname = os.getenv('AZURE_USER').replace('http://', '') credentials = ServicePrincipalCredentials(client_id=os.getenv('AZURE_USER'), secret=os.getenv('AZURE_PWD'), tenant=os.getenv('AZURE_TENANT')) client = KeyVaultClient(credentials) KEYVAULT = 'https://' + solname + '.vault.azure.net' secret_bundle = client.set_secret(KEYVAULT, 'dummy', '') secret_id = KeyVaultId.parse_secret_id(secret_bundle.id) redis_secret = client.get_secret(KEYVAULT, 'vmcr8tester-redis-pw', secret_id.version_none).value key = sys.argv[1] value = sys.argv[2] r = redis.StrictRedis(host=solname + '.redis.cache.windows.net', port=6380, db=0, password=redis_secret, ssl=True) r.set(key, value)
class AzureKeyVault: """Class to interact with the Azure Key Vault service. Relies on the Managed Identity access token to interact with the Key Vault. If used outside of the Azure environment (e.g. for development or testing), requires Service Principal to be defined. Warning ------- Use Service Principal authentication only for DEV environments! It is as secure as hard-coding secrets into the code or application configuration. Attributes ---------- _logger : :obj:`~logging.Logger` Channel to be used for log output specific to the module. _vault_name : :obj:`str` Name of Azure Key Vault to access. _service_principal : :obj:`dict` Service Principal credentials with access rights to Azure Key Vault, if provided. See :meth:`__init__` for more details _vault_creds : :obj:`BasicTokenAuthentication` Key Vault access token obtained either through Managed Identity (:obj:`MSIAuthentication`) or Service Principal (:obj:`ServicePrincipalCredentials`) authentication. _vault_uri : :obj:`str` Key Vault URI to query. _vault_client : :obj:`KeyVaultClient` Client instance to interact with Key Vault. """ """Standard API endpoint URI for Azure Key Vault resource.""" __AZURE_RESOURCE_KEYVAULT = "https://vault.azure.net" def __init__(self, **kwargs): """Initialize instance, get correct Key Vault access credentials. Keyword Arguments ----------------- vault_name : :obj:`str` Name of Key Vault to access app_id : :obj:`str`, optional Service Principal ``appId`` to access Key Vault outside Azure (default :obj:`None`) password : :obj:`str`, optional Service Principal ``password`` to access Key Vault outside Azure (default :obj:`None`) tenant : :obj:`str`, optional Service Principal ``tenant`` for Azure Subscription (default :obj:`None`) """ self._logger = getLogger(__name__) self._vault_name = kwargs.get("vault_name", None) if self._vault_name is None: self._logger.exception( "Exception: must provide 'vault_name' as a keyword argument" ) raise ValueError("must provide 'vault_name' as a keyword argument") else: self._service_principal = { "app_id": kwargs.get("app_id", None), "password": kwargs.get("password", None), "tenant": kwargs.get("tenant", None), } # access Key Vault with Service Principal credentials, if defined if self._service_principal["app_id"] is not None: self._logger.info( "access Key Vault '%s' with Service Principal", self._vault_name ) self._logger.debug( "Service Principal credentials: '%s'", self._service_principal ) self._vault_creds = ServicePrincipalCredentials( client_id=self._service_principal["app_id"], secret=self._service_principal["password"], tenant=self._service_principal["tenant"], resource=self.__AZURE_RESOURCE_KEYVAULT, ) # otherwise, access Key Vault with Managed Identity else: self._logger.info( "access Key Vault '%s' with Managed Identity", self._vault_name ) self._vault_creds = MSIAuthentication( resource=self.__AZURE_RESOURCE_KEYVAULT ) self._vault_uri = "https://{}.vault.azure.net/".format(self._vault_name) self._vault_client = KeyVaultClient(self._vault_creds) self._logger.debug( "Created instance from %s(%s)", self.__class__.__name__, ", ".join( "{}='{}'".format(key, value) for key, value in locals().items() ), # noqa ) def get_secret(self, secret_name=None, secret_version=""): # noqa """Get `secret_name` of specific `secret_version` from Key Vault. Parameters ---------- secret_name : :obj:`str` Name of secret to retrieve (default :obj:`None`) secret_version : :obj:`str`, optional Version of secret to retrieve, if empty means latest version (default '') Returns ------- :obj:`SecretBundle` Object containing secret value with meta-data from Key Vault, or `None` if :obj:`KeyVaultErrorException` raised """ if secret_name is None: self._logger.exception( "Exception: must provide 'secret_name' as a keyword argument" ) raise ValueError("must provide 'secret_name' as a keyword argument") self._logger.info( "requesting secret '%s' of version '%s' from Key Vault URI '%s'", secret_name, secret_version, self._vault_uri, ) secret = None try: secret = self._vault_client.get_secret( self._vault_uri, secret_name, secret_version ) except KeyVaultErrorException: self._logger.exception("Exception: getting secret") else: self._logger.debug("received secret '%s'", secret) return secret def set_secret( self, secret_name=None, secret_value=None, content_type="application/json" ): """Set `secret_name` to specific `secret_value` in the Key Vault. Parameters ---------- secret_name : :obj:`str` Name of secret to be updated (default :obj:`None`) secret_value : :obj:`str` Value to be stored in ``secret_name`` (default :obj:`None`) content_type : :obj:`str`, optional Content type of the value to be stored (default ``application/json``) Returns ------- :obj:`SecretBundle` Object containing latest secret value with meta-data from Key Vault, or `None` if :obj:`KeyVaultErrorException` raised """ if secret_name is None: self._logger.exception( "Exception: must provide 'secret_name' as a keyword argument" ) raise ValueError("must provide 'secret_name' as a keyword argument") if secret_value is None: self._logger.exception( "Exception: must provide 'secret_value' as a keyword argument" ) raise ValueError("must provide 'secret_value' as a keyword argument") self._logger.info( "updating secret '%s' with value of content type '%s' \ at Key Vault URI '%s'", secret_name, content_type, self._vault_uri, ) secret = None try: secret = self._vault_client.set_secret( self._vault_uri, secret_name, secret_value, content_type=content_type ) except KeyVaultErrorException: self._logger.exception("Exception: updating secret") else: self._logger.debug("updated secret '%s'", secret) return secret
class AzureRMKeyVaultSecret(AzureRMModuleBase): ''' Module that creates or deletes secrets in Azure KeyVault ''' def __init__(self): self.module_arg_spec = dict(secret_name=dict(type='str', required=True), secret_value=dict(type='str', aliases=['secret'], no_log=True), keyvault_uri=dict(type='str', required=True), state=dict(type='str', default='present', choices=['present', 'absent'])) required_if = [('state', 'present', ['secret_value'])] self.results = dict(changed=False, state=dict()) self.secret_name = None self.secret_value = None self.keyvault_uri = None self.state = None self.data_creds = None self.client = None self.tags = None super(AzureRMKeyVaultSecret, self).__init__(self.module_arg_spec, supports_check_mode=True, required_if=required_if, supports_tags=True) def exec_module(self, **kwargs): for key in list(self.module_arg_spec.keys()) + ['tags']: setattr(self, key, kwargs[key]) # Create KeyVault Client using KeyVault auth class and auth_callback self.client = KeyVaultClient(self.azure_credentials) results = dict() changed = False try: results['secret_id'] = self.get_secret(self.secret_name) # Secret exists and will be deleted if self.state == 'absent': changed = True except KeyVaultErrorException: # Secret doesn't exist if self.state == 'present': changed = True self.results['changed'] = changed self.results['state'] = results if not self.check_mode: # Create secret if self.state == 'present' and changed: results['secret_id'] = self.create_secret( self.secret_name, self.secret_value, self.tags) self.results['state'] = results self.results['state']['status'] = 'Created' # Delete secret elif self.state == 'absent' and changed: results['secret_id'] = self.delete_secret(self.secret_name) self.results['state'] = results self.results['state']['status'] = 'Deleted' else: if self.state == 'present' and changed: self.results['state']['status'] = 'Created' elif self.state == 'absent' and changed: self.results['state']['status'] = 'Deleted' return self.results def get_secret(self, name, version=''): ''' Gets an existing secret ''' secret_bundle = self.client.get_secret(self.keyvault_uri, name, version) if secret_bundle: secret_id = KeyVaultId.parse_secret_id(secret_bundle.id) return secret_id.id def create_secret(self, name, secret, tags): ''' Creates a secret ''' secret_bundle = self.client.set_secret(self.keyvault_uri, name, secret, tags) secret_id = KeyVaultId.parse_secret_id(secret_bundle.id) return secret_id.id def delete_secret(self, name): ''' Deletes a secret ''' deleted_secret = self.client.delete_secret(self.keyvault_uri, name) secret_id = KeyVaultId.parse_secret_id(deleted_secret.id) return secret_id.id
from azure.keyvault import KeyVaultClient, KeyVaultAuthentication from azure.common.credentials import ServicePrincipalCredentials credentials = ServicePrincipalCredentials( client_id='YourClientAdd', secret='YourSecret', tenant='domain.onmicrosoft.com', ) VAULT_URL = 'https://YourKeyvaultNAME.vault.azure.net' SECRET_ID = 'mysecret' client = KeyVaultClient(credentials) # VAULT_URL must be in the format 'https://<vaultname>.vault.azure.net' # SECRET_VERSION is required, and can be obtained with the KeyVaultClient.get_secret_versions(self, vault_url, secret_id) API key_bundle = client.get_key(VAULT_URL, 'key', 'e371b887e1f54708a947cc8570272543') key = key_bundle.key secret_bundle = client.get_secret(VAULT_URL, SECRET_ID, '90cdeb79bc494b77920ed2bbdba8139e') #Create a Secret my_secret = client.set_secret(VAULT_URL, "secretfrompython2", "pythonvalue2") #Create a Key key2 = client.create_key(VAULT_URL, "key2", "RSA") versions = client.get_key_versions(VAULT_URL, SECRET_ID) #Delete a Key delete_key(vault_base_url, key_name, custom_headers=None, raw=False, **operation_config) #client.delete_key(VAULT_URL,"key2") print(my_secret) print(secret_bundle) print(key) print(key2)
class KV_Repl(object): _repl_break_commands = set(('back', 'b')) _repl_quit_commands = set(('quit', 'q')) def __init__(self, config): self._auth = KeyVaultAuth(config, CLIENT_ID) self._config = config self._mgmt_client = KeyVaultManagementClient( self._auth.get_arm_creds(), config.subscription_id) self._data_client = KeyVaultClient(self._auth.get_keyvault_creds()) self._selected_vault = None self._current_index = None def start(self): try: self._vault_index_loop() except SystemExit: print('\nuser exited\n') def _continue_repl(self, display_action, break_commands=()): display_action() self._selection = input('> ').lower() if self._selection in break_commands: return None elif self._selection in KV_Repl._repl_quit_commands: sys.exit() try: self._selection = int(self._selection) except ValueError: pass return self._selection def _display_vault_index(self): print('\nAvailable Vaults:\n') self._current_index = self._get_vault_list() for idx, vault in enumerate(self._current_index): print('%d. %s' % (idx, vault.name)) print('\n#:select | (a)dd | (d)elete | (q)uit') def _vault_index_loop(self): while self._continue_repl(self._display_vault_index) is not None: vaults = self._current_index if isinstance(self._selection, int): i = self._selection if i >= 0 and i < len(vaults): self._selected_vault = self._mgmt_client.vaults.get( self._config.resource_group, vaults[i].name) self._vault_detail_loop() else: print('invalid vault index') elif self._selection == 'a' or self._selection == 'add': self._add_vault() else: print('invalid input') def _add_vault(self): name = input('\nenter vault name:') all_perms = Permissions() all_perms.keys = [KeyPermissions.all] all_perms.secrets = [SecretPermissions.all] all_perms.certificates = [CertificatePermissions.all] user_policy = AccessPolicyEntry(self._config.tenant_id, self._config.user_oid, all_perms) app_policy = AccessPolicyEntry(CLIENT_TENANT_ID, CLIENT_OID, all_perms) access_policies = [user_policy, app_policy] properties = VaultProperties(self._config.tenant_id, Sku(name='standard'), access_policies) properties.enabled_for_deployment = True properties.enabled_for_disk_encryption = True properties.enabled_for_template_deployment = True vault = VaultCreateOrUpdateParameters(self._config.location, properties) self._mgmt_client.vaults.create_or_update(self._config.resource_group, name, vault) print('vault %s created\n' % name) def _display_selected_vault_detail(self): print('\nName:\t%s' % self._selected_vault.name) print('Uri:\t%s' % self._selected_vault.properties.vault_uri) print('Id:\t%s' % self._selected_vault.id) print( '\n(s)ecrets | (k)eys | (c)ertificates | (e)ncrypt | (d)ecrypt | (b)ack | (q)uit\n' ) def _vault_detail_loop(self): while self._continue_repl( self._display_selected_vault_detail, break_commands=KV_Repl._repl_break_commands) is not None: if self._selection == 's' or self._selection == 'secrets': self._secret_index_loop() elif self._selection == 'k' or self._selection == 'keys': self._key_index_loop() elif self._selection == 'c' or self._selection == 'certificates': print('\nnot yet implemented\n') elif self._selection == 'e' or self._selection == 'encrypt': self._encrypt_file() else: print('invalid input') def _encrypt_file(self): while True: inpath = input('input file: ') if os.path.isfile(inpath): break else: print('error: file not found') while True: outpath = input('output file: ') @staticmethod def _prompt_for_file_path(prompt, verify_exists): inpath = input(prompt) def _display_secret_index(self): self._current_index = [] secret_iter = self._data_client.get_secrets( self._selected_vault.properties.vault_uri) if secret_iter is not None: try: self._current_index = [secret for secret in secret_iter] except TypeError: pass print('\n%s Secrets:\n' % self._selected_vault.name) for idx, s in enumerate(self._current_index): print('%d. %s' % (idx, KV_Repl._get_name_from_url(s.id))) print('\n#:show secret value (a)dd (d)elete (b)ack (q)uit\n') def _secret_index_loop(self): while self._continue_repl( self._display_secret_index, break_commands=KV_Repl._repl_break_commands) is not None: secrets = self._current_index if isinstance(self._selection, int): i = self._selection if i >= 0 and i < len(secrets): print('\n%s = %s\n' % (KV_Repl._get_secret_name_from_url(secrets[i].id), self._data_client.get_secret(secrets[i].id).value)) else: print('invalid secret index') elif self._selection == 'a' or self._selection == 'add': self._add_secret() elif self._selection == 'd' or self._selection == 'delete': print('\nnot yet implemented\n') def _add_secret(self): secret_name = input('\nSecret Name: ') secret_value = input('Secret Value: ') self._data_client.set_secret(self._selected_vault.properties.vault_uri, secret_name, secret_value) print('\nSecret %s added to vault %s' % (secret_name, self._selected_vault.name)) def _display_key_index(self): self._current_index = [] key_iter = self._data_client.get_keys( self._selected_vault.properties.vault_uri) if key_iter is not None: try: self._current_index = [secret for secret in key_iter] except TypeError: print('warning: caught TypeError') pass print('\n%s Keys:\n' % self._selected_vault.name) for idx, k in enumerate(self._current_index): print('%d. %s' % (idx, KV_Repl._get_name_from_url(k.kid))) print('\n#:get key | (a)dd | (i)mport | (d)elete | (b)ack | (q)uit\n') def _key_index_loop(self): while self._continue_repl( self._display_key_index, break_commands=KV_Repl._repl_break_commands) is not None: keys = self._current_index if isinstance(self._selection, int): i = self._selection if i >= 0 and i < len(keys): print('\n%s = %s\n' % (KV_Repl._get_secret_name_from_url(keys[i].id), self._data_client.get_secret(keys[i].id).value)) else: print('invalid key index') elif self._selection == 'a' or self._selection == 'add': self._add_key() elif self._selection == 'd' or self._selection == 'delete': print('\nnot yet implemented\n') def _add_key(self): key_name = input('\nKey Name: ') self._data_client.create_key(self._selected_vault.properties.vault_uri, key_name, kty=JsonWebKeyType.rsa.value) print('\nSecret %s added to vault %s' % (key_name, self._selected_vault.name)) @staticmethod def _get_name_from_url(url): split = url.split('/') return split[len(split) - 1] def _get_vault_list(self): vault_list = [vault for vault in self._mgmt_client.vaults.list()] return vault_list
class AzureRMKeyVaultSecret(AzureRMModuleBase): ''' Module that creates or deletes secrets in Azure KeyVault ''' def __init__(self): self.module_arg_spec = dict(secret_name=dict(type='str', required=True), secret_value=dict(type='str', no_log=True), keyvault_uri=dict(type='str', required=True), state=dict(type='str', default='present', choices=['present', 'absent'])) required_if = [('state', 'present', ['secret_value'])] self.results = dict(changed=False, state=dict()) self.secret_name = None self.secret_value = None self.keyvault_uri = None self.state = None self.data_creds = None self.client = None self.tags = None super(AzureRMKeyVaultSecret, self).__init__(self.module_arg_spec, supports_check_mode=True, required_if=required_if, supports_tags=True) def exec_module(self, **kwargs): for key in list(self.module_arg_spec.keys()) + ['tags']: setattr(self, key, kwargs[key]) # Create KeyVault Client using KeyVault auth class and auth_callback def auth_callback(server, resource, scope): if self.credentials['client_id'] is None or self.credentials[ 'secret'] is None: self.fail( 'Please specify client_id, secret and tenant to access azure Key Vault.' ) tenant = self.credentials.get('tenant') if not self.credentials['tenant']: tenant = "common" authcredential = ServicePrincipalCredentials( client_id=self.credentials['client_id'], secret=self.credentials['secret'], tenant=tenant, resource="https://vault.azure.net") token = authcredential.token return token['token_type'], token['access_token'] self.client = KeyVaultClient(KeyVaultAuthentication(auth_callback)) results = dict() changed = False try: results['secret_id'] = self.get_secret(self.secret_name) # Secret exists and will be deleted if self.state == 'absent': changed = True except KeyVaultErrorException: # Secret doesn't exist if self.state == 'present': changed = True self.results['changed'] = changed self.results['state'] = results if not self.check_mode: # Create secret if self.state == 'present' and changed: results['secret_id'] = self.create_secret( self.secret_name, self.secret_value, self.tags) self.results['state'] = results self.results['state']['status'] = 'Created' # Delete secret elif self.state == 'absent' and changed: results['secret_id'] = self.delete_secret(self.secret_name) self.results['state'] = results self.results['state']['status'] = 'Deleted' else: if self.state == 'present' and changed: self.results['state']['status'] = 'Created' elif self.state == 'absent' and changed: self.results['state']['status'] = 'Deleted' return self.results def get_secret(self, name, version=''): ''' Gets an existing secret ''' secret_bundle = self.client.get_secret(self.keyvault_uri, name, version) if secret_bundle: secret_id = KeyVaultId.parse_secret_id(secret_bundle.id) return secret_id.id def create_secret(self, name, secret, tags): ''' Creates a secret ''' secret_bundle = self.client.set_secret(self.keyvault_uri, name, secret, tags) secret_id = KeyVaultId.parse_secret_id(secret_bundle.id) return secret_id.id def delete_secret(self, name): ''' Deletes a secret ''' deleted_secret = self.client.delete_secret(self.keyvault_uri, name) secret_id = KeyVaultId.parse_secret_id(deleted_secret.id) return secret_id.id
def run_example(): """Keyvault management example.""" # # Create the Resource Manager Client with an Application (service principal) token provider # # By Default, use AzureStack supported profile KnownProfiles.default.use(KnownProfiles.v2018_03_01_hybrid) credentials, subscription_id, mystack_cloud = get_credentials() kv_dp_credentials, sub_id, mystack = get_credentials() kv_client = KeyVaultManagementClient( credentials, subscription_id, base_url=mystack_cloud.endpoints.resource_manager) resource_client = ResourceManagementClient( credentials, subscription_id, base_url=mystack_cloud.endpoints.resource_manager) kv_data_client = KeyVaultClient(kv_dp_credentials) # You MIGHT need to add KeyVault as a valid provider for these credentials # If so, this operation has to be done only once for each credentials resource_client.providers.register('Microsoft.KeyVault') # Create Resource group print('Create Resource Group') resource_group_params = {'location': LOCATION} print_item( resource_client.resource_groups.create_or_update( GROUP_NAME, resource_group_params)) # Create a vault print('\nCreate a vault') vault = kv_client.vaults.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': os.environ['AZURE_OBJECT_ID'], 'permissions': { 'keys': ['all'], 'secrets': ['all'] } }] } }) print_item(vault) # set and get a secret from the vault to validate the client is authenticated print('creating secret...') secret_bundle = kv_data_client.set_secret( vault.properties.vault_uri, 'auth-sample-secret', 'client is authenticated to the vault') print(secret_bundle) print('getting secret...') secret_bundle = kv_data_client.get_secret( vault.properties.vault_uri, 'auth-sample-secret', secret_version=KeyVaultId.version_none) print(secret_bundle) # List the Key vaults print('\nList KeyVaults') for vault in kv_client.vaults.list(): print_item(vault) # Delete keyvault print('\nDelete Keyvault') kv_client.vaults.delete(GROUP_NAME, KV_NAME) # Delete Resource group and everything in it print('\nDelete Resource Group') delete_async_operation = resource_client.resource_groups.delete(GROUP_NAME) delete_async_operation.wait() print("\nDeleted: {}".format(GROUP_NAME))
class AzureRMKeyVaultSecret(AzureRMModuleBase): ''' Module that creates or deletes secrets in Azure KeyVault ''' def __init__(self): self.module_arg_spec = dict( secret_name=dict(type='str', required=True), secret_value=dict(type='str', aliases=['secret'], no_log=True), keyvault_uri=dict(type='str', required=True), state=dict(type='str', default='present', choices=['present', 'absent']) ) required_if = [ ('state', 'present', ['secret_value']) ] self.results = dict( changed=False, state=dict() ) self.secret_name = None self.secret_value = None self.keyvault_uri = None self.state = None self.data_creds = None self.client = None self.tags = None super(AzureRMKeyVaultSecret, self).__init__(self.module_arg_spec, supports_check_mode=True, required_if=required_if, supports_tags=True) def exec_module(self, **kwargs): for key in list(self.module_arg_spec.keys()) + ['tags']: setattr(self, key, kwargs[key]) # Create KeyVault Client using KeyVault auth class and auth_callback self.client = KeyVaultClient(self.azure_credentials) results = dict() changed = False try: results['secret_id'] = self.get_secret(self.secret_name) # Secret exists and will be deleted if self.state == 'absent': changed = True except KeyVaultErrorException: # Secret doesn't exist if self.state == 'present': changed = True self.results['changed'] = changed self.results['state'] = results if not self.check_mode: # Create secret if self.state == 'present' and changed: results['secret_id'] = self.create_secret(self.secret_name, self.secret_value, self.tags) self.results['state'] = results self.results['state']['status'] = 'Created' # Delete secret elif self.state == 'absent' and changed: results['secret_id'] = self.delete_secret(self.secret_name) self.results['state'] = results self.results['state']['status'] = 'Deleted' else: if self.state == 'present' and changed: self.results['state']['status'] = 'Created' elif self.state == 'absent' and changed: self.results['state']['status'] = 'Deleted' return self.results def get_secret(self, name, version=''): ''' Gets an existing secret ''' secret_bundle = self.client.get_secret(self.keyvault_uri, name, version) if secret_bundle: secret_id = KeyVaultId.parse_secret_id(secret_bundle.id) return secret_id.id def create_secret(self, name, secret, tags): ''' Creates a secret ''' secret_bundle = self.client.set_secret(self.keyvault_uri, name, secret, tags) secret_id = KeyVaultId.parse_secret_id(secret_bundle.id) return secret_id.id def delete_secret(self, name): ''' Deletes a secret ''' deleted_secret = self.client.delete_secret(self.keyvault_uri, name) secret_id = KeyVaultId.parse_secret_id(deleted_secret.id) return secret_id.id