Skip to content

Update CA cert discovery#1694

Open
anjaliratnam-msft wants to merge 4 commits into
ai-dynamo:mainfrom
anjaliratnam-msft:ca-cert-update
Open

Update CA cert discovery#1694
anjaliratnam-msft wants to merge 4 commits into
ai-dynamo:mainfrom
anjaliratnam-msft:ca-cert-update

Conversation

@anjaliratnam-msft
Copy link
Copy Markdown

@anjaliratnam-msft anjaliratnam-msft commented May 28, 2026

What?

This PR is addressing a concern with finding the CA certs by automatically checking a list of known CA bundle paths across common Linux distributions. Users are still able to override this by setting the ca_bundle backend parameter or setting the AZURE_CA_BUNDLE environment variable.

Why?

This PR addresses a comment made in #1329

Summary by CodeRabbit

  • Bug Fixes
    • Improved SSL/TLS certificate handling for Azure Blob connections: the client now auto-detects common system CA bundles when none are specified, ensuring more reliable TLS setup across environments.
  • Chores
    • Connection-string handling consolidated to use the central configuration system while preserving existing empty-value behavior; no change to external behavior.

Review Change Stack

@anjaliratnam-msft anjaliratnam-msft requested a review from a team as a code owner May 28, 2026 16:56
@copy-pr-bot
Copy link
Copy Markdown

copy-pr-bot Bot commented May 28, 2026

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions
Copy link
Copy Markdown

👋 Hi anjaliratnam-msft! Thank you for contributing to ai-dynamo/nixl.

Your PR reviewers will review your contribution then trigger the CI to test your changes.

🚀

@dpressle
Copy link
Copy Markdown
Contributor

👀 Investigating Clang Format Check

@dpressle
Copy link
Copy Markdown
Contributor

🤖 CI Triage AgentClang Format Check · commit a8e7376d

I now have a complete and confident diagnosis. Here is the full report:


Summary: Clang Format Check failed on PR #1694 (ca-cert-update) due to misaligned inline comments in azure_blob_client.cpp.

Root cause: Commit [REDACTED:Hex High Entropy String] introduced a CA certificate path discovery block in src/plugins/azure_blob/azure_blob_client.cpp (around line 101) where the author manually padded trailing inline comments with extra spaces to vertically align them. clang-format-19 does not preserve that manual alignment — it strips the extra padding and places a single space before each // comment. The diff reported by clang-format-diff-19 is precise:

-    "/etc/ssl/certs/ca-certificates.crt",                // Debian/Ubuntu/Gentoo
-    "/etc/pki/tls/certs/ca-bundle.crt",                  // Fedora/RHEL 6
+    "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo
+    "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
     "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
-    "/etc/ssl/cert.pem"                                  // Alpine Linux
+    "/etc/ssl/cert.pem" // Alpine Linux

The three lines with shorter string literals have extra trailing spaces before their // comments to align them with the longest entry (/etc/pki/ca-trust/...). clang-format disallows this alignment style, causing exit code 1.

