how to list and find all the secrets in the keyvault which is to be expired in next 60 days?

379 Views Asked by At

As Azure Runbook has some limitation to integrate with Azuredevops server pipeline, which is hosted in onprem, we were looking for a bash script to find the secret in a listed keyvault list and if the secrets in the keyvault is about to expire in next 60 days only, then trigger the release pipeline with the specific secret and kv to extend the date to next 2 years followed by the release approval. We are struggling here to find the secret with its expire and to estimate the remaining days

(az keyvault secret list  --vault-name kv-01  --query "[?attributes.expires  ].{Id:id, expires:attributes.expires}" | jq '.[].expires' '+%s'

Looping through keyvaults failing

             inlineScript: |
                 #Azure Key Vault details
                 keyvaults=$(az keyvault list --query "[].{Name:name}")
                 echo "keyvaults are as below $keyvaults"
                 #Iterate through the kvs
                 for row in $(echo "${keyvaults}" | jq -c '.[]'); do
                     keyVaultName=$(echo "$row" | jq -r '.Name') 
                     done             
                     #Get the current date in UTC
                     currentDate=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
                     echo "currentDate is $currentDate".....
.................<As same as given in the same accepted answer>.......................

..................... .

3

There are 3 best solutions below

1
Venkat V On BEST ANSWER

how to list and find all the secrets in the keyvault which is to be expired in next 60 days?

To find secrets in an Azure Key Vault that are going to expire in the next 60 days and to estimate the remaining days for each secret, you can use the below bash script.

   
#Azure Key Vault details
keyVaultName="Keyvault name"

#Get the current date in UTC
currentDate=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

#Get a list of secrets in the Key Vault
secrets=$(az keyvault secret list --vault-name $keyVaultName --query "[].{Name:name, Expires:attributes.expires}")

#Iterate through the secrets
for row in $(echo "${secrets}" | jq -c '.[]'); do
    secretName=$(echo "$row" | jq -r '.Name')
    expirationDate=$(echo "$row" | jq -r '.Expires')

    # Check if the secret is already expired
    if [ "$(date -u +"%s")" -gt "$(date -u -d "$expirationDate" +"%s")" ]; then
        echo "Output-------------------------------------"
        echo "Expired: Secret $secretName has already expired on $expirationDate."

    else
        # Calculate the remaining days until expiration
        remainingDays=$(( ($(date -u -d "$expirationDate" +"%s") - $(date -u -d "$currentDate" +"%s")) / 86400 ))

        # Check if the secret is about to expire (within the next 60 days)
        if [ $remainingDays -lt 60 ]; then
            echo "About to Expire in 60 days : Secret $secretName is about to expire in $remainingDays days. Expiration Date: $expirationDate"

            # Trigger Azure DevOps release pipeline
            echo "Triggering Azure DevOps release pipeline..."
            # add your script to trigger the Azure DevOps release pipeline

        else
            echo "Not Expiring Soon: Secret $secretName is not expiring in 60 days. It's about to expire in $remainingDays days. Expiration Date: $expirationDate"
        fi
    fi
done

The above script will display already expired secrets, secrets about to expire in 60 days, and secrets that are not yet expired in the Key Vault.

Output:

enter image description here

2
Miao Tian-MSFT On

I can list and find all the secrets in the Azure Key Vault which are set to expire in the next 60 days, and then extend their expiration date to the next 2 years with the following yaml.

trigger:
- none

pool:
  vmImage: windows-latest

steps:
- task: AzureCLI@2
  inputs:
    azureSubscription: 'service connection name'
    scriptType: 'bash'
    scriptLocation: 'inlineScript'
    inlineScript: |
      # Set your vault name
      vault_name="my vault name"
      # Get the current date and the date 60 days from now in Unix epoch format to compare dates and times
      current_date=$(date -u +%s)
      expiry_date=$(date -u -d "60 days" +%s)
      # Get the date 2 years from now 
      new_expiry_date=$(date -d "+2 years" -u +%Y-%m-%dT%H:%M:%SZ)
      # List all secrets in the vault , get the id and attributes.expires
      secrets=$(az keyvault secret list --vault-name $vault_name --query "[].{id: id, exp: attributes.expires}" -o tsv)
      # Loop through the secrets
      while IFS=$'\t' read -r -a secret; do
        # Get the secret id and expiry date
        secret_id=${secret[0]}
        secret_expiry=${secret[1]}
        # If the secret has an expiry date
        if [ ! -z "$secret_expiry" ]; then
          # Convert the expiry date to Unix epoch format
          secret_expiry_seconds=$(date -u -d "$secret_expiry" +%s)
          # If the secret is set to expire in the next 60 days
          if (( secret_expiry_seconds > current_date && secret_expiry_seconds < expiry_date )); then
            # Extend the expiry date to 2 years from now
            echo "The secret $secret_id will expiry in 60 days. Extended the expiry date to $new_expiry_date"
            az keyvault secret set-attributes --vault-name $vault_name --name $(basename $secret_id) --expires $new_expiry_date
          else
            echo "The secret $secret_id will not expiry in 60 days."
          fi
        fi
      done <<< "$secrets"

My test Sample:

Before run, the secret 1 and secret 2 will expiry in 60 days:

enter image description here

Run the pipeline and this is the pipeline log: enter image description here

Result:

enter image description here

0
Thomas On

You can filter the secrets without looping (see How to query Azure CLI command output using a JMESPath query):

keyVaultName="thomastestkv"
expirationDate=$(date +%Y-%m-%dT%H:%M:%SZ -d '+60 days')

az keyvault secret list \
  --vault-name $keyVaultName \
  --query "[?attributes.expires <= '$expirationDate'].{Id:id, expires:attributes.expires}"

If you don't need the secrets that have already expired, you could do something like that:

keyVaultName="thomastestkv"
today=$(date +%Y-%m-%dT%H:%M:%SZ)
expirationDate=$(date +%Y-%m-%dT%H:%M:%SZ -d '+60 days')

az keyvault secret list \
  --vault-name $keyVaultName \
  --query "[?attributes.expires >= '$today' && attributes.expires <= '$expirationDate'].{Id:id, expires:attributes.expires}"

Also see existing post: