Can I safely save my private key on public build servers? - azure-devops

This is a technical question on comprehension:
When I want a cloud server (e.g. GitHub Actions, Azure DevOps, or GitLab CI/CD) to build and publish an app to any of the app stores ... isn't it necessary then that I upload my private key to these servers' key vault, so they can sign my app on my behalf?
Isn't that concept a bit risky?
I mean, I was taught to let my private keys never leave my machines.
What if I accidentally misconfigure the security settings on the uploaded key? What if some black hat gets hold of the key and abuses it? I mean, with each build process, the private key is getting copied from the vault to the build runner, usually residing somewhere else.
What are the techniques used to ensure that private keys are kept safely on a public server? Is there an official audit performed on these departments?
Should I rather use different Authenticode certificates for each of the above providers? Or will a single certificate be resilient enough?
I couldn't find a technical discussion on this question, only marketing docs. Has this security concern been scientifically scrutinized?

It is safe to use certificates in Azure DevOps, Azure DevOps encrypts the certificate and then uses it in the build pipeline.
We could use Azure Key Vault to protect encryption keys and secrets like certificates, connection strings, and passwords in the cloud. You could refer this doc for more details.
We could also save the certificate file in the Library->Secure Files, if someone want to access or use it, he need enough permission.
I found some sample to use certificate in the Azure DevOps Service, you could check it.
 
If you are using SSL certificate thumbprint, you could save it in the variable and then set the variable to Secret via the “lock” icon at the end of the row.
If you are using PFX certificate, you could refer to this doc.
Update1
GitHub action
We could save the certificate here in the GitHub, GitHub also encrypts the certificate, we could not get the value after save the variable in the Secrets, and we will get *** when print the Secrets value in the log.

Related

Getting started with Vault for existing non-containerized Windows apps

