Management of X.509 certificates is a common deployment pain-point.
The specific example that provided the impetus for this feature is creating HTTPS bindings in IIS.
Currently in Octopus, when configuring the HTTPS binding the certificate is referenced by thumbprint.
It is assumed that the certificate has been installed to the IIS server. And when the certificate referenced by that thumbprint inevitably expires, you have to remember to update the thumbprint in Octopus to match the new certificate.
We believe we can improve this and (hopefully) many other certificate-related scenarios.
Octopus == Certificate Repository
The Octopus Server is ideally placed to act as a central management point for X.509 certificates.
We intend to allow you to upload your certificates to Octopus.
We will support uploading in various file formats (.pfx, .pem, .cer), and you will be able to view and search the certificates you have uploaded.
Certificates can be scoped to environments (and tenants). This will prevent accidentally deploying your production certificate to a development environment, for example.
Private Keys
Technically X.509 certificates only contain the public key. However, in many cases (including configuring HTTPS IIS bindings) both the certificate and it's corresponding private key are required.
Both PFX (PKCS #12) and PEM formats support storing the private-key along with the certificate, and Octopus will support uploading these.
So for the pedants (and aren't we all), when we speak of a certificate in this context, we really mean certificate and it's associated private key (if supplied).
Because the certificate may include the private key, they will be persisted in the Octopus database encrypted with your master-key.
Phase I
The functionality we would like to deliver in the intial phase is:
- Upload X.509 certificates to Octopus
- Create certificate variables
- Use managed certificates when configuring IIS bindings
- Use managed certificates from custom scripts
Certificate Variables
To support certificates, we are planning to introduce the concept of typed variables. When creating a variable, you will able to specify that it will represent a certificate.
When working with certificates, there are many properties of potential interest:
- Thumbprint
- Public key
- Private key
- Entire raw certificate (possibly including private key)
- etc
At deploy-time, a certificate variable will be expanded into many variables.
i.e: MyCertificate
=>
MyCertificate.Type
: Certificate
MyCertificate.Name
: The friendly name provided when importing the certificate into Octopus
MyCertificate.Thumbprint
: The certificate thumbprint. e.g. A163E39F59560E6FE33A0299D19124B242D9B37E
MyCertificate.Subject
: The X.500 distinguished name of the subject
MyCertificate.Issuer
: The X.500 distinguished name of the issuer
MyCertificate.NotBefore
: e.g. 2016-06-15T13:45:30.0000000-07:00
MyCertificate.NotAfter
: e.g. 2019-06-15T13:45:30.0000000-07:00
MyCertificate.Pfx
: The base64 encoded certificate as in PKCS #12 format, including the private-key if present.
MyCertificate.PublicKey
: The base64 encoded DER ASN.1 primary key.
MyCertificate.PrivateKey
: The base64 encoded DER ASN.1 private key (if present).
MyCertificate.PublicKeyPem
: The PEM representation of the public key (i.e. the PublicKey with header\footer).
MyCertificate.PrivateKeyPem
: The PEM representation of the private key (i.e. the PrivateKey with header\footer).
This is a possible list of variables. The exact variables created are yet to be finalized.
The private-key variables will be stored and transmitted in the same manner as sensitive-variables; never in clear-text.
In the future we will extend the concept of typed-variables to other entities. An obvious candidate is Accounts.
IIS Bindings
When configuring HTTPS bindings for an IIS deployment, currently the certificate installation must be managed externally (or at least via a custom script). The thumbprint of the certificate is then entered into the binding configuration.
This feature will allow you to select a Certificate Variable, instead of a thumbprint.
It's interesting to note the binding is to a certificate variable, rather than directly to a certificate. Our reasoning is that the common (and recommended) scenario will be to have a certificate-variable, with different actual certificate values scoped per environment.
e.g.
So the IIS binding would be created using the OctoFX Certificate
variable, and the correct certificate would be installed depending on the environment being deployed to.
When deploying, the certificate will be installed in the Cert:\LocalMachine
store (if it isn't already), and the HTTPS binding will be configured in IIS.
Referencing Certificate Variables in Custom Scripts
Certificate Variables should make using certificates from custom scripts nice and easy, whatever your scripting language of choice (PowerShell, ScriptCS, F#, Bash).
Variable-substitution will work:
Write-Host #{MyCertificate.Thumbprint}
As will:
Write-Host $OctopusParameters["MyCertificate.Thumbprint"]
For the .NET-based scripting languages, we will likely provide a helper function to get the X509Certificate2 object, as even with the pfx representation available there are a few common traps when creating these objects.
The Future
Functionality we are considering for delivery in subsequent phases includes:
- Configure expiry notifications
- Report which machines a certificate is installed on
- Allow automatically replacing installed certificates when a new certificate is uploaded (i.e. create a 'deployment' for the certificate only)
- Let's Encrypt integration. i.e. implement ACME protocol and act as a Let's Encrypt agent
The Holy Grail
Our dream workflow would resemble this:
- Create a new certificate (automatically requested from Let's Encrypt)
- Reference it in HTTPS binding configuration of IIS deployment step
- When the certificate is close to expiry, a new certificate is automatically requested from Let's Encrypt and installed as a replacement on all machines where the expired certificate was used
Feedback
This is your chance to guide the development of this feature.
Would this be useful to you?
Is there anything on your wishlist that we haven't mentioned?