예제 #1
0
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}')
예제 #2
0
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)
예제 #3
0
    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)
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
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=(',', ': '))
예제 #7
0
        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")
예제 #8
0
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
예제 #9
0
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)")