We have a bunch of Windows server applications that currently handle secrets as follows; our apps are in C#.
We store them in settings files in code
We store them encrypted, using a certificate
The servers have this certificate with the private key, so they can decrypt the secret
We're looking at implementing Hashicorp Vault. It seems easy enough to simply replace the encrypt-store-decrypt with storing the secret in Vault in the KV engine, and just grabbing it in our apps - that takes that certificate out of the picture entirely. Since we're on-prem, I'll need to figure out our auth method.
We have different apps running on different machines, and it's somewhat dynamic (not as much as an autoscaling scenario, but not permanent - so we can't just assign servers to roles one time and depend on Kerberos auth).
I'm unsure how to make AppRole work in our scenario. We don't have one of the example "trusted platforms" or "trusted entities", there's no Nomad, Chef, Terraform, etc. We have Windows machines, in a domain, and we have a homegrown orchestrator that could be queried to say "This machine name runs these apps", so maybe there's something that can be done there?
Am I in "write your own auth plugin" territory, to speak to our homegrown orchestrator?
Edit - someone on Reddit suggested that this is a simple solution if our apps are all 1-to-1 with the Windows domain account they run under, because then we can just use kerb authentication. That's not currently the way we're architected, but we've got to solve this somehow, and that might do it nicely.
2nd edit - replaced "services" with "apps", since most of our services aren't actually running as Windows services, just processes. The launcher is a Windows service but the individual processes it launches are not.
How about Group Managed Service Accounts?
https://learn.microsoft.com/en-us/windows-server/security/group-managed-service-accounts/group-managed-service-accounts-overview
Essentially you created one "trusted platform" (to your key vault service).
Your service can still has its own identity but delegation to the gMSA when you want to retrieve the secrets.
For future visibility, here's what we landed on:
TLS certificate authentication. Using Vault, we issue a handful of certs, each will correspond to a security policy/profile, so that any machine that holds that certificate will be able to authenticate and retrieve the secrets they should have access to.
Kerberos ended up being a dead-end for two reasons. The vault.exe agent (which is part of this use case) can't use the native Windows Kerberos SSPI, so we'd have to manage and distribute keytab files. Also, if we used machine authentication, it would blow up our client count (we're using the cloud-hosted HCP Vault, where pricing is partially based on client count).
Custom plugins can't be loaded into the HCP, of course
Azure won't work, it requires Managed Identities which you can't assign to on-prem machines. Otherwise this might have been a great fit

How and where to put passphrase of the Tessera private key when using Hashicorp vault

We are using Quorum and Hashicorp vault in one of our systems. We have been able to successfully integrate these two i.e. we have put the Tessera private and public keys in the Vault and successfully ran the Quorum server.
The problem is, when we are trying to use passphrase for the private key, we could not find a way through which we can achieve this. Even we have observed that when we are using the tessera key generation tool for Hashicorp vault where it generates the keys and internally saves the same in the Vault as well, it does not ask for any passphrase. But when we use the normal key generation tool where it generates the keys and puts the same in the specified directory, it asks for the passphrase.
May you please help us how we can achieve this leveraging Hashicorp Vault and Tessera i.e. we generate a key pair where private is protected with passphrase.
We could not find any help in the Wiki and also we tried to analyze the source code and our impression is if we want to use passphrase protected private key for Tessera, we can't use Hashicorp Vault now.
Please help.
Tessera does not support the storing of passphrase-protected private keys in a Hashicorp Vault as Vault already encrypts the data that it stores.
However, to get access to the data stored in a Vault, the Tessera instance must possess the correct set of credentials (provided as environment variables) in order to authenticate with the Vault. Using these credentials offers more flexibility and control in comparison to the passphrases used to secure file-stored keys.
For example, configuring an authentication method (e.g. AppRole authentication) makes it possible to define the authorisation for a particular Tessera instance, ensuring it is only allowed to access the secrets that it needs. Additionally these credentials can be configured to expire after a certain number of uses or length of time.
Finally, TLS should be enabled on the Vault server to ensure secure communication between Vault and Tessera. The necessary TLS certificates and keys should be included in the Tessera start-up config.
The Tessera wiki provides more details on the exact configuration and environment variables to provide:
https://github.com/jpmorganchase/tessera/wiki/Setting-up-a-Hashicorp-Vault
https://github.com/jpmorganchase/tessera/wiki/Keys#4-hashicorp-vault-key-pairs

store P12 on public datacenter securely

We have a lot of user P12 files (certificates) for each clients/tenant and we would like to store it securely. We don't use cloud solution like Amazon, Azure Keyvault or other datacenter solution but a hosting company.
Do you have any solution ? Vault from Hashicorp
You can use Vault to manage your own PKI and issue certificates instead. In fact, it is more than that,
From using Hashicorp Vault to manage PKI and issue certificates
Vault allows you to manage an entire Public Key Infrastructure (PKI)
to ensure secure communication among different services. This allows
companies to easily setup their own certificate authority (CA), revoke
or issue new certificates using simple API calls, thus dumping the
painful process of constantly generating self-signed certificates.
You can checkout this guide for the process of using Vault to generate and issue certificates.

How to bootstrap certificates for LCM to reference for signatureverification settings?

WMF 5.1 includes new functionality to allow signing of MOF documents and DSC Resource modules (reference). However, this seems very difficult to implement in reality -- or I'm making it more complicated than it is...
My scenario is VMs in Azure and I'd like to leverage Azure Automation for Pull DSC Server; however, I see this applying on premise too. The problem is that the certificate used to sign the MOF configurations and/or modules needs to get placed on the machine before fetching and applying the configuration otherwise configuration will fail because the certificate isn't trusted or present on the machine.
I tried using Azure KeyVault to bootstrap the certificate (just the public key because that's my understanding of how signing works) and that fails using Add-AzureRmVMSecret because the CertificateUrl parameter expects a full certificate with the public/private key pair to install. In an ideal world, this would be the solution but that's not the case...
Other ideas, again in this context, would be to upload the cert to blob storage, use a CustomScriptExtension to pull down the cert and install into the LocalMachine store but that feels nasty as well because, ideally, that script should be signed as well and that puts us back in the same spot.
I suppose another idea would be to first PUSH a configuration that downloaded and installed certificates only but that doesn't sound great either.
Last option would be to rely on an AD GPO or something similar to potentially push the certificate first...but, honestly, trying to move away from much of that if/when possible...
Am I off-base on this? It seems like this should be a solvable problem -- just looking for at least one "good" way of doing it.
Thanks
David Jones has quite a bit of experiencing dealing with this issue in an on-premises environment, but as you stated the same concepts should apply for Azure. Here is a link to his blog. This is a link to his GitHub site with a PKITools module that he created. If all else fails you can reach out to him on Twitter.
While it's quite easy to populate a pre-booted image with public certificates. it's not possible (that I have found) to populate the private key.
DSC would require the private key to decrypt the passwords.
The most common tactic people blog about is to use the unattend to script the import of a PFX. issue there is you have to leave the password for the PFX in plain text. Perhaps that is ok in your environment.
The other option requires a more complicated setup. Use a simple DSC or GPO to auto enroll a unique certificate. then have the system, via first boot script or DSC custom resource, tickle an API (Like Polaris) and that triggers a DSC script that uses PKITools or other script to get the public certificate that the machine has. Then have that API push a new DSC config (or pull settings) to the machine.

Azure Service Fabric, KeyVault, SSL Certificates

I want to secure my own HTTPS end point (node.js express.js server) with a certificate which I have deployed to the cluster (that is, it exists in Cert:\LocalMachine\My).
I of course want to avoid having my certificate in source control. I can't use an EndpointBindingPolicy in the ServiceManifest because as far as I'm aware that is just for http.sys(?) based systems, which this isn't.
What I thought is perhaps run a SetupEntryPoint script to:
grab the certificate from the store
export it as a pfx with a random passphrase (or some appropriate format)
copy it to {pkgroot}/certs/ssl_cert.pfx
replace some sort of token in serverinit.js with the random passphrase
This way the server, er, code base doesn't need to have the certificate present, i just needs to trust that it will be there when the service is run.
However I don't think I can do this, if it even is as sensible idea, as the certificates in the store are marked such that the private key is non-exportable! Or, at least, they are with my RDP account!
Is there a way to export the certificate with its private key?
What are my options here?
I ended up writing a powershell script which runs in my release pipeline, arguments are clientID, clientSecret and certificateName. clientSecret is stored as a protected environmental variable for my agent.
Create new application registration under same subscription as KeyVault (which should be same as SF Cluster) (e.g. in portal.azure.com)
Note down app ID
Create app secret
Modify KeyVault ACL with App as principal, set get only on secrets
use REST api with client ID and secret https://learn.microsoft.com/en-us/rest/api/keyvault/getsecret
I chose this over grabbing the certificate in the SetupEntryPoint, for example, as this hides the client secret better from the open world (e.g. developers who shouldn't/don't need access to it)