Skip to content

CHEF-37581: Fix SSL certificate verification in Habitat plans (Linux, macOS, Windows) - #348

Open
sanghinitin wants to merge 4 commits into
mainfrom
CHEF-37581-fix-ssl-validation
Open

CHEF-37581: Fix SSL certificate verification in Habitat plans (Linux, macOS, Windows)#348
sanghinitin wants to merge 4 commits into
mainfrom
CHEF-37581-fix-ssl-validation

Conversation

@sanghinitin

Copy link
Copy Markdown
Contributor

Summary

Fixes SSL certificate verification failures when Habitat-packaged chef-cli connects to supermarket.chef.io (and other HTTPS endpoints) on Linux, macOS, and Windows. Without this fix, commands such as chef install fail with an OpenSSL::SSL::SSLError because Ruby cannot locate a trusted CA bundle inside the Habitat sandbox.

Jira Ticket

CHEF-37581

Root Cause

Habitat packages run inside an isolated environment where the system CA store is not available. Ruby's OpenSSL bindings require SSL_CERT_FILE (and optionally SSL_CERT_DIR) to be pointed at a valid CA bundle. The core/cacerts Habitat package provides this bundle, but it was not wired into the Habitat plans.

Error Fixed

[ERROR] SSL Validation failure connecting to host: supermarket.chef.io -
SSL_connect returned=1 errno=0 peeraddr=13.216.54.233:443 state=error:
certificate verify failed (unable to get local issuer certificate)

Error: Failed to generate Policyfile.lock
Reason: (OpenSSL::SSL::SSLError) SSL Error connecting to
https://supermarket.chef.io/universe - SSL_connect returned=1 errno=0
peeraddr=13.216.54.233:443 state=error: certificate verify failed
(unable to get local issuer certificate)

Changes

All Platforms

  • Added core/cacerts to pkg_deps (runtime dependency, not build-only) so the CA bundle is present when chef install runs post-installation.

Linux — habitat/plan.sh

  • Build time: exports SSL_CERT_FILE and SSL_CERT_DIR in do_build() before bundle install, fixing SSL during gem fetching from rubygems.org.
  • Runtime: injects both variables into the generated chef-cli wrapper script so every subsequent invocation (e.g. chef install) can reach supermarket.chef.io.

macOS — habitat/aarch64-darwin/plan.sh

  • Same changes as Linux: SSL_CERT_FILE / SSL_CERT_DIR set at build time in do_build() and baked into the runtime wrapper script.

Windows — habitat/plan.ps1

  • Build time: sets $env:SSL_CERT_FILE in Invoke-Build before bundle install.
  • Runtime: adds Set-RuntimeEnv SSL_CERT_FILE in Invoke-SetupEnvironment so the variable is exported to every child process spawned by the installed package.

Files Modified

  • habitat/plan.sh
  • habitat/aarch64-darwin/plan.sh
  • habitat/plan.ps1

Testing

  • Verified the diff targets the exact lines where bundle install and the runtime wrapper are constructed in each plan.
  • The core/cacerts package is an established Habitat package in the base-2025 channel used by this project.
  • Pattern is consistent with how other Chef Habitat plans resolve CA trust (e.g. chef-workstation).

Signed-off-by: nitin sanghi <nsanghi@progress.com>
@sanghinitin
sanghinitin requested a review from a team as a code owner August 11, 2026 11:16
Copilot AI lite review requested due to automatic review settings August 11, 2026 11:16
@sanghinitin
sanghinitin requested review from a team as code owners August 11, 2026 11:16
@sanghinitin sanghinitin added the Type: Bug Does not work as expected. label Aug 11, 2026
@github-actions

Copy link
Copy Markdown

Simplecov Report

Covered Threshold
98.51% 90%

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request updates the Habitat packaging plans for chef-cli to ensure Ruby/OpenSSL can consistently locate a trusted CA bundle inside the Habitat sandbox, preventing SSL verification failures when connecting to HTTPS endpoints (e.g., supermarket.chef.io) across Linux, macOS, and Windows.

Changes:

  • Add core/cacerts as a runtime dependency in all Habitat plans so a CA bundle is available at runtime.
  • Export SSL_CERT_FILE (and SSL_CERT_DIR on Unix) during build steps to prevent SSL failures during bundle install.
  • Propagate the CA bundle path into the runtime environment (Unix wrapper scripts; Windows Set-RuntimeEnv) so subsequent invocations inherit working SSL trust.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
habitat/plan.sh Adds core/cacerts and exports SSL_CERT_FILE/SSL_CERT_DIR during build and in the generated runtime wrapper.
habitat/aarch64-darwin/plan.sh Mirrors the Linux changes for macOS aarch64: adds core/cacerts and exports SSL_CERT_FILE/SSL_CERT_DIR for build + runtime wrapper.
habitat/plan.ps1 Adds core/cacerts and sets SSL_CERT_FILE at build time and via Set-RuntimeEnv for runtime inheritance.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

…ict with core/cacerts pkg_env

Signed-off-by: nitin sanghi <nsanghi@progress.com>
Copilot AI review requested due to automatic review settings August 11, 2026 12:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (3)

habitat/plan.sh:110

  • The wrapper script unconditionally exports SSL_CERT_FILE/SSL_CERT_DIR, which will override any user-provided trust configuration (e.g., corporate CA bundles) and can break access to endpoints that require a different CA. Prefer defaulting these values only when the variables are not already set.
export SSL_CERT_FILE="$(pkg_path_for core/cacerts)/ssl/certs/cacert.pem"
export SSL_CERT_DIR="$(pkg_path_for core/cacerts)/ssl/certs"

