en-US/about_AuthenticodeAzureKeys.help.txt
TOPIC
about_authenticodeazurekeys SHORT DESCRIPTION OpenAuthenticode can use an Azure KeyVault certificate and key to sign data without having the key leave the vault. It sends the data that needs to be signed, typically a hash, to the Azure API and receives the signature back from that operation. This guide will demonstrate how to easily set up an Azure App Principal through the Azure CLI that can be used for this operation. It assumes that an Azure KeyVault and signing certificate has already been created/imported. LONG DESCRIPTION The following is a bash script that can be used to generate an Azure App Principal that can be used with Get-OpenAuthenticodeAzKey to sign files. The `APP_NAME`, `RESOURCE_GROUP`, `VAULT_NAME`, and `VAULT_CERT` variables need to be prefilled before running the code. It also requires the Azure CLI to be installed, otherwise run this in `docker run -it mcr.microsoft.com/azure-cli` where the cli is already available. # The name of the app principal granted access APP_NAME="..." # The name of the resource group the vault is stored in RESOURCE_GROUP="..." # The name of the Azure KeyVault. VAULT_NAME="..." # The name of the certificate in the above vault to use for signing VAULT_CERT="..." ROLE_NAME="KeyVault PowerShell-OpenAuthenticode" SUBSCRIPTION_ID="$( az login | jq -r '.[].id' )" ROLE_INFO="$( az role definition list \ --name "${ROLE_NAME}" \ --custom-role-only \ --resource-group "${RESOURCE_GROUP}" )" if [ "${ROLE_INFO}" == "[]" ]; then ROLE_DEF="$(cat << EOF { "Name": "${ROLE_NAME}", "Description": "Allow access to a cert for Authenticode signing with PowerShell-OpenAuthenticode.", "Actions": [], "DataActions": [ "Microsoft.KeyVault/vaults/certificates/read", "Microsoft.KeyVault/vaults/keys/sign/action" ], "NotDataActions": [], "AssignableScopes": ["/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}"] } EOF )" ROLE_INFO="$( az role definition create \ --role-definition "${ROLE_DEF}" )" ROLE_ID="$( echo "${ROLE_INFO}" | jq -r '.name' )" else ROLE_ID="$( echo "${ROLE_INFO}" | jq -r '.[].name' )" fi PRINCIPAL_INFO="$( az ad sp create-for-rbac \ --name "${APP_NAME}" \ )" AZURE_CREDENTIALS="$( echo "${PRINCIPAL_INFO}" | jq -r "{clientId: .appId, clientSecret: .password, tenantId: .tenant, vaultName: \"${VAULT_NAME}\", vaultCert: \"${VAULT_CERT}\"}" )" CLIENT_ID="$( echo "${PRINCIPAL_INFO}" | jq -r '.appId' )" az role assignment create \ --assignee "${CLIENT_ID}" \ --role "${ROLE_ID}" \ --scope "/subscriptions/${SUBSCRIPTION_ID}/resourceGroups/${RESOURCE_GROUP}/providers/Microsoft.KeyVault/vaults/${VAULT_NAME}" > /dev/null echo "Save this json as your GitHub Actions secret" echo "${AZURE_CREDENTIALS}" The resulting json contains all the information needed to sign files using OpenAuthenticode. # AZURE_CREDENTIALS contains the json from the above script $credInfo = ConvertFrom-Json -InputObject $env:AZURE_CREDENTIALS $vaultName = $credInfo.vaultName $vaultCert = $credInfo.vaultCert $env:AZURE_CLIENT_ID = $credInfo.clientId $env:AZURE_CLIENT_SECRET = $credInfo.clientSecret $env:AZURE_TENANT_ID = $credInfo.tenantId $key = Get-OpenAuthenticodeAzKey -Vault $vaultName -Certificate $vaultCert $env:AZURE_CLIENT_ID = '' $env:AZURE_CLIENT_SECRET = '' $env:AZURE_TENANT_ID = '' $signParams = @{ Key = $key TimeStampServer = 'http://timestamp.digicert.com' HashAlgorithm = 'SHA256' } Set-OpenAuthenticodeSignature -FilePath $path @signParams In this example the output json from the bash script has been stored in the environment variable `AZURE_CREDENTIALS`. Ensure the credentials json is stored securely so that it cannot be used for any unauthorised signing operations. |