Cowboy in the desert.

RFC: X.509 Certificate Management

Michael Richardson

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.

Thumbprint in HTTPS IIS binding configuration

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.

Upload certificate mockup

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:

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.

Add certificate variable

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.

Configure IIS binding using certificate variable

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.


Certificate variables scoped per Environment

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:

  1. Create a new certificate (automatically requested from Let's Encrypt)
  2. Reference it in HTTPS binding configuration of IIS deployment step
  3. 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


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?