habitat/aarch64-darwin/plan.sh:115

  • Same as Linux plan: the generated wrapper script overwrites SSL_CERT_FILE/SSL_CERT_DIR unconditionally, preventing users from supplying a custom CA bundle when needed. Default these variables only if they are unset.
export SSL_CERT_FILE="$(pkg_path_for core/cacerts)/ssl/certs/cacert.pem"
export SSL_CERT_DIR="$(pkg_path_for core/cacerts)/ssl/certs"

habitat/plan.ps1:38

  • Using -Force here will override any SSL_CERT_FILE the user sets when running the package, which can prevent using a custom CA bundle. Unless you specifically need to clobber an existing value, drop -Force so a caller can override the default at runtime.
    Set-RuntimeEnv -Force SSL_CERT_FILE "$(Get-HabPackagePath 'core/cacerts')/ssl/certs/cacert.pem"

…id conflict with core/cacerts pkg_env

Signed-off-by: nitin sanghi <nsanghi@progress.com>
Copilot AI review requested due to automatic review settings August 11, 2026 12:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (2)

habitat/plan.sh:28

  • PR description says SSL_CERT_FILE/SSL_CERT_DIR are exported in do_build() before bundle install to fix build-time gem fetching, but this plan only sets them for runtime (do_setup_environment + wrapper). If the build environment doesn’t already have CA paths configured, bundle install may still fail with the same SSL verification error. Consider exporting SSL_CERT_FILE (and SSL_CERT_DIR) in do_build() before any Bundler network access, similar to the Windows plan.
  # core/cacerts already exports SSL_CERT_FILE; -f forces our declaration to win
  set_runtime_env -f SSL_CERT_FILE "$(pkg_path_for core/cacerts)/ssl/certs/cacert.pem"
  set_runtime_env -f SSL_CERT_DIR "$(pkg_path_for core/cacerts)/ssl/certs"

habitat/aarch64-darwin/plan.sh:41

  • PR description says SSL_CERT_FILE/SSL_CERT_DIR are exported in do_build() before bundle install to fix build-time gem fetching, but this plan only sets them for runtime (do_setup_environment + wrapper). If the build environment doesn’t already have CA paths configured, bundle install may still fail with the same SSL verification error. Consider exporting SSL_CERT_FILE (and SSL_CERT_DIR) in do_build() before any Bundler network access, similar to the Windows plan.
  # core/cacerts already exports SSL_CERT_FILE; -f forces our declaration to win
  set_runtime_env -f SSL_CERT_FILE "$(pkg_path_for core/cacerts)/ssl/certs/cacert.pem"
  set_runtime_env -f SSL_CERT_DIR "$(pkg_path_for core/cacerts)/ssl/certs"

Signed-off-by: nitin sanghi <nsanghi@progress.com>
Copilot AI review requested due to automatic review settings August 11, 2026 13:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Suppressed comments (3)

habitat/plan.sh:108

  • These SSL_CERT_* exports are only being injected into the runtime wrapper. The PR description also states SSL_CERT_FILE/SSL_CERT_DIR are exported in do_build() before bundle install to fix SSL during gem fetching, but do_build() currently has no SSL_CERT_* exports (plan.sh:47-68). If the Habitat studio lacks a system CA store, bundle install can still fail during the build even though runtime is fixed.
export PATH="$(pkg_path_for ${ruby_pkg})/bin:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:\${USER_GEM_HOME}/bin:$pkg_prefix/vendor/bin:\$PATH"
export LD_LIBRARY_PATH="$(pkg_path_for core/libarchive)/lib:\$LD_LIBRARY_PATH"
export SSL_CERT_FILE="\${SSL_CERT_FILE:-$(pkg_path_for core/cacerts)/ssl/certs/cacert.pem}"
export SSL_CERT_DIR="\${SSL_CERT_DIR:-$(pkg_path_for core/cacerts)/ssl/certs}"

habitat/aarch64-darwin/plan.sh:113

  • Like Linux, SSL_CERT_* is only set in the generated runtime wrapper here. The PR description says SSL_CERT_FILE/SSL_CERT_DIR are also exported in do_build() before bundle install, but do_build() currently has no SSL_CERT_* exports (aarch64-darwin/plan.sh:46-61). That means gem fetching during the build can still fail if the studio doesn’t expose a system CA store.
export PATH="$(pkg_path_for ${ruby_pkg})/bin:/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:$pkg_prefix/vendor/bin:\$PATH"
export DYLD_LIBRARY_PATH="$(pkg_path_for core/libarchive)/lib:\$DYLD_LIBRARY_PATH"
export SSL_CERT_FILE="\${SSL_CERT_FILE:-$(pkg_path_for core/cacerts)/ssl/certs/cacert.pem}"
export SSL_CERT_DIR="\${SSL_CERT_DIR:-$(pkg_path_for core/cacerts)/ssl/certs}"

habitat/plan.ps1:60

  • This sets $env:SSL_CERT_FILE for the build (before bundle install), but the PR description also calls out adding Set-RuntimeEnv SSL_CERT_FILE in Invoke-SetupEnvironment so the installed package exports it to child processes. Invoke-SetupEnvironment currently sets several runtime env vars but not SSL_CERT_FILE, so runtime SSL verification may still fail on Windows.
        bundle config --local jobs 4
        bundle config --local retry 5
        bundle config --local silence_root_warning 1
        if (-not $env:SSL_CERT_FILE) { $env:SSL_CERT_FILE = "$(Get-HabPackagePath 'core/cacerts')/ssl/certs/cacert.pem" }
        Write-BuildLine " ** Using bundler to retrieve the Ruby dependencies"
        bundle install

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Type: Bug Does not work as expected.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants