Skip to content

[CLI] Require explicit CA for remote Python REST connections - #166

Merged
qiluo-msft merged 3 commits into
sonic-net:masterfrom
ashutosh-agrawal:fix/cli-rest-server-verification
Sep 8, 2026
Merged

[CLI] Require explicit CA for remote Python REST connections#166
qiluo-msft merged 3 commits into
sonic-net:masterfrom
ashutosh-agrawal:fix/cli-rest-server-verification

Conversation

@ashutosh-agrawal

@ashutosh-agrawal ashutosh-agrawal commented Sep 3, 2026

Copy link
Copy Markdown
Member

Why

The Python CLI actioner may connect to either the default local REST server or a configured remote endpoint. Remote connections should use a CA certificate selected specifically for that REST server while preserving the existing local workflow.

What

  • Require REST_API_CA_CERT to identify a readable PEM CA certificate file for every non-loopback REST endpoint.
  • Pass the configured CA path directly to Requests without falling back to Requests-specific or system CA bundles.
  • Preserve the current behavior for localhost, IPv4 loopback addresses (127.0.0.0/8), and IPv6 loopback (::1).
  • Limit certificate-warning suppression to individual loopback requests.
  • Document the remote endpoint configuration and add focused unit coverage.

How to verify

  • python3 -m unittest discover -s CLI/tests -p 'test_*.py' -v — 7 tests passed.
  • python3 -m py_compile CLI/actioner/cli_client.py CLI/tests/test_cli_client.py
  • git diff --check origin/master...HEAD

VS validation on vlab-01:

  1. Built target/debs/trixie/sonic-mgmt-framework_1.0-01_amd64.deb and installed it in the mgmt-framework container.
  2. Confirmed the default loopback REST endpoint remained reachable.
  3. Confirmed that setting only REQUESTS_CA_BUNDLE did not provide a fallback for a remote endpoint.
  4. Confirmed that a missing or unreadable REST_API_CA_CERT was rejected before the request.
  5. Configured REST_API_CA_CERT with the test endpoint's CA and confirmed that the request succeeded.

Results:

endpoint_classification=PASS
local_loopback_request=PASS status=404
requests_ca_bundle_fallback_rejected=PASS
invalid_explicit_ca_rejected=PASS
explicit_ca_accepted=PASS status=200

Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>
Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

headers=req_headers,
data=body,
params=query,
verify=verify)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The fix correctly moves away from verify=False for remote endpoints, but using verify=True
relies on whatever CA certificates happen to be present in the container's system store.
For a managed SONiC deployment this is fragile — the container may not carry the right
enterprise CA, and there's no explicit operator control over which CA is trusted.

Suggest adding a --rest-ca-cert CLI option (or a counterpart in the existing REST
client config) that accepts a PEM-format CA file, and using that path as the verify=
argument for remote requests:

verify = ca_cert_path if not _is_loopback_endpoint(url) else False

where ca_cert_path is the value of --rest-ca-cert. If a remote endpoint is configured
and no --rest-ca-cert is supplied, the client should fail with a clear error rather than
falling back to the system store.

This gives operators an explicit, visible CA provisioning step instead of implicit
system-bundle trust.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@qiluo-msft Thanks. After looking further, I agree that falling back to the general system trust store does not provide REST-specific control over the trusted CA.

I propose splitting the work into focused changes. In this PR, I will update the Python actioner client to require an explicitly configured CA file for non-loopback REST_API_ROOT values, without falling back to the system trust store.

The CLI also has a C++ libcurl REST client used for authentication and token refresh. I will submit a follow-up PR applying the same explicit-CA behavior there. The operator-facing --rest-ca-cert option, including host-to-container certificate provisioning, can then be added separately in sonic-buildimage.

Would this staged approach work for you?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Updated in f0e11c8. The Python actioner now requires REST_API_CA_CERT for non-loopback endpoints and passes that PEM path directly to Requests. It does not fall back to REQUESTS_CA_BUNDLE or the system CA store, and missing or unreadable configuration returns a clear error before making the request.

I added focused unit coverage and repeated the VS validation. The configured explicit CA succeeded, while the Requests bundle fallback and an invalid explicit path were rejected. The C++ client and operator-facing CLI plumbing remain scoped to the follow-up changes described above.

Signed-off-by: Ashutosh Agrawal <ashu@cisco.com>
@mssonicbld

Copy link
Copy Markdown

/azp run

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@ashutosh-agrawal ashutosh-agrawal changed the title [CLI] Verify certificates for remote REST server connections [CLI] Require explicit CA for remote Python REST connections Sep 5, 2026
@qiluo-msft
qiluo-msft merged commit c08cc7b into sonic-net:master Sep 8, 2026
6 checks passed
qiluo-msft pushed a commit that referenced this pull request Sep 9, 2026
Why
The C++ klish REST client may connect to either the default local REST server or a configured remote HTTPS endpoint. Remote connections should use a CA certificate selected specifically for that REST server while preserving the existing local workflow.

What
Require REST_API_CA_CERT to identify a readable CA certificate file for every non-loopback HTTPS REST endpoint.
Configure libcurl to verify the peer certificate and hostname using the selected CA file without falling back to its compiled-in CA directory.
Preserve the current behavior for localhost, IPv4 loopback addresses (127.0.0.0/8), and IPv6 loopback (::1).
Report a clear initialization error when the required CA configuration is missing or invalid.
Add focused coverage for accepted and rejected endpoint classification and CA path validation.
This is the C++ client counterpart to #166. Operator-facing CLI configuration can be added separately.

How to verify
Run tools/test/rest-tls.sh to verify:

localhost, IPv4 127.0.0.0/8, IPv6 ::1, and IPv4-mapped 127.0.0.0/8 endpoints are recognized as loopback.
Remote, misleading, and malformed endpoint names are not recognized as loopback.
Readable CA files are accepted, while missing paths, empty paths, and directories are rejected.
All tests passed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants