PowerShell / SecretManagement

PowerShell module to consistent usage of secrets through different extension vaults
MIT License
325 stars 46 forks source link

Set-AuthenticodeSignature should support Key Vault certificates #115

Open clairernovotny opened 7 years ago

clairernovotny commented 7 years ago

Today, signing PowerShell scripts/modules requires a certificate to be present in the certificate store or via a PFX file.

There's a growing number of situations where these are not available -- for example, if the key is stored in Key Vault an RSA-HSM key. There's no way to get a private key out.

There should be a way for PowerShell code signing to either use the KeyVault SignAsync API directly or at least have an extension mechanism where the sign digest can be externalized and someone else can write an adapter.

This also has the added benefit of working cross platform as the crypto itself is done in the HSM.

gdasher commented 2 years ago

One note on this issue: the CA browser forum decision to require hardware modules for code signing certs (https://cabforum.org/2022/04/06/ballot-csc-13-update-to-subscriber-key-protection-requirements/) means the lack of support for this integration makes things quite a bit more painful.

As far as I can tell from a few hours of searching, one either has to use a third party tool (such as https://github.com/vcsjones/AzureSignTool or https://github.com/nextgens/CloudSignTool) or roll their own plumbing to make this all work together if you want to leverage cloud capabilities e.g. for CI/CD and still produce signed PS. Native support for standard cloud HSM/KMS services would be very much appreciated to aid in usability.

DennisBergemann commented 1 year ago

Hi, is any effort to this topic here? I need to sign scripts in storage account with keyvault from azure runbook with managed Identity.

Any suggestions? Maybe i am not aware of an workaround now, this topic here seems a bit old.

Thank you for suggestions or help Dennis Bergemann

Crypt32 commented 1 year ago

Thumb up on this. We are actively using PowerShell to perform signing in DevOps pipelines and it is not possible to move keys to Azure KeyVault without rewriting all pipelines to use external command instead of Set-AuthenticodeSignature cmdlet.

DennisBergemann commented 1 year ago

@Crypt32 do you know about this? https://tech.nicolonsky.ch/sign-powershell-az-devops/

iam using this approach, but yeah maybe you have to rewrite a bit as well

Crypt32 commented 1 year ago

@Crypt32 do you know about this? https://tech.nicolonsky.ch/sign-powershell-az-devops/

iam using this approach, but yeah maybe you have to rewrite a bit as well

this doesn't look like a solution in my case since our keys are now protected by HSM in KeyVault.

JustinGrote commented 1 year ago

Most third party cert providers now require an HSM as of June 2023, so this has become even more important now. https://knowledge.digicert.com/alerts/code-signings-new-private-key-storage-requirement.html#:~:text=Starting%20June%201%2C%202023%2C%20at,EAL%204%2B%2C%20or%20equivalent.

smallsam commented 1 year ago

I was researching this issue too and in additional to the Azure KeyVault based options that @gdasher notes above:

As far as I can tell from a few hours of searching, one either has to use a third party tool (such as https://github.com/vcsjones/AzureSignTool or https://github.com/nextgens/CloudSignTool) or roll their own plumbing to make this all work together if you want to leverage cloud capabilities e.g. for CI/CD and still produce signed PS. Native support for standard cloud HSM/KMS services would be very much appreciated to aid in usability.

It looks like jSign is a reasonable candidate for handling all your authenticode needs (not just powershell scripts). The biggest downside is the jvm requirement but if you're putting this in an ephemeral build environment it's not a big deal and as you're likely on windows, there's a chocolatey package: https://community.chocolatey.org/packages/jsign. This is what I will likely pursue as it will handle my broader signing needs.

jberkers42 commented 7 months ago

Adding to this since we also have PowerShell Module and Script code signing requirements. Being able to use set-authenticodesignature to sign PowerShell code with an HSM-Backed Key Vault Certificate is becoming essential.

JustinGrote commented 7 months ago

To be fair, this repository is not where this responsibility would lie. This issue should be moved to the Azure Key Vault secretmanagement vault repo.

DennisBergemann commented 7 months ago

@jberkers42 i solved it with azure devops solution. Here you can add your certificate and use it in powershell script with Set-AuthentodeSignature

  1. Point Certificate from keyvault
  2. Create script what import the cert in devops agents store and signs your scripts

the pipeline will sign your script when you push new scripts in repository

find them in artifacts

Crypt32 commented 7 months ago

@jberkers42 i solved it with azure devops solution. Here you can add your certificate and use it in powershell script with Set-AuthentodeSignature

  1. Point Certificate from keyvault
  2. Create script what import the cert in devops agents store and signs your scripts

the pipeline will sign your script when you push new scripts in repository

find them in artifacts

you can't export keys from HSM, so this approach isn't going to work.

DennisBergemann commented 7 months ago

@Crypt32 you can not upload HSM keys in KEYVault and load them as Variable in Azure Devops? are you sure?

My Solution works great for my codesigning certificates on windows and is often used.

DennisBergemann commented 7 months ago

@Crypt32 you can refer to this https://tech.nicolonsky.ch/sign-powershell-az-devops/

i am using near the same approach so i had not to rewrite

Crypt32 commented 7 months ago

@Crypt32 you cann not upload HSM keys in KEYVault and load them as Variable in Azure Devops? are you sure?

with HSMs, you do not upload keys manually, because keys exist outside the HSM in this case. Keys are no longer secure and will fail key attestation, you can't prove anymore that the key is backed by HSM. Instead, you let the HSM to generate keys and store them securely.

In other words in HSM-enabled environments, keys never exist outside the secure tamper-evident HSM storage which makes your scenario impossible.

Crypt32 commented 7 months ago

@Crypt32 you can refer to this https://tech.nicolonsky.ch/sign-powershell-az-devops/

i am using near the same approach so i had not to rewrite

this is applicable only to software-based keys, not hardware-based keys.

jberkers42 commented 7 months ago

Exactly as @Crypt32 commented, a key generated and stored in HSM (Hardware Security Module) cannot be exported. It is one of the currently requirements, as a result of numerous Code Signing Key breaches, that when generating a Key Pair for Code Signing in Azure Key Vault that you choose HSM backed key storage, and that you mark it as non-exportable.

We used Software Based keys in the previous iteration of our Code Signing, with additional controls to alert us each time the key was used. The key was stored as non-exportable in that case also, but in a Windows Crypto Store. Due to changes in policy by the Browser CA Forum this is no longer sufficient.

Thanks for looking for a solution, though.

DennisBergemann commented 7 months ago

@Crypt32 @jberkers42 Thank you for making me smarter. I was not aware of this.

JustinGrote commented 7 months ago

So just a reminder that Set-AuthenticodeSignature is part of https://github.com/powershell/powershell and not SecretManagement. SecretManagement is just an abstraction API for accessing secrets in a common way, so once there is a method, it could theoretically be possible to shoehorn this functionality into a vault with Set-Secret, but that command will not come from this repo, it would come from a vault provider such as Azure Key Vault or a new third party abstraction. Further discussion should occur on an issue there.

@jborean93 has a module that can do authenticode signing using the Azure Key Vault HSM sign api https://github.com/jborean93/PowerShell-OpenAuthenticode/blob/main/docs/en-US/about_AuthenticodeAzureKeys.md

jborean93 commented 7 months ago

Thanks for the ping Justin, OpenAuthenticode can run on any platform as long as it has PowerShell 7.2+ but one downside is it has more limited support for files you can sign. Currently it supports .ps1, .psd1, .psm1, .psc1, .ps1xml, .dll, and `.exe https://github.com/jborean93/PowerShell-OpenAuthenticode/blob/main/docs/en-US/about_AuthenticodeProviders.md#long-description. I use this in all my modules and have found the OIDC method is perfect for CI as you can authorise a specific GitHub actions workflow access to the signing API using the docs that Justin has linked. This means there are no secrets needed to be stored in GitHub, just the KeyVault details.

If you need support for more extensions you can look at using AzureSignTool which runs on Windows only but exposes a way to sign things using the Windows Authenticode providers with the Azure sign API so has support for every extension that Windows ships with.