A new managed signing service on Azure offers low-cost, low-touch code signing with integration into GitHub Actions.
How do we ensure that the code weβre installing is, at the very least, the code that a vendor shipped? The generally accepted solution is code signing, adding a digital signature to binaries that can be used to ensure authorship. At the same time, the signature includes a hash that can be used to show that the code youβve received hasnβt been altered after itβs been signed.
code signing is increasingly important as part of ensuring software bills of materials and reducing the risks associated with malware hijacking legitimate binaries. Signing is necessary if youβre planning on using services like the Microsoft Store or the Windows Package Manager to distribute your applications, allowing the repository to verify software sources.
Using public key infrastructure to secure code
The process of code signing is a straightforward one, building on familiar public key cryptography techniques. Like these it requires digital certificates and signatures, verifying the publisherβs identity and the certificate authority that issued the underlying certificates. That last feature is key to establishing the trust relationship between publisher and code, with a list of trusted certificate authorities managed both by stores and the underlying OS that the certified code targets.
For many good reasons itβs becoming a lot harder to manage your own signing infrastructure. Self-signed certificates arenβt accepted by stores, though they can be used for internal code distribution, and certificates now need to be held in trusted hardware security modules, where they must be regularly renewed to ensure that youβre always using a valid certificate for your code.
Microsoft has long offered several different ways of signing code, using the technique to ensure that Windows only installs trusted drivers. The process has since been extended to Microsoftβs own software updates and to the installers used by the Windows Store.
One of those ways was Azure Code Signing, which didnβt really capture the attention of developers, despite integrating well with Visual Studio and the Windows Store. However, Azure Code Signing wasnβt the cheapest option either, and had to compete with on-premises solutions.
Introducing Trusted Signing
Microsoft has both simplified its cloud-hosted option and incorporated the latest updates to Azureβs secure computing infrastructure, rolling out a preview of what it calls Trusted Signing. As part of the launch, Microsoft is introducing a new pricing structure and providing integration with GitHubβs build pipelines.
The goal behind Trusted Signing is to bring the entire code signing life cycle into one place, simplifying the process of acquiring the necessary certificates, storing them securely, and providing a secure and private way of signing code.
The service builds on top of familiar Azure tools. You can set it up from the Azure Portal, adding a Trusted Signing account to a resource group inside your subscription. Itβs best to set up a separate resource group for code signing thatβs not used for anything else, as this lets you more effectively control the users and roles that have access.
There are two options for Trusted Signing: basic and premium. The main difference between the two is the number of identity validations and certificate profiles you can store. Identity validation is used to prove who you (or your organization) are, while certificate profiles are used to generate the certificates used to sign your code. Certificate profiles contain information about the role of the signature and how the signature is trusted.
Getting started with Trusted Signing
Getting started is straightforward. You can use the Azure Portal or the Azure CLI, though you can validate identity only through the portal. You should keep this in mind if youβre using the CLI, as it adds another step and prevents you from automating the process.
The first step is to register a code signing resource provider in your Azure subscription. Thereβs a list of resource providers in your account settings, where you can select the Microsoft.CodeSigning option. This toggles from NotRegistered to Registered, allowing you to set up Trusted Signing by creating an account to hold your identity details and signing certificate profiles. Currently youβre limited to Azureβs US and Europe regions, with each region having its own dedicated endpoint URL that can be used to add automated signing to external build services.
Next you create a Trusted Signing account as a new Azure resource. Like most Azure resources, creating the resource involves stepping through a basic wizard, filling out the necessary forms to create a new resource group, pick a pricing plan, and deploy your account to an Azure region. It takes a few minutes to deploy your instance, then you can validate your organizationβs identity.
Youβll need to be logged into Azure with an account that has the appropriate Trusted Signing Identity Verifier role. You will need to choose whether youβre validating a public or private identity. A public identity needs a legal business identity for the certificate, while private requires only your Azure tenant. Public identities must have a URL, a contact email address, and your Microsoft Store Seller ID, if you intend to deliver code through the Microsoft Store.
There are some limitations that make using Trusted Signing impossible for startups or sole traders, as you need to have three years of tax history. (The documentation implies that this may change in the future.) You may need to provide additional information through the portal if Microsoft needs additional verification. Donβt expect an instant response. It could take a week or more to get an account verified.
Once that happens, you can create a certificate profile, again for public or private use. Start by filling out a form with the information that will be encoded in your signing certificates. You should now be ready to start signing code using the details stored in your Trusted Signing account, linking it to a growing set of signing integrations.
Adding Trusted Signing to a GitHub build action
Perhaps the most interesting option is support for using a GitHub action to sign your code as soon as a build completes, using one of the Windows runners. Simply add the action after a build completes, using your account secrets and the code signing endpoint for your Trusted Signing account. As part of the configuration process, you need to add the folder and file types that are being signed, the hash type youβre using, and an RFC 3161 timestamp. If youβre targeting specific output files, you can include a file catalog file that lists the files being signed.
The result is a hands-off approach to delivering a signed build: Push some code to a specific production branch of your repository, and the action will handle building, packaging, and signing the code. It will even deliver it to the Windows Store or a Windows Package Manager repository. The runner is available in the Visual Studio Store, so it can be managed and edited inside Visual Studio.
Automating the certificate life cycle
Another aspect of the service is support for your certificate life cycle. The underlying model is the standard x.509 approach for certificates and their keys. Itβs important to note that certificates are short-lived: They are renewed daily and are valid for only 72 hours. That allows you to quickly invalidate specific builds that may have been compromised. You donβt have to do anything. The entire process is automatic, with issued certificates logged in Azure and stored and managed in secure cryptographic hardware.
Of course, one of the key questions is cost, and Trusted Signing isnβt too expensive. The basic option, which allows one of each certificate profile type, costs $9.99 for 5,000 signatures per month (additional signings are $0.005 per signature). If you need more certificates, you can choose the $99.99 premium option with 100,000 signatures per month and the same pricing for overages, with 10 of each type in each account.
Microsoft is going a long way to make code signing simpler to use. It would be nice if there were a free option along the lines of Letβs Encrypt for open-source projects or for individual developers, but for now thatβs not on the table.
Whatβs needed is a code signing infrastructure thatβs simple to use and available for everyone, so we can make code signing a natural part of the software development life cycle. The more code thatβs signed, the lower the risk for us all, including for Microsoft and Windows. Providing a signing service like Trusted Signing as a public service might be the best approach in the long run, but for now, Trusted Signing is what we have.


