Skip to content

fix: improve certifi error message and docs for SOAR (#191) - #308

Merged
dandye merged 4 commits into
google:mainfrom
Som0111:fix/secops-soar-certifi-error-message-191
Sep 7, 2026
Merged

fix: improve certifi error message and docs for SOAR (#191)#308
dandye merged 4 commits into
google:mainfrom
Som0111:fix/secops-soar-certifi-error-message-191

Conversation

@Som0111

@Som0111 Som0111 commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Fixes #191

Problem

When the secops-soar MCP server fails due to an SSL/certifi certificate
issue, it shows a misleading message blaming SOAR credentials instead of
the real cause.

Changes

  • http_client.py — re-raises ssl.SSLError instead of swallowing it
  • bindings.py — catches ssl.SSLError around scope fetch and raises a
    distinct RuntimeError explaining the certifi fix
  • server/secops-soar/README.md — added Troubleshooting section with
    certifi setup instructions for macOS/Linux/Windows
  • tests/unit/ — tests covering SSL error re-raising vs credential errors

Before

"Failed to fetch valid scopes from SOAR, please make sure you have
configured the right SOAR credentials."

After

Distinct error explaining it's a local CA/certifi issue with fix instructions.
docs/usage_guide.md untouched.

AI Assistance

Used Claude Code to implement the fix. Reviewed full diff and take
responsibility for the submitted work.

@Som0111
Som0111 requested a review from a team September 6, 2026 18:13
@google-cla

google-cla Bot commented Sep 6, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@dandye

dandye commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Hi @Som0111, thank you for contributing and tackling #191!

Before we can review or merge contributions, Google requires a signed Contributor License Agreement (CLA). Please follow the steps in the CLA check to sign it.

Once signed, please address the following review items:

PowerShell Syntax in README: In server/secops-soar/README.md, $Env:SSL_CERT_FILE = python -m certifi causes a PowerShell parser error. Please update it to enclose the command in parentheses:

$Env:SSL_CERT_FILE = (python -m certifi)

Catch aiohttp.ClientSSLError in addition to ssl.SSLError: In http_client.py, some aiohttp SSL handshake failures raise aiohttp.ClientSSLError (which does not inherit from Python's ssl.SSLError). Please catch (ssl.SSLError, aiohttp.ClientSSLError) so all SSL failures are consistently reported.

Fix Ruff Lint Errors: Please run ruff check on the modified files and combine the nested with statements in tests/unit/test_certificate_error_handling.py (Rule SIM117).

Include Before/After Evidence: As noted in #191, please attach before/after execution logs or screenshots demonstrating the old error message versus the new actionable diagnostic message.

@Som0111

Som0111 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the detailed review! Addressed all three items:

  1. Fixed PowerShell syntax — $Env:SSL_CERT_FILE = (python -m certifi)
  2. Now catching (ssl.SSLError, aiohttp.ClientSSLError) in http_client.py
  3. SIM117 fixed — nested with statements combined in test file

For before/after evidence — I don't have a live SOAR environment, but here
is the test output demonstrating the behaviour change:

Before: ssl.SSLError was swallowed and surfaced as a generic credentials
error ("Failed to fetch valid scopes from SOAR, please make sure you have
configured the right SOAR credentials.")

After: ssl.SSLError and aiohttp.ClientSSLError are re-raised and caught in
bindings.py, surfacing a distinct RuntimeError explaining the certifi fix.

Test results:

  • test_http_client_get_reraises_ssl_error PASSED
  • test_http_client_get_swallows_generic_connection_error PASSED
  • test_get_valid_scopes_reports_certificate_issue_not_credentials PASSED
  • test_get_valid_scopes_still_blames_credentials_when_no_data PASSED

4/4 passed in 0.07s

Happy to provide live SOAR logs if you can point me to a mock setup.

test_results_before_after

@dandye dandye self-assigned this Sep 7, 2026
@dandye
dandye self-requested a review September 7, 2026 04:49

@dandye dandye left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for addressing the PowerShell syntax, ruff lint, and adding aiohttp.ClientSSLError to http_client.py in the latest commit.

There is one spot remaining in bindings.py:

In server/secops-soar/secops_soar_mcp/bindings.py:47, _get_valid_scopes() still catches only ssl.SSLError:

async def _get_valid_scopes():
    try:
        valid_scopes_list = await http_client.get(consts.Endpoints.GET_SCOPES)
    except ssl.SSLError as e:
        raise RuntimeError(_CERTIFICATE_ERROR_MESSAGE) from e

Because aiohttp.ClientSSLError does not inherit from ssl.SSLError (issubclass(aiohttp.ClientSSLError, ssl.SSLError) == False), any ClientSSLError re-raised by http_client.get() escapes _get_valid_scopes() without being wrapped in _CERTIFICATE_ERROR_MESSAGE.

We can reproduce this with a quick test:

@pytest.mark.asyncio
async def test_get_valid_scopes_reports_certificate_issue_on_client_ssl_error():
    conn_key = aiohttp.client_reqrep.ConnectionKey("example.com", 443, True, True, None, None, None)
    client_ssl_err = aiohttp.ClientSSLError(conn_key, OSError("handshake failed"))
    with (
        mock.patch.object(
            bindings,
            "http_client",
            new=mock.AsyncMock(get=mock.AsyncMock(side_effect=client_ssl_err)),
        ),
        pytest.raises(RuntimeError) as exc_info,
    ):
        await bindings._get_valid_scopes()

    assert "certificate" in str(exc_info.value).lower()

To resolve this, import aiohttp in bindings.py and catch both:

import aiohttp
...
    except (ssl.SSLError, aiohttp.ClientSSLError) as e:
        raise RuntimeError(_CERTIFICATE_ERROR_MESSAGE) from e

Minor note on the error message text in bindings.py:38-40:
"See the 'Additionally, for the secops-soar MCP server...' note in README.md / docs/usage_guide.md" only appears verbatim in docs/usage_guide.md (in README.md it is under ## Troubleshooting). Suggest tweaking the string:
See the 'Troubleshooting' section in README.md or setup notes in docs/usage_guide.md for setup steps.

Once bindings.py catches aiohttp.ClientSSLError, all unit tests pass cleanly and this is ready to merge.

@Som0111

Som0111 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

Fixed — bindings.py now catches (ssl.SSLError, aiohttp.ClientSSLError)
and error message updated to reference the Troubleshooting section.
New test added and all 5 tests pass.

Comment thread server/secops-soar/tests/unit/conftest.py Outdated
@Som0111
Som0111 requested a review from dandye September 7, 2026 07:24

@dandye dandye left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM! Thank you @Som0111 for quickly addressing the review comments, updating the exception handling in bindings.py to catch aiohttp.ClientSSLError, and updating the test copyright headers. Verified locally that all 5 unit tests pass hermetically and CI checks are green.

@dandye
dandye merged commit 88eb0b7 into google:main Sep 7, 2026
6 checks passed
@dandye

dandye commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Merged! Thanks again @Som0111 for the contribution and the quick turnaround on the review feedback.

@Som0111

Som0111 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for the thorough review and guidance, @dandye !
Really learned a lot from this contribution.
Would you mind if I mentioned this contribution on LinkedIn?

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.

Improve error message and docs for the SOAR certifi issue

2 participants