Skip to content

fix: use CredentialStoreAdapter in sap_tool instead of raw os.getenv()#6319

Merged
bryanadenhq merged 3 commits into
aden-hive:mainfrom
KartikPawade:fix/sap-tool-credential-store
Apr 1, 2026
Merged

fix: use CredentialStoreAdapter in sap_tool instead of raw os.getenv()#6319
bryanadenhq merged 3 commits into
aden-hive:mainfrom
KartikPawade:fix/sap-tool-credential-store

Conversation

@KartikPawade

@KartikPawade KartikPawade commented Mar 13, 2026

Copy link
Copy Markdown

Fixes #6318

Description

The sap_tool accepted a credentials parameter but never used it — all credential resolution went through os.getenv() directly. This fix aligns sap_tool with the standard pattern used by every other tool in the repo, following the n8n tool pattern as suggested by @Antiarin.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)

Related Issues

Fixes #6318

Changes Made

  • Moved _get_config() inside register_tools() to access the credentials closure
  • Added CredentialStoreAdapter resolution with os.getenv() fallback, matching the n8n tool pattern
  • Updated type hint from credentials: Any to credentials: CredentialStoreAdapter | None with TYPE_CHECKING import
  • Added 3 new tests covering credential store usage, missing values, and env var fallback

Testing

  • Unit tests pass — all 10 tests pass (7 existing + 3 new)
  • Lint passes (ruff check clean)
  • Existing env var behavior preserved (backward compatible)

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Summary by CodeRabbit

  • New Features

    • SAP tool can read credentials from a credential store, falling back to environment variables.
  • Improvements

    • Clearer, user-facing error message when SAP credentials are not configured.
  • Tests

    • Added tests covering credential-store resolution, missing credential behavior, and environment-variable fallback.

@levxn levxn 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

@KartikPawade

Copy link
Copy Markdown
Author

@TimothyZhang7, could you please merge this.

@bryanadenhq

Copy link
Copy Markdown
Collaborator

Hi @KartikPawade, there seems to be a linter error, please run uv run ruff check. I can merge after that.

Made-with: Cursor
@coderabbitai

coderabbitai Bot commented Mar 31, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c9869b06-8120-454d-b837-eac6c9fb0648

📥 Commits

Reviewing files that changed from the base of the PR and between 63fb089 and 3bb69a5.

📒 Files selected for processing (2)
  • tools/src/aden_tools/tools/sap_tool/sap_tool.py
  • tools/tests/tools/test_sap_tool.py
✅ Files skipped from review due to trivial changes (1)
  • tools/tests/tools/test_sap_tool.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tools/src/aden_tools/tools/sap_tool/sap_tool.py

📝 Walkthrough

Walkthrough

register_tools in the SAP tool now accepts an optional CredentialStoreAdapter and resolves sap_base_url, sap_username, and sap_password from it first, falling back to environment variables. _get_config() was moved inside register_tools() and typing imports use TYPE_CHECKING. Tests were added for credential-store and env flows.

Changes

