vcsjones / AzureSignTool

SignTool Library and Azure Key Vault Support
MIT License
267 stars 85 forks source link

File 'CertName' does not exist. #255

Open rkg-mm opened 2 months ago

rkg-mm commented 2 months ago

This is likely not a bug but a mistake on my side, however I struggle to get this working with an RBAC enabled KeyVault via service connection, and wonder if there could be some details in the docs provided in the permissions necessary for RBAC, or some help if my issue is of totally different nature, since the error message is quiet strange.

I receive the error File 'CertName' does not exist. when running command

AzureSignTool sign -kvu "REDACTED" -kvi $Env:servicePrincipalId -kvt $Env:tenantId -kvs $Env:servicePrincipalKey -kvc CertName -tr "http://timestamp.digicert.com" -v D:\a\1/build/binaries/test.exe

I am running it via AzureCLI@2 Task like this:

- task: AzureCLI@2
  displayName: 'Sign'
  inputs:
    scriptType: ps
    scriptLocation: inlineScript
    azureSubscription: '${{ parameters.keyVaultServiceConnection }}'
    addSpnToEnvironment: true
    inlineScript: |
      AzureSignTool sign -kvu "${{ parameters.keyVaultUrl }}" -kvi $Env:servicePrincipalId -kvt $Env:tenantId -kvs $Env:servicePrincipalKey -kvc ${{ parameters.azureKeyVaultSigningCertificateName }} -tr "http://timestamp.digicert.com" -v $(binaries)

The certificate exists under the name "CertName" in the KeyVault. The service connection passed to "azureSubscription" does have access to the key vault (i even gave it Admin permissions on the vault in the end while testing).

So:

  1. Is this error related to missing permissions on the certificate?
  2. If yes, can anyone please explain which RBAC permissions are required to the vault (and possibly the certificate itself)? Maybe this could be added to the docs?

Thanks in advance!

edit: After looking through the source I think the message is from here https://github.com/vcsjones/AzureSignTool/blob/078c7620e590e0841ec4fa4e06cb045e7574a5d1/src/AzureSignTool/Program.cs#L501 , wouldn't that mean that the parameter is recognized as a file parameter instead the certificate parameter? If i delete the whole parameter it is bringing the same error with the next parameter (timestamp url), which sounds strange to me...

rkg-mm commented 2 months ago

Ok this indeed is not a bug, i traced it down - still not sure what the solution is though. the $env:servicePrincipalKey is not provided by AzureCliTask, even though I set addSpnToEnvironment:true. However, the other 2 values and the value "$env:idToken" are provided instead. Not sure how to use that idToken? I think it has to do with using federation identity in the service connection, instead of a client secret. Is there a way to use it this way?

edit, ok switching the service connection to type "service principal" instead of using federation type, it seems to work. Except wrong RBAC permissions, which I still need to figure out which ones are required.

So I would leave this open with 2 requests to save other some headaches:

  1. could you describe how this works using federated identities (or add a hint in the docs that this cannot be used if its not supported)
  2. Could you please also list the required RBAC permissions in https://github.com/vcsjones/AzureSignTool/blob/main/WALKTHROUGH.md? Its either combination of "KeyVault Crypto User" and "KeyVault Reader", or, if you want to strip it down to the absolute minimum with a custom role, then use this for custom role:
    "permissions": [
    {
        "actions": [],
        "notActions": [],
        "dataActions": [
            "Microsoft.KeyVault/vaults/certificates/read",
            "Microsoft.KeyVault/vaults/keys/read",
            "Microsoft.KeyVault/vaults/keys/sign/action",
            "Microsoft.KeyVault/vaults/keys/verify/action"
        ],
        "notDataActions": []
    }
    ]
PAKalucki commented 1 month ago

I have faced similiar issue in Azure DevOps when using AzureSignTool. My current workaround is to get the access token with az cli and then pass that directly to AzureSignTool. It would be nice if AzureSignTool supported federated authentication as it is now recommended way of authenticating with Azure from Azure DevOps.

My workaround if anyone wants to use it:

      - task: AzureCLI@2
        displayName: 'Sign with AzureSignTool'
        inputs:
          scriptType: ps
          scriptLocation: inlineScript
          azureSubscription: xyz
          addSpnToEnvironment: true
          inlineScript: |
            $accessToken = az account get-access-token --resource "https://vault.azure.net"  --query "accessToken" --output tsv
            AzureSignTool sign -du "https://www.xyz.com" -kvu "https://xyz.vault.azure.net" -kva $accessToken -kvc "xyz" -v "$(Build.ArtifactStagingDirectory)\xyz.msi"

On a side note I think displaying "File 'CertName' does not exist" as an error when there is authentication issue should be considered a bug.