def main(): # 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'] kv_name = config_data['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) #token = credentials.token #print('Token is: ' + token['access_token']) # get a key vault client client = KeyVaultClient(credentials) # list the secrets secrets = client.get_secrets(key_vault_uri) print('Listing secrets') for secret_item in secrets: secret_name = secret_item.id.split('/secrets/', 1)[1] secret_bundle = client.get_secret(key_vault_uri, secret_name, '') print(f'{secret_name}: {secret_bundle.value}')
def main(argv): if len(sys.argv) < 3: raise ValueError( 'Expecting vault_url, client_id, clientSecretKey,tenant_id') vault_url = sys.argv[1] client_id = sys.argv[2] secretKey = sys.argv[3] tenant_id = sys.argv[4] credentials = ServicePrincipalCredentials(client_id=client_id, secret=secretKey, tenant=tenant_id, resource=resource_uri) client = KeyVaultClient(KeyVaultAuthentication(None, credentials)) token = credentials.token token_type = token['token_type'] access_token = token['access_token'] secrets = client.get_secrets(vault_url) secretsData = {} for secret in secrets: secretName = secret.id.rsplit('/', 1)[-1] secretItem = client.get_secret(vault_url, secretName, '') secretVersion = secretItem.id.rsplit('/', 1)[-1] secretsData[secretName] = secretVersion json_data = json.dumps(secretsData) print(json_data)
def _process_key_vault(self, key_vault_index, key_vault_name, rg_name, sub_index, sub): """Get details of Key Vault in management and data plane. Arguments: sub_index (int): Subscription index (for logging only). sub (Subscription): Azure subscription object. rg_name (str): Resource group name. key_vault_index (int): Key Vault index (for logging only). key_vault_name (str): Name of the Key Vault. Yields: dict: An Azure Key Vault server record. """ def _auth_callback(server, resource, scope): credentials = self._key_vault_credentials token = credentials.token return token['token_type'], token['access_token'] _log.info('Working on key_vault #%d: %s; %s', key_vault_index, key_vault_name, util.outline_az_sub(sub_index, sub, self._tenant)) subscription_id = sub.get('subscription_id') creds = self._credentials key_vault_mgmt_client = KeyVaultManagementClient( creds, subscription_id) key_vault_details = key_vault_mgmt_client.vaults.get( rg_name, key_vault_name) yield from _get_normalized_key_vault_record(key_vault_details, sub) try: kv_client = \ KeyVaultClient(KeyVaultAuthentication(_auth_callback)) secrets = \ kv_client.get_secrets(key_vault_details.properties.vault_uri) keys = \ kv_client.get_keys(key_vault_details.properties.vault_uri) # Retrieve data using each iterator. for record in itertools.chain( _get_data_record(secrets, 'key_vault_secret', sub_index, sub, self._tenant), _get_data_record(keys, 'key_vault_key', sub_index, sub, self._tenant), ): yield record except CloudError as e: _log.error('Failed to fetch key vault details; %s; error: %s: %s', util.outline_az_sub(sub_index, sub, self._tenant), type(e).__name__, e)
def _retrieve_secrets(self, client: AzureKeyVaultClient, vault: str, prefix: Optional[str]) -> List[Secret]: secrets = list(client.get_secrets(vault)) secrets_ids = self._extract_keyvault_ids_from(secrets) secrets_filtered = self._filter_keyvault_ids(secrets_ids, prefix) app_secrets = [ Secret(_.databricks_secret_key, client.get_secret(vault, _.keyvault_id, "").value) for _ in secrets_filtered ] return app_secrets
def get_secrets(self): """Get all of the secrets from Key Vault. Requires List permission. Returns a list of SecretItem objects as documented here: https://docs.microsoft.com/en-us/python/api/azure-keyvault/azure.keyvault.v7_0.models.secret_item_py3.secretitem?view=azure-python """ credentials = ServicePrincipalCredentials( client_id=self._config["client_id"], secret=self._config["app_secret"], tenant=self._config["tenant_id"], ) client = KeyVaultClient(credentials) try: secrets = client.get_secrets(self._config["key_vault_uri"]) except KeyVaultErrorException: secrets = [] return secrets
class KeyVaultSampleBase(object): """Base class for Key Vault samples, provides common functionality needed across Key Vault sample code :ivar config: Azure subscription id for the user intending to run the sample :vartype config: :class: `KeyVaultSampleConfig`q :ivar credentials: Azure Active Directory credentials used to authenticate with Azure services :vartype credentials: :class: `ServicePrincipalCredentials <msrestazure.azure_active_directory.ServicePrincipalCredentials>` :ivar keyvault_data_client: Key Vault data client used for interacting with key vaults :vartype keyvault_data_client: :class: `KeyVaultClient <azure.keyvault.KeyVaultClient>` :ivar keyvault_mgmt_client: Key Vault management client used for creating and managing key vaults :vartype keyvault_mgmt_client: :class: `KeyVaultManagementClient <azure.mgmt.keyvault.KeyVaultManagementClient>` :ivar resource_mgmt_client: Azure resource management client used for managing azure resources, access, and groups :vartype resource_mgmt_client: :class: `ResourceManagementClient <azure.mgmt.resource.ResourceManagementClient>` """ def __init__(self): self.config = KeyVaultSampleConfig() self.credentials = None self.keyvault_data_client = None self.keyvault_mgmt_client = None self.resource_mgmt_client = None self._setup_complete = False self.samples = {(name, m) for name, m in inspect.getmembers(self) if getattr(m, 'kv_sample', False)} models = {} models.update({ k: v for k, v in azure.keyvault.models.__dict__.items() if isinstance(v, type) }) models.update({ k: v for k, v in azure.mgmt.keyvault.models.__dict__.items() if isinstance(v, type) }) self._serializer = Serializer(models) def setup_sample(self): """ Provides common setup for Key Vault samples, such as creating rest clients, creating a sample resource group if needed, and ensuring proper access for the service principal. :return: None """ if not self._setup_complete: self.mgmt_creds = ServicePrincipalCredentials( client_id=self.config.client_id, secret=self.config.client_secret, tenant=self.config.tenant_id) self.data_creds = ServicePrincipalCredentials( client_id=self.config.client_id, secret=self.config.client_secret, tenant=self.config.tenant_id) self.resource_mgmt_client = ResourceManagementClient( self.mgmt_creds, self.config.subscription_id) # ensure the service principle has key vault as a valid provider self.resource_mgmt_client.providers.register('Microsoft.KeyVault') # ensure the intended resource group exists self.resource_mgmt_client.resource_groups.create_or_update( self.config.group_name, {'location': self.config.location}) self.keyvault_mgmt_client = KeyVaultManagementClient( self.mgmt_creds, self.config.subscription_id) self.keyvault_data_client = KeyVaultClient(self.data_creds) self._setup_complete = True def create_vault(self): """ Creates a new key vault with a unique name, granting full permissions to the current credentials :return: a newly created key vault :rtype: :class:`Vault <azure.keyvault.generated.models.Vault>` """ vault_name = get_name('vault') # setup vault permissions for the access policy for the sample service principle permissions = Permissions() permissions.keys = KEY_PERMISSIONS_ALL permissions.secrets = SECRET_PERMISSIONS_ALL permissions.certificates = CERTIFICATE_PERMISSIONS_ALL policy = AccessPolicyEntry(self.config.tenant_id, self.config.client_oid, permissions) properties = VaultProperties(self.config.tenant_id, Sku(name='standard'), access_policies=[policy]) parameters = VaultCreateOrUpdateParameters(self.config.location, properties) parameters.properties.enabled_for_deployment = True parameters.properties.enabled_for_disk_encryption = True parameters.properties.enabled_for_template_deployment = True print('creating vault {}'.format(vault_name)) vault = self.keyvault_mgmt_client.vaults.create_or_update( self.config.group_name, vault_name, parameters) # wait for vault DNS entry to be created # see issue: https://github.com/Azure/azure-sdk-for-python/issues/1172 self._poll_for_vault_connection(vault.properties.vault_uri) print('created vault {} {}'.format(vault_name, vault.properties.vault_uri)) return vault def _poll_for_vault_connection(self, vault_uri, retry_wait=10, max_retries=4): """ polls the data client 'get_secrets' method until a 200 response is received indicating the the vault is available for data plane requests """ last_error = None for x in range(max_retries - 1): try: # sleep first to avoid improper DNS caching time.sleep(retry_wait) self.keyvault_data_client.get_secrets(vault_uri) return except ClientRequestError as e: print('vault connection not available') last_error = e raise last_error def _serialize(self, obj): if isinstance(obj, Paged): serialized = [self._serialize(i) for i in list(obj)] else: serialized = self._serializer.body(obj, type(obj).__name__) return json.dumps(serialized, indent=4, separators=(',', ': '))
secret = dbutils.widgets.get("MySID"), # 'g0DeEFCo8DP5Cj/m84peUDR+66HlMZCdlemQdfcYk1Q=', tenant = dbutils.widgets.get("MyTID"), # '72f988bf-86f1-41af-91ab-2d7cd011db47', resource = 'https://vault.azure.net' ) # dbutils.widgets.removeAll() token = credentials.token return token['token_type'], token['access_token'] client = KeyVaultClient(KeyVaultAuthentication(auth_callack)) # key_bundle = client.get_key(vault_url, key_name, key_version) # json_key = key_bundle.key # COMMAND ---------- secrets = client.get_secrets(KEY_VAULT_URI) myversion = "0" for sec in secrets: if sec.id.rsplit('/')[4] == workingdir: print(sec.id.rsplit('/')[4] + ' Match') versions = client.get_secret_versions(KEY_VAULT_URI, workingdir) for version in versions: if version.attributes.enabled: print(version) myversion = version.id.rsplit('/')[5] print(myacversion) else: print(sec.id.rsplit('/')[4] + ' No Match') if myversion == "0": dbutils.notebook.exit("no secret found")
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 AzureSecrets: """ Azure secrets object that can be used for CLI and as a module. """ def __init__(self, vault_base_url: str = None, client_id: str = None, secret: str = None, tenant: str = None): self.vault_base_url = vault_base_url self.client_id = client_id self.secret = secret self.tenant = tenant try: if self.vault_base_url is None: self.vault_base_url = os.environ["AZURE_VAULT_BASE_URL"] if self.client_id is None: self.client_id = os.environ['AZURE_CLIENT_ID'] if self.secret is None: self.secret = os.environ['AZURE_SECRET_KEY'] if self.tenant is None: self.tenant = os.environ['AZURE_TENANT_ID'] except KeyError as e: print("Did you forget to set the environment variable?", e) sys.exit(1) self.client = KeyVaultClient(KeyVaultAuthentication(_auth_callback)) def get_secret(self, secret_name: str, secret_version: str = None) -> str: """ Get the value for the secret key. :param secret_name: Name of the secret key. :type secret_name: str :param secret_version: The version string of the secret key. :type secret_version: str :return: The secret value. :rtype: str >>> secrets = AzureSecrets('https://', 'client id', 'secret key', 'tenant id') >>> print(secrets.get_secret('secret-name')) secret-value """ if secret_version is None: secret_version = os.environ.get("SECRET_VERSION", "") key_bundle = self.client.get_secret(self.vault_base_url, secret_name, secret_version) return key_bundle.value def get_secrets(self, env_names: list = None) -> dict: """ A dictionary of secret name and it's value. :param env_names: A list of secret names. :type env_names: list :rtype: dict :return: Dictionary of secrets. >>> secrets = AzureSecrets('https://', 'client id', 'secret key', 'tenant id') >>> print(secrets.get_secret(['secret-name-1', 'secret-name-2'])) { 'secret-name-1' : 'secret-value-1', 'secret-name-2': 'secret-value-2' } """ secrets = {} key_bundle = self.client.get_secrets(self.vault_base_url) try: if env_names is None: for secret_id in key_bundle: _secret_id = secret_id.as_dict()['id'].split('/').pop() secrets.update( {_secret_id: self.get_secret(secret_name=_secret_id)}) else: for secret_name in env_names: secrets.update({ secret_name: self.get_secret(secret_name=secret_name) }) except KeyVaultErrorException as e: print("Error:", e) sys.exit(1) return secrets def env_powershell(self, secret_names: list = None): """ Prints environment variable for PowerShell """ for key, value in self.get_secrets(secret_names).items(): print('$Env:{0}="{1}"'.format(key.replace('-', "_"), value)) print("# Run this command to configure your shell:") print("# & secrets env --shell powershell | Invoke-Expression") def env_cmd(self, secret_names: list = None): """ Prints environment variable for CMD """ for key, value in self.get_secrets(secret_names).items(): print("SET {0}={1}".format(key, value)) print("REM Run this command to configure your shell:") print( "REM @FOR /f \"tokens=*\" %i IN ('secrets env --shell cmd') DO @%i" ) def env_bash(self, secret_names: list = None): """ Prints environment variable for Bash """ for key, value in self.get_secrets(secret_names).items(): print("export {0}={1}".format(key, value)) print("# Run this command to configure your shell:") print("# eval $(secrets env --shell bash)")