Cohort / File(s) Summary
SAP Tool Core
tools/src/aden_tools/tools/sap_tool/sap_tool.py
Changed register_tools(mcp, credentials) signature to accept `CredentialStoreAdapter
SAP Tool Tests
tools/tests/tools/test_sap_tool.py
Added _mock_credentials() helper, tool_fns_with_creds fixture, and TestCredentialStoreAdapter tests covering credential-store resolution, missing credentials, and environment fallback. Minor fixture typing annotation update.

Sequence Diagram(s)

sequenceDiagram
    participant Agent
    participant Register as Registrar
    participant CredStore as CredentialStore (optional)
    participant Env as Environment
    participant SAP as SAP API

    Agent->>Registrar: call register_tools(mcp, credentials?)
    alt credentials provided
        Registrar->>CredStore: credentials.get('sap_base_url','sap_username','sap_password')
        CredStore-->>Registrar: returns values or None
    else no credentials
        Registrar->>Env: read SAP_BASE_URL/SAP_USERNAME/SAP_PASSWORD
        Env-->>Registrar: returns values or empty
    end
    Registrar->>SAP: make authenticated request using resolved values
    SAP-->>Registrar: response
    Registrar-->>Agent: register tool functions
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐇 I nibble configs from a secret nest,

Credentials found, not left to guess.
Env or store — I check them both,
Now SAP calls hop forth with oath.
🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 35.71% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: replacing os.getenv() with CredentialStoreAdapter for SAP tool credential resolution.
Linked Issues check ✅ Passed The PR successfully addresses #6318 by implementing CredentialStoreAdapter resolution with os.getenv() fallback in register_tools(), matching the pattern used by other tools.
Out of Scope Changes check ✅ Passed All changes are directly related to the objective: moving _get_config() into register_tools(), implementing CredentialStoreAdapter resolution, updating type hints, and adding corresponding tests.

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

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

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

@KartikPawade

Copy link
Copy Markdown
Author

Hi @bryanadenhq , made those ruff formatting, I think we are good now, let me know if anything.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tools/tests/tools/test_sap_tool.py (1)

240-258: Add a regression test for fallback when adapter is present but missing values

This suite only checks env fallback with credentials=None. The runtime path in tools/mcp_server.py passes an adapter, so a key regression case is: adapter provided, adapter values missing, env vars set, and tool still succeeds.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tools/tests/tools/test_sap_tool.py` around lines 240 - 258, Add a new test
(e.g., test_env_fallback_when_adapter_missing_values) that mirrors
test_env_fallback_when_no_adapter but supplies an adapter object with missing
credential values instead of None; patch os.environ with ENV and patch
aden_tools.tools.sap_tool.sap_tool.httpx.get to return the same
_mock_resp(data), then call the same tool invocation sap_list_purchase_orders
(via tool_fns["sap_list_purchase_orders"]) passing the adapter or arranging the
runtime in tools/mcp_server.py so the adapter is present but its credential
fields are empty/absent, assert result["count"] == 0 and that mock_get was
called with a URL containing "my-tenant-api.s4hana.ondemand.com" to verify env
fallback works when adapter exists but lacks values.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tools/src/aden_tools/tools/sap_tool/sap_tool.py`:
- Around line 44-53: The _get_config() logic currently uses credentials directly
and skips environment fallbacks and may let CredentialStoreAdapter.get()
KeyError propagate; update _get_config() to obtain base_url, username, and
password by first attempting safe lookups from credentials using .get(...) (or
catching KeyError when calling CredentialStoreAdapter.get) and falling back to
os.getenv("SAP_BASE_URL"/"SAP_USERNAME"/"SAP_PASSWORD") when credentials are
missing or lookup fails; ensure any KeyError from CredentialStoreAdapter.get is
caught and treated as a missing value so env vars are used instead, referencing
the _get_config function and variables base_url, username, password and the
CredentialStoreAdapter.get method.

In `@tools/tests/tools/test_sap_tool.py`:
- Around line 25-47: Add explicit type hints: annotate _mock_credentials() to
return MagicMock, and annotate tool_fns and tool_fns_with_creds to return
Dict[str, Callable[..., Any]] (or typing.Mapping[str, Callable[..., Any]] if
preferred). Update the function signatures for _mock_credentials, tool_fns, and
tool_fns_with_creds accordingly and ensure necessary typing imports (Dict,
Callable, Any) are present.

---

Nitpick comments:
In `@tools/tests/tools/test_sap_tool.py`:
- Around line 240-258: Add a new test (e.g.,
test_env_fallback_when_adapter_missing_values) that mirrors
test_env_fallback_when_no_adapter but supplies an adapter object with missing
credential values instead of None; patch os.environ with ENV and patch
aden_tools.tools.sap_tool.sap_tool.httpx.get to return the same
_mock_resp(data), then call the same tool invocation sap_list_purchase_orders
(via tool_fns["sap_list_purchase_orders"]) passing the adapter or arranging the
runtime in tools/mcp_server.py so the adapter is present but its credential
fields are empty/absent, assert result["count"] == 0 and that mock_get was
called with a URL containing "my-tenant-api.s4hana.ondemand.com" to verify env
fallback works when adapter exists but lacks values.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0067c351-445c-4ab4-b589-e04939854521

📥 Commits

Reviewing files that changed from the base of the PR and between 52b1a3f and 63fb089.

📒 Files selected for processing (2)
  • tools/src/aden_tools/tools/sap_tool/sap_tool.py
  • tools/tests/tools/test_sap_tool.py

Comment thread tools/src/aden_tools/tools/sap_tool/sap_tool.py
Comment thread tools/tests/tools/test_sap_tool.py Outdated
@bryanadenhq
bryanadenhq merged commit bf86dae into aden-hive:main Apr 1, 2026
9 checks 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.

[Bug]: sap_tool uses os.getenv() instead of CredentialStoreAdapter, not following the pattern

4 participants