Azure Sign Tool

repository·main·Indexed 18 days ago

https://github.com/vcsjones/azuresigntool

A utility for signing files using Azure-based code signing services, compatible with Windows SDK signtool mechanisms. It supports signing files using certificates stored in Azure Key Vault with authentication via Client Credentials, Access Tokens, or Managed Identity. The tool can be installed as a global .NET tool, via WinGet, or as a single-file executable.

Tokens
4.5K
Snippets
10
Records
17
Agent score
13%

What's inside Azure Sign Tool

  1. Supported file formats for signing

    main
    Azure Sign Tool uses the same signing mechanisms as the Windows SDK signtool. Consequently, it supports the same file formats as signtool. Note that the specific formats available depend on your operating system and the Subject Interface Packages (SIPs) installed on your system.
  2. Authenticate to Azure Key Vault

    main

    AzureSignTool supports several authentication methods to access your Key Vault:

    1. Client Credentials: Provide --azure-key-vault-client-id (-kvi), --azure-key-vault-client-secret (-kvs), and --azure-key-vault-tenant-id (-kvt).
    2. Access Token: Provide an existing token via --azure-key-vault-accesstoken (-kva). This bypasses the need for client ID/secret/tenant ID.
    3. Managed Identity: Use --azure-key-vault-managed-identity (-kvm) to use the ambient Managed Identity. This also supports existing sessions from Azure CLI, PowerShell, or Visual Studio credentials via the DefaultAzureCredential class.
  3. Prerequisites for using AzureSignTool with Azure Key Vault

    main

    Before using AzureSignTool to sign files, you must complete these preparations in your Azure subscription:

    1. Obtain a certificate.
    2. Create an Azure KeyVault: Note the KeyVault URL (e.g., https://[VAULT_ID].vault.azure.net).
    3. Upload the certificate: Upload your certificate into the KeyVault and assign it a name.
    4. Configure Access Policies: Ensure the identity (Service Principal or Application) used by your CI/CD tool has the following permissions in the KeyVault Access Policies:
    AreaPermissions
    KeySign
    SecretGet
    CertificateGet
  4. Cancelling a signing operation

    main
    You can cancel a signing operation using the standard Ctrl+C key sequence. When cancelled, the tool will finish any signing operations that are currently in flight before exiting. The final exit status code will reflect the outcome of the operations that were completed.
  5. System requirements for Azure Sign Tool

    main

    To run Azure Sign Tool, you need:

    • Operating System: Windows 10 or Windows Server 2016 (minimum).
    • Recommendation: Use Windows Server 2022 or later, as support for Windows Server 2016 is limited and some features require newer versions of Windows.
  6. Run AzureSignTool using dnx

    main

    If the .NET 10 SDK is installed, you can use dnx (an alias for dotnet dnx) to run AzureSignTool directly from NuGet without a separate installation step.

    To invoke the sign command:

    dnx AzureSignTool --yes sign <arguments>

    Note: Use --yes to automatically confirm the package installation. To ensure arguments are passed to the tool rather than dnx, use the -- separator:

    dnx AzureSignTool --yes -- --version
  7. Sign files in GitLab CI using Service Principal authentication

    main

    To sign files in GitLab CI using a Service Principal:

    1. Configure KeyVault: Grant the service principal Key: Sign, Secret: Get, and Certificate: Get permissions via Access Policies.
    2. Download Tool: Use Invoke-WebRequest to download the AzureSignTool-x64.exe binary.
    3. Execute: Run the executable using long-form parameter names. Ensure you have defined $AZURE_CLIENT_ID, $AZURE_CLIENT_SECRET, and $AZURE_TENANT_ID in your GitLab CI/CD variables.

    Parameter Mapping:

    • --azure-key-vault-url: KeyVault URL
    • --azure-key-vault-client-id: Client ID
    • --azure-key-vault-client-secret: Client Secret
    • --azure-key-vault-tenant-id: Tenant ID
    • --azure-key-vault-certificate: Certificate Name
    sign:
      stage: deploy
      image: mcr.microsoft.com/dotnet/sdk:8.0-windowsservercore-ltsc2019
      before_script:
        - Invoke-WebRequest https://github.com/vcsjones/AzureSignTool/releases/latest/download/AzureSignTool-x64.exe -OutFile AzureSignTool.exe
      script:
        - >
            .\AzureSignTool.exe sign 
            --azure-key-vault-url https://example.vault.azure.net/
            --azure-key-vault-client-id $AZURE_CLIENT_ID
            --azure-key-vault-client-secret $AZURE_CLIENT_SECRET
            --azure-key-vault-tenant-id $AZURE_TENANT_ID
            --azure-key-vault-certificate example-certificate
            --verbose 
            example.exe
      artifacts:
        paths:
          - example.exe
  8. Install AzureSignTool via Single-file Download

    main

    For environments without .NET installed (like non-.NET-centric CI pipelines), you can download self-contained executables from the GitHub releases page.

    Example for downloading and running the v7.0.0 ARM64 version:

    Invoke-WebRequest https://github.com/vcsjones/AzureSignTool/releases/download/v7.0.0/AzureSignTool-arm64.exe -OutFile AzureSignTool.exe
    .\AzureSignTool.exe
  9. Sign files in Azure DevOps using an existing Service Connection

    main

    If you already have an Azure DevOps service connection with service principal authentication, follow these steps:

    1. Configure KeyVault: Add an access policy to your KeyVault for the service principal used by your connection, granting Key: Sign, Secret: Get, and Certificate: Get permissions.
    2. Install the tool: Add a DotNetCoreCLI@2 task to your build configuration to install azuresigntool globally.
    3. Execute signing: Use the AzureCLI@2 task. This allows you to leverage environment variables (like $Env:servicePrincipalId) provided by the service connection to authenticate.

    Required Parameters Mapping:

    • -du: KeyVault URL
    • -kvi: Client ID (Service Principal ID)
    • -kvt: Tenant ID
    • -kvs: Client Secret (Service Principal Key)
    • -kvc: Certificate Name
    • -v: Files to sign
    # Install step
    - task: DotNetCoreCLI@2
      inputs:
        command: 'custom'
        custom: 'tool'
        arguments: 'install --global azuresigntool'
      displayName: Install AzureSignTool
    
    # Sign step
    - task: AzureCLI@2
      displayName: 'Sign outputted .exe with global AzureSignTool'
      inputs:
        scriptType: ps
        scriptLocation: inlineScript
        azureSubscription: '[YOUR_CONNECTION_NAME]'
        addSpnToEnvironment: true
        inlineScript: |
          AzureSignTool sign -du "[YOUR_URL]" -kvu "https://[VAULT_ID].vault.azure.net" -kvi $Env:servicePrincipalId -kvt $Env:tenantId -kvs $Env:servicePrincipalKey -kvc "[REDACTED_CERT_NAME]" -v [FILES_YOU_WANT_TO_SIGN]
  10. Install AzureSignTool via .NET Tool

    main

    You can install AzureSignTool as a global .NET tool using NuGet. It is recommended to specify an exact version (e.g., 7.0.1) or a major-minor version (e.g., 7.0.*) to avoid breaking changes from automatic major version updates.

    To install and run:

    dotnet tool install --global --version 7.0.1 AzureSignTool
    AzureSignTool.exe
  11. Sign files in GitLab CI using OIDC (JWT Tokens)

    main

    For a more secure approach in GitLab CI, use OpenID Connect (OIDC) with Federated Identity:

    1. Configure Federated Identity: Set up a federated identity for your service principal in Azure AD to trust GitLab.
    2. Configure KeyVault: Grant the service principal Key: Sign, Secret: Get, and Certificate: Get permissions.
    3. Setup GitLab Job:
      • Define id_tokens in your job configuration to obtain a GITLAB_OIDC_TOKEN.
      • In before_script, use az login with the --federated-token flag to authenticate the runner.
      • In script, use the --azure-key-vault-managed-identity flag instead of providing explicit client secrets.
    sign:
      stage: deploy
      image: mcr.microsoft.com/dotnet/sdk:8.0-windowsservercore-ltsc2019
      id_tokens:
        GITLAB_OIDC_TOKEN:
          aud: 'https://gitlab.com'
      before_script:
        - az login --service-principal -u $AZURE_CLIENT_ID --tenant $AZURE_TENANT_ID --federated-token $GITLAB_OIDC_TOKEN
        - Invoke-WebRequest https://github.com/vcsjones/AzureSignTool/releases/latest/download/AzureSignTool-x64.exe -OutFile AzureSignTool.exe
      script:
        - >
          .\AzureSignTool.exe sign 
          --azure-key-vault-url https://example.vault.azure.net/
          --azure-key-vault-managed-identity
          --azure-key-vault-certificate example-certificate
          --verbose 
          example.exe
      artifacts:
        paths:
          - example.exe
  12. Sign files in Azure DevOps using a custom Application Principal

    main

    If you do not have an existing service connection, you can use a custom Azure AD Application registration:

    1. Register an Application: In Azure AD, create a new application. Note the Application (client) ID and Directory (tenant) ID.
    2. Create a Client Secret: Generate a secret for the application and save it immediately.
    3. Configure KeyVault: Add an access policy to your KeyVault for this specific application with Key: Sign, Secret: Get, and Certificate: Get permissions.
    4. Install and Run: Install the tool via DotNetCoreCLI@2 and run the signing command using a CmdLine@2 task, passing the IDs and secret directly as arguments.
    # Install step
    - task: DotNetCoreCLI@2
      inputs:
        command: 'custom'
        custom: 'tool'
        arguments: 'install --global azuresigntool'
      displayName: Install AzureSignTool
    
    # Sign step
    - task: CmdLine@2
      displayName: 'Sign outputted .exe with global AzureSignTool'
      inputs:
        script: AzureSignTool sign -du "[YOUR_URL]" -kvu "https://[VAULT_ID].vault.azure.net" -kvi "[REDACTED_APPLICATION_ID]" -kvt "[REDACTED_DIRECTORY_ID]" -kvs "[REDACTED_APPLICATION_CLIENT_SECRET]" -kvc "[REDACTED_CERT_NAME]" -v [FILES_YOU_WANT_TO_SIGN]