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:
COPY
to insert the certification onto the filesystem of the container. This step will leverage heredoc syntaxRUN
to run theupdate-ca-certificates
command (info about compatibility can be found here)- This devcontainer base uses Debian, which includes the
update-ca-certificates
command.
- This devcontainer base uses Debian, which includes the
- Create the
NODE_EXTRA_CA_CERTS
environment 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