Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add documentation for installing custom root ca certificates #1428

Merged
merged 2 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions docs/advanced/root-ca-certificates.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Root CA Certificates

To install a [root certificate](https://en.wikipedia.org/wiki/Root_certificate) into your container built using `ko`, you can use one of the following methods.

## incert
[`incert`](https://github.com/chainguard-dev/incert) allows you to append CA certificates to an image and push the modified image to a specified registry.

`incert` can be run after `ko build` to build your Go application container image with custom root CA certificates.

### Example
1. Build and push your Go application container image using `ko build`
```sh
KO_DOCKER_REPO=mycompany/myimage:latest ko build .
```

2. Append the built image with your custom CA certificate(s) using `incert`
```sh
incert -image-url=mycompany/myimage:latest -ca-certs-file=/path/to/cacerts.pem -dest-image-url=myregistry/myimage:latest
```

## Custom Base Image

New root certificates can be [installed into a custom image](https://stackoverflow.com/questions/42292444/how-do-i-add-a-ca-root-certificate-inside-a-docker-image) using standard OS packages. Then, this custom image can be used [to override the base image for `ko`](https://ko.build/configuration/#overriding-base-images). Once the Go application container image is built using `ko` with the custom base image, the root certificates installed on the base image will be trusted by the Go application.

### Example

1. Make a custom container image with your new root certificates
```dockerfile
# Dockerfile
FROM alpine

RUN apk update
RUN apk add ca-certificates

ADD new-root-ca.crt /usr/local/share/ca-certificates/new-root-ca.crt
RUN chmod 644 /usr/local/share/ca-certificates/new-root-ca.crt
RUN update-ca-certificates
```

2. Build and push the custom container image to a container registry
```sh
docker build . -t docker.io/ko-build/image-with-new-root-certs
docker push docker.io/ko-build/image-with-new-root-certs
```

3. Configure `ko` to [override the default base image](https://ko.build/configuration/#overriding-base-images) with the custom image
```yaml
# .ko.yaml
defaultBaseImage: docker.io/ko-build/image-with-new-root-certs
```

**OR**
```sh
export KO_DEFAULTBASEIMAGE=docker.io/ko-build/image-with-new-root-certs
```

4. Build the Go app container image with `ko`
```sh
ko build .
```

## Static Assets
Alternatively, root certificates can be installed into the Go application container image using a combination of [`ko` static assets](https://ko.build/features/static-assets/) and [overriding the default system location for SSL certificates](https://pkg.go.dev/crypto/x509#SystemCertPool).

Using `ko`'s support for static assets, root certificates can be stored in the `<importpath>/kodata` directory (either checked into the repository, or injected dynamically by a CI pipeline). After running `ko build`, the certificate files are then bundled into the built image at the path `$KO_DATA_PATH`.

To enable the Go application to trust the bundled certificate(s), the container runtime or orchestrator (Docker, Kubernetes, etc) must set the environment variable `SSL_CERT_DIR` to the same value as `KO_DATA_PATH`. Go [uses `SSL_CERT_DIR` to determine the directory to check for SSL certificate files](https://go.dev/src/crypto/x509/root_unix.go). Once this variable is set, the Go application will trust the bundled root certificates in `$KO_DATA_PATH`.

### Example

1. Copy the root certificate(s) to the `<importpath>/kodata/` directory
```sh
# $(pwd) assumed to be at <importpath> for this example
mkdir -p kodata
cp $CERT_FILE_DIR/*.crt kodata/
```

2. Build the Go application container image
```sh
KO_DOCKER_REPO=docker.io/ko-build/static-assets-certs ko build .
```

3. Run the Go application container image with `SSL_CERT_DIR` equal to `/var/run/ko` (the default value for `$KO_DATA_PATH`)
kosamson marked this conversation as resolved.
Show resolved Hide resolved
```sh
docker run -e SSL_CERT_DIR=/var/run/ko docker.io/ko-build/static-assets-certs
```

A functional client-server example for this can be seen [here](https://github.com/kosamson/ko-private-ca-test).
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ nav:
- advanced/terraform.md
- advanced/lambda.md
- advanced/linux-capabilities.md
- advanced/root-ca-certificates.md
- CLI Reference:
- 'ko': reference/ko.md
- 'ko apply': reference/ko_apply.md
Expand Down