feat: add MaybeDontAnalyzer security analyzer#2142
feat: add MaybeDontAnalyzer security analyzer#2142robotdan wants to merge 4 commits intoOpenHands:mainfrom
Conversation
Implements a SecurityAnalyzerBase that validates agent actions against policy rules configured in a Maybe Don't Gateway instance. Calls the gateway's POST /api/v1/action/validate endpoint and maps the response risk_level directly to SecurityRisk. - MaybeDontAnalyzer class following GraySwan patterns - 41 tests covering init, request building, risk mapping, error handling, HTTP lifecycle, and end-to-end security_risk flow - Example script (40_maybedont_security_analyzer.py) - Exported from openhands.sdk.security module Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add MAYBE_DONT_SERVER_LISTEN_ADDR=0.0.0.0:8080 (127.0.0.1 unreachable from host) - Disable AI validation and audit report (require OpenAI API key) - Match Docker command to docs PR (OpenHands/docs#350) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
[Automatic Post]: I have assigned @rbren as a reviewer based on git blame information. Thanks in advance for the help! |
|
[Automatic Post]: This PR seems to be currently waiting for review. @rbren, could you please take a look when you have a chance? |
|
[Automatic Post]: It has been a while since there was any activity on this PR. @robotdan, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up. |
1 similar comment
|
[Automatic Post]: It has been a while since there was any activity on this PR. @robotdan, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up. |
|
[Automatic Post]: This PR seems to be currently waiting for review. @rbren, could you please take a look when you have a chance? |
|
[Automatic Post]: It has been a while since there was any activity on this PR. @robotdan, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up. |
|
[Automatic Post]: This PR seems to be currently waiting for review. @rbren, could you please take a look when you have a chance? |
|
[Automatic Post]: It has been a while since there was any activity on this PR. @robotdan, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up. |
|
[Automatic Post]: This PR seems to be currently waiting for review. @rbren, could you please take a look when you have a chance? |
|
[Automatic Post]: It has been a while since there was any activity on this PR. @robotdan, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up. |
1 similar comment
|
[Automatic Post]: It has been a while since there was any activity on this PR. @robotdan, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up. |
|
Hey @robotdan are you still working at this PR? Should I review it? |
|
@OpenHands /codereview /github-pr-review 🤖 This comment was automatically posted by the pr-triage skill (OpenHands) on behalf of a maintainer. See PR #2906 for skill details. |
|
I'm on it! xingyaoww can track my progress at all-hands.dev |
xingyaoww
left a comment
There was a problem hiding this comment.
🟢 Good taste — Clean, well-structured integration that closely follows the existing GraySwan analyzer patterns. The code is straightforward, error handling is thorough, and the test suite covers the important paths.
A couple of minor suggestions inline, plus one thing to fix before the test-examples workflow picks this up.
This review was generated by an AI assistant (OpenHands) on behalf of the team.
| f"timeout={self.timeout}s, client_id={self.client_id}" | ||
| ) | ||
|
|
||
| def set_events(self, events: Any) -> None: |
There was a problem hiding this comment.
🟡 Suggestion: set_events takes Any here, but GraySwanAnalyzer.set_events uses the typed Sequence[LLMConvertibleEvent]. Using the typed signature keeps the interface consistent and gives callers better editor/type-checker support.
| def set_events(self, events: Any) -> None: | |
| def set_events(self, events: Sequence[LLMConvertibleEvent]) -> None: |
(You'd need to add from collections.abc import Sequence to the imports.)
| Returns: | ||
| SecurityRisk level based on gateway response | ||
| """ | ||
| url = f"{self.gateway_url.rstrip('/')}/api/v1/action/validate" |
There was a problem hiding this comment.
🟡 Suggestion: self.gateway_url is typed str | None, so pyright will flag .rstrip('/') here. After model_post_init it's always a str, but the type checker doesn't know that. A quick assert makes the intent explicit:
| url = f"{self.gateway_url.rstrip('/')}/api/v1/action/validate" | |
| assert self.gateway_url is not None | |
| url = f"{self.gateway_url.rstrip('/')}/api/v1/action/validate" |
| @@ -0,0 +1,150 @@ | |||
| """OpenHands Agent SDK — Maybe Don't Security Analyzer Example | |||
There was a problem hiding this comment.
🟠 Important: This example is not in _EXCLUDED_EXAMPLES in tests/examples/test_examples.py, so the test-examples CI workflow will try to run it. It will fail because (a) there's no Maybe Don't Gateway in CI, and (b) it calls input() which raises EOFError in non-interactive mode.
Please add it to the exclusion list, similar to 16_llm_security_analyzer.py:
# In tests/examples/test_examples.py, _EXCLUDED_EXAMPLES:
"examples/01_standalone_sdk/40_maybedont_security_analyzer.py",
SummaryI completed a code review of PR #2142 ("feat: add MaybeDontAnalyzer security analyzer") and submitted an APPROVE review via the GitHub API with 3 inline comments. What was done:
Review findings posted:
No code changes were madeThis was a review-only task — no files in the repository were modified, which is appropriate for a |
Summary
Adds
MaybeDontAnalyzer, a newSecurityAnalyzerBaseimplementation that validates agent actions against policy rules configured in a Maybe Don't Gateway instance.POST /api/v1/action/validateendpoint before action executionActionEventfields (tool_name,tool_call.arguments,thought,summary) to the gateway's request formatrisk_levelresponse directly toSecurityRisk(HIGH/MEDIUM/LOW/UNKNOWN)UNKNOWNmodel_post_initenv var resolution,set_events/closelifecycleHow it fits with existing integrations
MaybeDont doc for OpenHands
Configuration
Files
openhands-sdk/openhands/sdk/security/maybedont/analyzer.pyMaybeDontAnalyzerclassopenhands-sdk/openhands/sdk/security/maybedont/__init__.pyopenhands-sdk/openhands/sdk/security/__init__.py__all__tests/sdk/security/maybedont/test_maybedont_analyzer.pyexamples/01_standalone_sdk/40_maybedont_security_analyzer.pyRelated
Test plan
uv run pytest tests/sdk/security/maybedont/ -v— 41 tests passuv run pytest tests/sdk/security/ -v— 119 tests pass (no regressions)make format && make lint— cleanrm -rf→ HIGH, safe commands → LOW)🤖 Generated with Claude Code