Adding feature to update rules in place rather than having to only create new ones - #253
Adding feature to update rules in place rather than having to only create new ones#253Pavornoc wants to merge 1 commit into
Conversation
|
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
left a comment
There was a problem hiding this comment.
Thank you for adding the update_rule tool to the SecOps MCP server. This is a very helpful capability that fills an important gap in detection rule management.
Before merging, please address the following review feedback items:
-
Use lazy logging formatting instead of eager f-strings:
Inupdate_rule:- Replace
logger.info(f"Updating detection rule {rule_id}")withlogger.info("Updating detection rule %s", rule_id). - Replace
logger.error(f"Error updating rule {rule_id}: {str(e)}", exc_info=True)withlogger.error("Error updating rule %s: %s", rule_id, e, exc_info=True).
Using lazy%sformatting avoids eager string interpolation and conforms with logging standards across the repository.
- Replace
-
Use regex for YARA-L rule name extraction:
Usingline.strip().replace("rule ", "").replace(" {", "").strip()can corrupt rule names containingruleas a substring (e.g.,rule rule_execution_detected {becomes_execution_detected) and can fail with non-standard spacing or leading comments.
Please use regular expression matching instead:match = re.search(r"^\s*rule\s+([A-Za-z0-9_]+)", rule_text, re.MULTILINE) if match: result += f"Rule Name: {match.group(1)}\n"
-
Safe resource name and version extraction:
Ensureruledictionary access handles unexpected types safely:resource_name = rule.get("name", "") if isinstance(rule, dict) else "" version_id = resource_name.split("/")[-1] if resource_name else "" if "@" in version_id: result += f"New version: {version_id}\n"
-
Align docstrings with optional parameter defaults:
In the docstring,project_id,customer_id, andregionare marked as(required), but in the function signature they default toOptional[str] = None. Please update the docstring to specify(Optional[str])and note that they default to environment configuration. -
Deduplicate response text:
The return string repeats"Successfully updated detection rule."at the beginning and"Rule updated successfully."at the end. Please clean up the text so the confirmation message is not duplicated.
Once these updates are in place, we will be ready to approve and merge this PR.
Summary
Adds an
update_ruleMCP tool to the SecOps server, filling a gap in the existingrule management workflow.
Currently, the only way to modify an existing YARA-L detection rule via MCP is to
create a new rule and manually clean up the old version.
update_rulewraps theexisting
chronicle.update_rule()client method (PATCHrules/{rule_id}withupdate_mask=text) to replace rule text in place, preserving the rule's ID,deployment state, and version history.
Changes
server/secops/secops_mcp/tools/security_rules.py— newupdate_ruletool,inserted after
create_rule. No existing code modified.server/secops/tests/test_secops_rules_unit.py— new unit test file with 9 testscovering the success path, correct argument forwarding, version string surfacing,
graceful handling of missing API fields, and error propagation.
Notes
secopslibrary already exposesChronicleClient.update_rule(rule_id, rule_text);this PR only adds the MCP tool layer.
replace("rule ", "")approach as
create_rulefor consistency. A fix to both functions would be aseparate follow-on.