From 953e6e36c14a0149185de5be8bb0ae7d79a98d7a Mon Sep 17 00:00:00 2001 From: Alan Gabriel Bem Date: Fri, 20 Mar 2026 09:56:38 +0100 Subject: [PATCH 1/2] feat: add CA_CERT support for corporate SSL inspection Adds CA_CERT config variable (.dclaude) and DCLAUDE_CA_CERT env var to configure a custom CA certificate for environments with corporate SSL inspection proxies. Sets NODE_EXTRA_CA_CERTS and SSL_CERT_FILE inside the container, resolves relative paths, and validates the cert is within the mounted directory tree. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 1 + README.md | 3 +++ dclaude | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/CLAUDE.md b/CLAUDE.md index 4405abc..a74902a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -149,6 +149,7 @@ dclaude supports a `.dclaude` config file that applies settings recursively to a - `CHROME_PORT` - Chrome DevTools port - `MOUNT_ROOT` - Mount directory (relative to config file, or absolute path) - `AWS_CLI` - AWS config mode (`mount`, `volume`, `none`) +- `CA_CERT` - Path to CA certificate for corporate SSL inspection (relative to config file, or absolute) **Note:** Chrome profiles are stored in `.dclaude.d/` directory, keeping `.dclaude` available for the config file. diff --git a/README.md b/README.md index a303229..702d787 100644 --- a/README.md +++ b/README.md @@ -265,6 +265,7 @@ dclaude shell # Open a bash shell (alias for exec) | `DCLAUDE_AWS_CLI` | `auto` | AWS config: `auto`, `mount`, `volume`, `none` | | `DCLAUDE_TMUX_SESSION` | `claude-TIMESTAMP` | Custom tmux session name for concurrent sessions | | `DCLAUDE_ITERM2` | `true` | Enable iTerm2 shell integration (only affects iTerm2) | +| `DCLAUDE_CA_CERT` | (none) | Path to CA certificate for corporate SSL inspection | ## Configuration File @@ -275,6 +276,7 @@ Create a `.dclaude` file at your project root to configure dclaude for that dire NAMESPACE=mycompany NETWORK=host DEBUG=true +CA_CERT=certs/corporate-ca.pem ``` dclaude walks up the directory tree to find `.dclaude` files. Any dclaude session started from that directory or any subdirectory will use these settings. @@ -290,6 +292,7 @@ dclaude walks up the directory tree to find `.dclaude` files. Any dclaude sessio | `DEBUG` | Enable debug output (`true`, `false`) | | `CHROME_PORT` | Chrome DevTools port | | `AWS_CLI` | AWS config mode (`mount`, `volume`, `none`) | +| `CA_CERT` | Path to CA certificate for corporate SSL inspection (relative to config file, or absolute) | Config file variables are the unprefixed equivalents of `DCLAUDE_*` environment variables (e.g., `NAMESPACE` in `.dclaude` = `DCLAUDE_NAMESPACE` env var). diff --git a/dclaude b/dclaude index 34abab2..a39447d 100755 --- a/dclaude +++ b/dclaude @@ -138,6 +138,18 @@ load_config_file() { AWS_CLI) [[ -z "${DCLAUDE_AWS_CLI:-}" ]] && DCLAUDE_AWS_CLI="$value" ;; + CA_CERT) + if [[ -z "${DCLAUDE_CA_CERT:-}" ]]; then + # Resolve relative paths relative to config file's directory + if [[ "$value" != /* ]]; then + local config_dir + config_dir=$(dirname "$config_file") + DCLAUDE_CA_CERT=$(cd "$config_dir" && realpath "$value" 2>/dev/null) + else + DCLAUDE_CA_CERT="$value" + fi + fi + ;; esac fi done < "$config_file" @@ -155,6 +167,11 @@ readonly GIT_AUTH_MODE="${DCLAUDE_GIT_AUTH:-auto}" # auto, agent-forwarding, ke readonly NAMESPACE="${DCLAUDE_NAMESPACE:-}" CHROME_PORT="${DCLAUDE_CHROME_PORT:-9222}" readonly AWS_CLI_MODE="${DCLAUDE_AWS_CLI:-auto}" # auto, mount, volume, none +# Resolve CA_CERT relative paths (env var: relative to PWD, config file: already resolved) +if [[ -n "${DCLAUDE_CA_CERT:-}" && "${DCLAUDE_CA_CERT}" != /* ]]; then + DCLAUDE_CA_CERT=$(realpath "$DCLAUDE_CA_CERT" 2>/dev/null) || true +fi +readonly CA_CERT="${DCLAUDE_CA_CERT:-}" # Path to CA certificate for corporate proxies # Show config file if loaded (always at info level, details at debug) if [[ -n "$DCLAUDE_CONFIG_FILE" ]]; then @@ -166,6 +183,7 @@ if [[ -n "$DCLAUDE_CONFIG_FILE" ]]; then [[ -n "${DCLAUDE_CHROME_PORT:-}" ]] && debug " CHROME_PORT=$DCLAUDE_CHROME_PORT" [[ -n "${DCLAUDE_MOUNT_ROOT:-}" ]] && debug " MOUNT_ROOT=$DCLAUDE_MOUNT_ROOT" [[ -n "${DCLAUDE_AWS_CLI:-}" ]] && debug " AWS_CLI=$DCLAUDE_AWS_CLI" + [[ -n "$CA_CERT" ]] && debug " CA_CERT=$CA_CERT" fi fi @@ -1914,6 +1932,23 @@ main() { ;; esac + # Handle CA certificate for corporate proxies / SSL inspection + # The cert file must be within the mounted directory tree to be accessible inside the container + if [[ -n "$CA_CERT" ]]; then + if [[ ! -f "$CA_CERT" ]]; then + warning "CA certificate not found: $CA_CERT" + elif [[ "$CA_CERT" != "$MOUNT_ROOT"* ]]; then + warning "CA certificate is outside the mounted directory: $CA_CERT" + warning "It must be within: $MOUNT_ROOT" + else + DOCKER_ARGS+=( + -e "NODE_EXTRA_CA_CERTS=${CA_CERT}" + -e "SSL_CERT_FILE=${CA_CERT}" + ) + info "CA certificate: $CA_CERT" + fi + fi + # Add any additional environment variables if [[ -n "${CLAUDE_MODEL:-}" ]]; then DOCKER_ARGS+=(-e "CLAUDE_MODEL=${CLAUDE_MODEL}") From 6b1c391597dd13b660b8693a121ce6eb1e1045c9 Mon Sep 17 00:00:00 2001 From: Alan Gabriel Bem Date: Fri, 20 Mar 2026 10:03:23 +0100 Subject: [PATCH 2/2] fix: preserve CA_CERT path when realpath fails Ensures the user-provided path is kept for the "not found" warning instead of silently clearing the variable. Co-Authored-By: Claude Opus 4.6 (1M context) --- dclaude | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dclaude b/dclaude index a39447d..4586397 100755 --- a/dclaude +++ b/dclaude @@ -169,7 +169,7 @@ CHROME_PORT="${DCLAUDE_CHROME_PORT:-9222}" readonly AWS_CLI_MODE="${DCLAUDE_AWS_CLI:-auto}" # auto, mount, volume, none # Resolve CA_CERT relative paths (env var: relative to PWD, config file: already resolved) if [[ -n "${DCLAUDE_CA_CERT:-}" && "${DCLAUDE_CA_CERT}" != /* ]]; then - DCLAUDE_CA_CERT=$(realpath "$DCLAUDE_CA_CERT" 2>/dev/null) || true + DCLAUDE_CA_CERT=$(realpath "$DCLAUDE_CA_CERT" 2>/dev/null) || DCLAUDE_CA_CERT="$PWD/$DCLAUDE_CA_CERT" fi readonly CA_CERT="${DCLAUDE_CA_CERT:-}" # Path to CA certificate for corporate proxies