Inserting a private CA certificate into a VS Code devcontainer
I’ve always wondered how much productivity loss SSL inspection causes due to various platforms and applications having very difficult means of trusting an internal CA certificate. Where I work, we’ve certainly lost a lot. But hey, there is a really easy workaround with VS Code devcontainers that will make them work behind a firewall with very little effort.
Preparation
Before we jump into how to solve this problem, we need to get into collecting the certificate and understanding how a Dockerfile fits into running a devcontainer.
Collecting the cert
The first step is to get your hands on the internal root CA’s public certificate. You could ask whatever team manages your network security for a copy or try to figure out the correct certificate from your operating system’s certificate store, but the easiest way is to simply navigate to any external website and look at the certificate chain. This will be different in different browsers, but the idea is that you want to export the rootest root CA certificate in base64 encoding. You do not need to include the certificate chain because it is the root certificate (and therefore has no chain).
Working with Dockerfiles
If you have done much work with devcontainers, then you are likely wondering what I mean by a Dockerfile. Most of the configuration happens in the .devcontainer/devcontainer.json file, right? For advanced customizations, you can leverage a Dockerfile (info is also in the devcontainers references docs) that you also place in the .devcontainer directory. Then, instead of using the image property in the devcontainer.json file, you would use "build": { "dockerfile": "Dockerfile" }.
For example, here’s a very simple Go devcontainer configuration:
{
"name": "Go",
"image": "mcr.microsoft.com/devcontainers/go:dev-1.23-bookworm",
"postCreateCommand": "go version"
}
If we wanted to use a Dockerfile, you’d switch it up to be:
{
"name": "Go",
"build": { "dockerfile": "Dockerfile" },
"postCreateCommand": "go version"
}
And the beginning of your Dockerfile would start with (assuming this was a single stage build):
FROM mcr.microsoft.com/devcontainers/go:dev-1.23-bookworm
Inserting the certificate into the devcontainer
With the certificate and an understanding of how the Dockerfile works with devcontainers, all we need to do is to add 3 additional steps:
COPYto insert the certification onto the filesystem of the container. This step will leverage heredoc syntaxRUNto run theupdate-ca-certificatescommand (info about compatibility can be found here)- This devcontainer base uses Debian, which includes the
update-ca-certificatescommand.
- This devcontainer base uses Debian, which includes the
- Create the
NODE_EXTRA_CA_CERTSenvironment variable.
You can see all three steps have been applied in the below Dockerfile:
FROM mcr.microsoft.com/devcontainers/go:dev-1.23-bookworm
# Place the certificate into the certificate directory
# The extra blank line at the end is required!
COPY <<EOF /usr/local/share/ca-certificates/root.crt
-----BEGIN CERTIFICATE-----
<base64 cert>
-----END CERTIFICATE-----
EOF
# Execute the command to update the ca certs
RUN update-ca-certificates
# Add the cert to the NODE_EXTRA_CA_CERTS environment variable
ENV NODE_EXTRA_CA_CERTS=/usr/local/share/ca-certificates/root.crt
Conclusion
With that all in place, simply build (or rebuild) your devcontainer and you can test if it is working by running a curl command against an https:// website.
Leave a Comment