Skip to content
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
70 changes: 16 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ This repository contains a Dev Container Feature collection for SolarWinds.

## Feature: cato

The `cato` feature installs a CATO SSL certificate in the container trust store and can configure Node.js/npm to use that certificate. Please note, the feature needs to be installed first (before any other feature, e.g., node, etc).
The `cato` feature installs a [CATO SSL certificate](https://support.catonetworks.com/hc/en-us/articles/32115505825821-Getting-Started-with-Cato-Certificates) in the container trust store and can configure Node.js/npm to use that certificate. Please note, the feature needs to be installed first (before any other feature, e.g., node, etc).

Published feature reference:

```json
"features": {
"ghcr.io/solarwinds-cloud/devcontainers/features/cato:1": {}
"ghcr.io/solarwinds/devcontainers/features/cato:1": {}
},
"overrideFeatureInstallOrder": [
"ghcr.io/solarwinds-cloud/devcontainers/features/cato"
"ghcr.io/solarwinds/devcontainers/features/cato"
]
```

Expand All @@ -25,64 +25,26 @@ The feature installs the bundled Cato Networks Root CA and exports:
4. `CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt`
5. `NPM_CONFIG_CAFILE=/etc/ssl/certs/ca-certificates.crt`

### Private GHCR Access
### Support

This feature is published to a private GHCR package. The host machine must be authenticated to `ghcr.io` before the Dev Containers CLI resolves the `features` block. VS Code GitHub sign-in is not automatically reused for Docker/OCI registry pulls, so Docker needs its own GHCR credential.
Supported base images (with `update-ca-certificates` available):

For consuming repositories, add a host-side bootstrap script under the consuming repo's `.devcontainer/` folder and run it with `initializeCommand`:
1. Debian/Ubuntu-based
2. Alpine-based images

```jsonc
{
"initializeCommand": "bash ${localWorkspaceFolder}/.devcontainer/ghcr-login.sh",
"features": {
"ghcr.io/solarwinds-cloud/devcontainers/features/cato:1": {},
"...another features...": {}
},
"overrideFeatureInstallOrder": [
"ghcr.io/solarwinds-cloud/devcontainers/features/cato"
]
}
```

`initializeCommand` is the Dev Container lifecycle hook for this host-init step because it runs on the host before the container is built and before features are installed. Do not put this in `postCreateCommand`, `postStartCommand`, or the feature's `install.sh`; those run too late because the feature package has already been resolved by then.

Example `.devcontainer/ghcr-login.sh` for Linux, macOS, or WSL hosts:

```bash
#!/usr/bin/env bash
set -euo pipefail

registry="ghcr.io"
feature_ref="ghcr.io/solarwinds-cloud/devcontainers/features/cato:1"

if docker manifest inspect "$feature_ref" >/dev/null 2>&1; then
exit 0
fi
Operational expectations:

if ! command -v gh >/dev/null 2>&1; then
echo "GitHub CLI is required to refresh GHCR credentials. Install gh, then run:"
echo " gh auth login"
echo " gh auth refresh -h github.com -s read:packages"
exit 1
fi
1. If `ca-certificates` tooling is missing, installation can bootstrap it using `apt-get` or `apk`.
2. Images without `update-ca-certificates` and without a supported package manager are not supported by this feature.

auth_status="$(gh auth status -h github.com 2>&1)" || {
echo "$auth_status"
echo "GitHub CLI is not authenticated. Run: gh auth login"
exit 1
}
### Certificate Lifecycle

if ! printf '%s\n' "$auth_status" | grep -q "read:packages"; then
gh auth refresh -h github.com -s read:packages >/dev/null
fi

gh auth token | docker login "$registry" -u "$(gh api user -q .login)" --password-stdin >/dev/null

docker manifest inspect "$feature_ref" >/dev/null
```

The script first checks whether Docker can already read the feature manifest and exits without touching GitHub auth if it can. If Docker is missing usable GHCR credentials, the script uses the existing GitHub CLI token. It only runs `gh auth refresh` when `gh auth status -h github.com` does not show the `read:packages` scope. The first rebuild may open a GitHub authorization flow if that scope is missing; otherwise it should only perform a quiet Docker login and continue.
Bundled certificate lifecycle details, validity period, and SHA-256 fingerprint are documented in [src/cato/NOTES.md](src/cato/NOTES.md).

## Contributing

Development, testing, and release instructions are maintained in [CONTRIBUTING.md](CONTRIBUTING.md).

## Security

Please review our security policy in [SECURITY.md](SECURITY.md).
26 changes: 26 additions & 0 deletions src/cato/NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,32 @@ The feature installs the bundled Cato Networks Root CA certificate.
2. Certificate installation is part of the feature contract and fails fast if trust-store setup fails.
3. Trust is configured using environment variables instead of per-tool config files.

## Certificate Lifecycle and Integrity

The `cato` feature ships a bundled copy of the Cato Networks Root CA certificate in `install.sh`.

Current bundled certificate metadata:

1. Subject: `CN=Cato Networks Root CA, OU=Cato Cloud, O=Cato Networks Ltd., L=Tel Aviv, C=IL`
2. Issuer: self-signed (same as subject)
3. Validity: `notBefore=2024-03-05T12:30:08Z`, `notAfter=2034-03-03T12:30:38Z`
4. SHA-256 fingerprint: `03cb0160356c415ae37fb5757c4fc62ac1e079ac162894415bfaa8b27ebfd2b1`

Update policy:

1. If Cato publishes a replacement root or rotation guidance, update the PEM in `install.sh`.
2. Update certificate assertions in `test/cato/test.sh` and `test/cato/_scenario_assertions.sh` if needed.
3. Bump `version` in `src/cato/devcontainer-feature.json` whenever the bundled certificate changes.
4. Re-run feature validation and tests before release.

Local verification command:

```sh
awk '/-----BEGIN CERTIFICATE-----/{flag=1} flag{print} /-----END CERTIFICATE-----/{flag=0}' src/cato/install.sh \
| openssl x509 -outform der \
| sha256sum
```

## Under The Hood

### High-Level Flow
Expand Down
2 changes: 1 addition & 1 deletion src/cato/devcontainer-feature.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "1.1.0",
"name": "Cato",
"description": "Install a CATO SSL certificate and configure container tooling to trust it.",
"documentationURL": "https://github.com/solarwinds-cloud/devcontainers/tree/main/src/cato",
"documentationURL": "https://github.com/solarwinds/devcontainers/tree/main/src/cato",
"options": {},
"containerEnv": {
"NODE_EXTRA_CA_CERTS": "/etc/ssl/certs/ca-certificates.crt",
Expand Down
Loading