Implicated commit: [REDACTED:Hex High Entropy String] (PR #1694, branch ca-cert-update)

File: src/plugins/azure_blob/azure_blob_client.cpp — lines ~101–108 (the ca_info path-discovery initializer list)

Suggested fix: Remove the manual whitespace padding from the three inline comments so they each have exactly one space before //. The corrected block should read:

for (const auto *path : {
        "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo
        "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
        "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
        "/etc/ssl/cert.pem" // Alpine Linux
    }) {

Alternatively, run clang-format-19 -i src/plugins/azure_blob/azure_blob_client.cpp locally (with the project's .clang-format style file active) before pushing, to auto-correct the formatting in one step.

Related: PR #1694 — Update CA cert discovery

🛡️ This comment had 1 potential secret(s) redacted (Hex High Entropy String). See request_id 71fceb77-4959-4565-9967-ec058f147ba6 in the triage console for the audit trail.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 28, 2026

Caution

Review failed

Failed to post review comments

📝 Walkthrough

Walkthrough

Adds include, reads AZURE_STORAGE_CONNECTION_STRING via nixl::config::getValueDefaulted, implements AZURE_CA_BUNDLE with fallback probe of /etc/ssl/certs/ca-certificates.crt, and declares CurlTransportOptions while applying CAInfo only when a bundle is found.

Changes

CA Bundle Discovery and CURL Transport Configuration

Layer / File(s) Summary
Include and preparatory changes
src/plugins/azure_blob/azure_blob_client.cpp
Adds <filesystem> and reorders local includes to support filesystem-based CA probing.
AZURE_STORAGE_CONNECTION_STRING retrieval
src/plugins/azure_blob/azure_blob_client.cpp
Replaces getenv-based retrieval with nixl::config::getValueDefaulted("AZURE_STORAGE_CONNECTION_STRING", ""), preserving prior empty-string behavior.
CA bundle probing and selection
src/plugins/azure_blob/azure_blob_client.cpp
Returns AZURE_CA_BUNDLE when non-empty; otherwise checks /etc/ssl/certs/ca-certificates.crt with std::filesystem::exists and uses it if present, else returns empty.
CURL transport initialization
src/plugins/azure_blob/azure_blob_client.cpp
Declares Azure::Core::Http::CurlTransportOptions unconditionally; sets CurlTransportOptions.CAInfo only when a non-empty CA bundle path/value is available, then attaches the transport accordingly.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hop through headers, sniffing certs at night,
If AZURE_CA_BUNDLE sleeps, I search /etc/ssl by light.
CurlOptions stand ready, CAInfo set if found—
A snug little transport, safe and sound. 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update CA cert discovery' clearly and concisely summarizes the main change in the PR, which is refining how CA certificates are discovered for Azure blob client connections.
Description check ✅ Passed The PR description includes all required template sections (What, Why) with substantive content explaining the feature and its motivation, though the optional How section is omitted.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/plugins/azure_blob/azure_blob_client.cpp`:
- Around line 100-110: The CA probe block is failing clang-format and the
pointer style drifts from repo convention; refactor the initializer list and
pointer declarations (e.g., replace the "const auto *path" range-for with an
explicit const char* path and ensure pointer symbols are right-adjacent to the
type like const char*), avoid manually aligning the comment columns, and then
run clang-format on the modified block in
src/plugins/azure_blob/azure_blob_client.cpp so the initializer list and
surrounding code conform to the repo style (keep references to ca_info,
caBundle, fopen, and the path list intact).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ac9ef77e-1322-41a4-8e18-c4dc64a34d8a

📥 Commits

Reviewing files that changed from the base of the PR and between 3009db5 and a8e7376.

📒 Files selected for processing (1)
  • src/plugins/azure_blob/azure_blob_client.cpp

Comment thread src/plugins/azure_blob/azure_blob_client.cpp Outdated
Signed-off-by: Anjali Ratnam <anjaliratnam@microsoft.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/plugins/azure_blob/azure_blob_client.cpp (1)

105-113: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

CA bundle probe only checks a Debian-family path; extend default CA discovery for other distros

File: src/plugins/azure_blob/azure_blob_client.cpp (around lines 105-113)

for (const auto *path : {
         "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo
     }) {
    if (FILE *f = fopen(path, "r")) {
        fclose(f);
        ca_info = path;
        break;
    }
}

The fallback loop only probes /etc/ssl/certs/ca-certificates.crt. On Fedora/RHEL/CentOS/Alpine this will leave ca_info == nullptr, so curlOptions.CAInfo won’t be set and curl falls back to its built-in CA bundle. Since the PR’s intent is cross-distro CA discovery, add the common distro paths to the initializer list (keeping exactly one space before each // so clang-format stays green).

🐛 Proposed fix to restore cross-distro probing
             for (const auto *path : {
                      "/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo
+                     "/etc/pki/tls/certs/ca-bundle.crt", // Fedora/RHEL 6
+                     "/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", // CentOS/RHEL 7
+                     "/etc/ssl/cert.pem", // Alpine Linux
                  }) {

If the single-path behavior is intentional, update the PR description/commit message to explicitly document that non-Debian systems require ca_bundle / AZURE_CA_BUNDLE for correct CA handling.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/plugins/azure_blob/azure_blob_client.cpp` around lines 105 - 113, The CA
bundle probe only checks Debian's "/etc/ssl/certs/ca-certificates.crt" and
leaves ca_info null on other distros; update the fallback loop in
src/plugins/azure_blob/azure_blob_client.cpp (the block that sets ca_info and
later influences curlOptions.CAInfo) to include additional common CA paths used
by Fedora/RHEL/CentOS/Alpine such as "/etc/pki/tls/certs/ca-bundle.crt",
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", "/etc/ssl/cert.pem", and
"/etc/ssl/ca-bundle.pem" (keeping exactly one space before each // comment to
preserve clang-format), so the loop can find a system CA bundle across distros
and set ca_info for curlOptions.CAInfo.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/plugins/azure_blob/azure_blob_client.cpp`:
- Around line 105-113: The CA bundle probe only checks Debian's
"/etc/ssl/certs/ca-certificates.crt" and leaves ca_info null on other distros;
update the fallback loop in src/plugins/azure_blob/azure_blob_client.cpp (the
block that sets ca_info and later influences curlOptions.CAInfo) to include
additional common CA paths used by Fedora/RHEL/CentOS/Alpine such as
"/etc/pki/tls/certs/ca-bundle.crt",
"/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem", "/etc/ssl/cert.pem", and
"/etc/ssl/ca-bundle.pem" (keeping exactly one space before each // comment to
preserve clang-format), so the loop can find a system CA bundle across distros
and set ca_info for curlOptions.CAInfo.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 06930aa7-fe41-4a51-b774-dd0f3e3e4239

📥 Commits

Reviewing files that changed from the base of the PR and between a8e7376 and 3ab0181.

📒 Files selected for processing (1)
  • src/plugins/azure_blob/azure_blob_client.cpp

Copy link
Copy Markdown
Contributor

@kyleknap kyleknap left a comment

Choose a reason for hiding this comment

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

Looks good. I just had some smaller suggestions.

Comment on lines +105 to +107
for (const auto *path : {
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo
}) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For this, I'm thinking:

  1. Let's avoid doing a for loop and just look for this one specific location
  2. Add a comment saying why we have it there and hint that we could potentially remove it. I think something along the lines of the following would work
Libcurl currently looks for CA bundles based on the platform that is built (currently CentOS) and not the
platform that it is running on. This means it will not look for certs in the correct location on Ubuntu. This
is a workaround to make sure we check for Ubuntu certs before falling back to libcurl's default location.
In the future, we can remove this check if we find a way to build libcurl to search for certs in a more
cross-distro compatible way.

for (const auto *path : {
"/etc/ssl/certs/ca-certificates.crt", // Debian/Ubuntu/Gentoo
}) {
if (FILE *f = fopen(path, "r")) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of trying to read the file, I'm thinking we just check whether the file exists (e.g., std::filesystem::exists). Mainly it will make it a bit simpler and we don't have to worry about managing file handles as in most cases if the file is there it is most likely going to be readable as it is the distros managing the certs at that location.

@@ -93,9 +96,27 @@ azureBlobClient::azureBlobClient(nixl_b_params_t *custom_params,
options.Telemetry.ApplicationId = "azpartner-nixl/0.1.0";

std::string caBundle = ::getCaBundle(custom_params);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead of updating the if statement could we add this additional fallback logic to the getCaBundle to help consolidate all CA bundle related resolution logic to one place?

const char *env_conn = std::getenv("AZURE_STORAGE_CONNECTION_STRING");
if (env_conn && env_conn[0] != '\0') return std::string(env_conn);
if (env_conn && env_conn[0] != '\0') {
return std::string(env_conn);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Was there a particular reason we needed to update this line? If we do need to update it, it may make sense to update it to the pattern of the rest of these that use a nixl::config helper as I noticed this was the only parameter did not get updated when this file was updated and don't think it was intentional.

}) {
if (FILE *f = fopen(path, "r")) {
fclose(f);
ca_info = path;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also if we do detect the file's existence and decide to use it, we should add a logging statement using the NIXL_DEBUG macro so it is easier to tell if we resolved to this CA bundle based on this hardcoded path or that is what libcurl is defaulting to.

Signed-off-by: Anjali Ratnam <anjaliratnam@microsoft.com>
@pull-request-size pull-request-size Bot added size/M and removed size/S labels May 29, 2026
Copy link
Copy Markdown
Contributor

@kyleknap kyleknap left a comment

Choose a reason for hiding this comment

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

It's looking good. Just a couple more suggestions.

Comment on lines +111 to +119

{
Azure::Core::Http::CurlTransportOptions curlOptions;
curlOptions.CAInfo = caBundle;
const char *ca_info = caBundle.empty() ? nullptr : caBundle.c_str();

if (ca_info) {
curlOptions.CAInfo = ca_info;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is it possible to not update these lines at all? Mainly if we don't make changes here, we can keep it localized to getCaBundle().

Comment on lines +91 to +94
if (std::filesystem::exists("/etc/ssl/certs/ca-certificates.crt")) {
NIXL_DEBUG << "Using CA bundle: /etc/ssl/certs/ca-certificates.crt";
return "/etc/ssl/certs/ca-certificates.crt";
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we set the location value once and reuse it and be a little more descriptive in the debug message to better indicate why we are using it? e.g.:

const std::string ubuntu_ca_bundle = "/etc/ssl/certs/ca-certificates.crt";
if (std::filesystem::exists(ubuntu_ca_bundle)) {
    NIXL_DEBUG << "Using detected CA bundle at: " << ubuntu_ca_bundle;
    return ubuntu_ca_bundle;
}

Signed-off-by: Anjali Ratnam <anjaliratnam@microsoft.com>
@pull-request-size pull-request-size Bot added size/S and removed size/M labels May 29, 2026
options.Telemetry.ApplicationId = "azpartner-nixl/0.1.0";

std::string caBundle = ::getCaBundle(custom_params);
Azure::Core::Http::CurlTransportOptions curlOptions;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Let's remove this line as well. It does not appear to be needed.

// we find a way to build libcurl to search for certs in a more cross-distro compatible way.
const std::string ubuntu_ca_bundle = "/etc/ssl/certs/ca-certificates.crt";
if (std::filesystem::exists(ubuntu_ca_bundle)) {
NIXL_DEBUG << "Using detected CA bundle at: " << ubuntu_ca_bundle;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looking more into this, it might make sense to use NIXL_INFO macro instead? Mainly it seems to better fit the contributing guidelines as "configuration loaded" and when building from the container, which installs the wheels, I'm only seeing this log message if NIXL_INFO is used. @aranadive Thoughts?

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants