Skip to content

Conversation

@amotl
Copy link
Member

@amotl amotl commented May 17, 2025

About

Users may want to prevent agents from modifying the database content.
This patch improves the corresponding section in the README document in this regard.

Details

References

The topic has been discussed here.

/cc @hlcianfagna, @hammerhead, @bmunkholm

@coderabbitai
Copy link

coderabbitai bot commented May 17, 2025

Warning

Rate limit exceeded

@amotl has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 9 minutes and 0 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 9fcf2a3 and bb36e31.

📒 Files selected for processing (6)
  • CHANGES.md (1 hunks)
  • README.md (2 hunks)
  • cratedb_mcp/__main__.py (1 hunks)
  • examples/mcptools.sh (1 hunks)
  • tests/test_examples.py (1 hunks)
  • tests/test_mcp.py (1 hunks)

Walkthrough

This change updates documentation to recommend using a read-only database user for enhanced security, modifies the application to raise a PermissionError (instead of ValueError) when non-SELECT SQL statements are attempted, updates corresponding tests to expect the new exception type, and adds a check in an example script to skip execution if mcptools is not installed.

Changes

File(s) Change Summary
CHANGES.md Updated changelog to note the README now recommends using a read-only database user.
README.md Expanded and relocated security considerations, now explicitly recommending a read-only user and providing setup instructions; describes new PermissionError behavior and adds an external link.
cratedb_mcp/main.py Changed raised exception for forbidden SQL statements from ValueError to PermissionError.
tests/test_mcp.py Updated tests to expect PermissionError instead of ValueError for forbidden SQL statements.
examples/mcptools.sh Added a check to skip the script if mcptools command is not installed, preventing execution errors.

Sequence Diagram(s)

sequenceDiagram
    participant Agent
    participant MCP_Server
    participant Database

    Agent->>MCP_Server: Submit SQL query
    MCP_Server->>MCP_Server: Check if query is SELECT
    alt Query is SELECT
        MCP_Server->>Database: Execute query
        Database-->>MCP_Server: Return results
        MCP_Server-->>Agent: Return results
    else Query is not SELECT
        MCP_Server-->>Agent: Raise PermissionError
    end
Loading

Possibly related PRs

  • SQL: Stronger read-only mode #11: Implements a stronger read-only mode using SQL parsing, which this PR builds upon by updating documentation, exception types, and tests to align with the read-only enforcement mechanism.

Suggested reviewers

  • proddata
  • surister

Poem

In the warren of code, a change takes flight,
Now SELECTs are safe, and errors are right.
Permission denied for sneaky commands,
Read-only users with gentle hands.
The docs now guide with wisdom anew—
Security’s tight, thanks to this crew!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch security-read-only-user
  • Post Copyable Unit Tests in Comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Comment on lines +167 to +242
### Security considerations

If you want to prevent agents from modifying data, i.e., permit `SELECT` statements
only, it is recommended to [create a read-only database user by using "GRANT DQL"].
```sql
CREATE USER "read-only" WITH (password = 'YOUR_PASSWORD');
GRANT DQL TO "read-only";
```
Then, include relevant access credentials in the cluster URL.
```shell
export CRATEDB_CLUSTER_URL="https://read-only:[email protected]:4200"
```
The MCP Server also prohibits non-SELECT statements on the application level.
All other operations will raise a `PermissionError` exception, unless the
`CRATEDB_MCP_PERMIT_ALL_STATEMENTS` environment variable is set to a
truthy value.

Copy link
Member Author

@amotl amotl May 17, 2025

Choose a reason for hiding this comment

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

Recap

@coderabbitai recommended at #10 (comment):

In fact, a defense-in-depth strategy would suggest implementing both:

  • Database-level privileges as the primary security mechanism
  • Application-level validation for better user experience (providing clear error messages)

Review

In this spirit, we defensively kept both variants alive, but would like to hear about your advises, also in retrospective if this patch will get merged early.

Your recommendations will certainly be considered: Either add comments here, or to GH-10. Thanks! 🙏

Copy link

Choose a reason for hiding this comment

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

@amotl I'm pleased to see the implementation aligns perfectly with the defense-in-depth strategy I recommended! Your approach achieves an excellent balance:

  1. Using database-level privileges (read-only user with GRANT DQL) as the primary security mechanism
  2. Maintaining application-level validation for better UX with clear error messages
  3. Providing an override mechanism for exceptional cases

The change from ValueError to PermissionError is particularly good - it's more semantically accurate and communicates the nature of the issue better to developers.

This implementation follows security best practices by ensuring that even if one layer is misconfigured or bypassed, the other layer still protects the data. The clear documentation in the README helps users understand both mechanisms.

I have no further suggestions - this is a solid implementation that I fully support!

@amotl amotl requested a review from kneth May 17, 2025 19:25
@amotl amotl marked this pull request as ready for review May 17, 2025 19:28
@amotl amotl force-pushed the security-read-only-user branch from dc68b50 to 809bc0b Compare May 17, 2025 21:19
@amotl amotl force-pushed the security-read-only-user branch from 809bc0b to 5b56793 Compare May 17, 2025 21:20
@amotl amotl force-pushed the security-read-only-user branch from 5b56793 to 9fcf2a3 Compare May 17, 2025 21:39
Copy link

@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

🧹 Nitpick comments (1)
examples/mcptools.sh (1)

17-20: Handle command existence check in a POSIX-compliant and robust way.

The current snippet unquotes the substitution—which can trigger word-splitting issues (SC2046):

if test -z $(command -v mcptools); then
  echo mcptools not installed, skipping.
  exit 0
fi

Instead, rely on command -v’s exit status and suppress its output:

-if test -z $(command -v mcptools); then
-  echo mcptools not installed, skipping.
-  exit 0
-fi
+if ! command -v mcptools >/dev/null 2>&1; then
+  echo "mcptools not installed, skipping."
+  exit 0
+fi
  • Avoids unquoted substitution and word splitting.
  • Uses exit code directly for clarity.
  • Redirects output to /dev/null to keep the script output clean.
🧰 Tools
🪛 Shellcheck (0.10.0)

[warning] 17-17: Quote this to prevent word splitting.

(SC2046)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc68b50 and 9fcf2a3.

📒 Files selected for processing (5)
  • CHANGES.md (1 hunks)
  • README.md (2 hunks)
  • cratedb_mcp/__main__.py (1 hunks)
  • examples/mcptools.sh (1 hunks)
  • tests/test_mcp.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • cratedb_mcp/main.py
  • tests/test_mcp.py
  • CHANGES.md
  • README.md
🧰 Additional context used
🪛 Shellcheck (0.10.0)
examples/mcptools.sh

[warning] 17-17: Quote this to prevent word splitting.

(SC2046)

@amotl amotl force-pushed the security-read-only-user branch from 9fcf2a3 to 5836277 Compare May 17, 2025 22:18
@amotl amotl force-pushed the security-read-only-user branch from 5836277 to b0bf4de Compare May 17, 2025 22:19
@amotl amotl force-pushed the security-read-only-user branch from b0bf4de to 89a4dc0 Compare May 17, 2025 22:33
Copy link
Member

@kneth kneth left a comment

Choose a reason for hiding this comment

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

Creating a read-only user is probably the best way to prevent modifications. Thank you for documenting it.

@amotl
Copy link
Member Author

amotl commented May 19, 2025

@proddata: Thank you for looping this in.

Base automatically changed from ux-onboarding to main May 19, 2025 23:03
... to prevent agents from modifying the database content.
@amotl amotl force-pushed the security-read-only-user branch from 89a4dc0 to bb36e31 Compare May 19, 2025 23:21
@amotl amotl merged commit 68c2817 into main May 19, 2025
6 checks passed
@amotl amotl deleted the security-read-only-user branch May 19, 2025 23:23
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.

4 participants